Hallo liebe Gemeinde,
als STM32 Anfänger versuche ich gerade per SDIO eine SD-Karte zu lesen
und das mit einem Discovery F4 daran angeschlossen eine SD-Kartenadapter
wie im Bild. Als "Library" verwende ich die "stm32_eval_sd_io.c". Ich
nehme an, das ist gemeint wenn hier von der ST SDIO FW die Rede ist
(Liege ich hier schon falsch?).
In der "stm32_eval_sd_io.h" habe ich das include "stm32_eval.h" ersetzt
durch:
1 | #include <stdint.h>
|
2 | #include "stm32f4xx.h"
|
3 | #include "stm32f4xx_sdio.h"
|
4 | #include "stm32f4xx_dma.h"
|
5 | #include "stm32f4xx_gpio.h"
|
6 | #include "stm32f4xx_rcc.h"
|
7 |
|
8 | #define SDIO_INIT_CLK_DIV 119
|
9 | #define SDIO_TRANSFER_CLK_DIV 7
|
10 | #define SD_DETECT_PIN GPIO_Pin_9
|
11 | #define SD_DETECT_GPIO_PORT GPIOC
|
12 | #define SD_POLLING_MODE
|
Dann folgende Funktion implementiert:
1 | extern "C" void SD_LowLevel_Init()
|
2 | {
|
3 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN | RCC_AHB1ENR_GPIODEN;
|
4 | RCC->APB2ENR |= RCC_APB2ENR_SDIOEN;
|
5 |
|
6 | // PC8=D0, PC12=CLK, PC9=DETECT
|
7 | GPIOC->MODER = GPIOC->MODER & ~0x030F0000 | 0x02060000;
|
8 | GPIOC->PUPDR = GPIOC->PUPDR & ~0x030F0000 | 0x01050000;
|
9 | GPIOC->OSPEEDR |= 0x030F0000;
|
10 | GPIOC->AFR[1] = GPIOC->AFR[1] & ~0x0000000F | 0x0000000C;
|
11 | GPIOC->AFR[1] = GPIOC->AFR[1] & ~0x000F0000 | 0x000C0000;
|
12 |
|
13 | // PD2=CMD
|
14 | GPIOD->MODER = GPIOD->MODER & ~0x00000030 | 0x00000020;
|
15 | GPIOD->PUPDR = GPIOD->PUPDR & ~0x00000030 | 0x00000010;
|
16 | GPIOD->OSPEEDR |= 0x00000030;
|
17 | GPIOD->AFR[0] = GPIOD->AFR[0] & ~0x00000F00 | 0x00000C00;
|
18 |
|
19 | SDIO_SetPowerState(SDIO_PowerState_ON);
|
20 | SDIO_ClockCmd(ENABLE);
|
21 | }
|
Damit lässt sich erst einmal alles compilieren. In main() dann die
Aufrufe (im ST Beispiel so in etwa gefunden)
1 | SD_Init();
|
2 | SDIO_DeInit();
|
3 | SD_PowerON();
|
4 | SD_GetCardInfo(&ci);
|
die soweit alle funktionieren und SD_OK zurückliefern. "ci" enthält auch
plausible Werte. So weit scheint es also zu funktionieren.
Nachfolgende Aufrufe von SD_GetCardStatus oder SD_ReadBlock bleiben aber
hängen und zwar in folgender Schleife (stm32_eval_sd_io.c)
1 | /*!< Polling mode */
|
2 | while (!(SDIO->STA &(SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)))
|
3 | {
|
4 | if (SDIO_GetFlagStatus(SDIO_FLAG_RXFIFOHF) != RESET)
|
5 | {
|
6 | for (count = 0; count < 8; count++)
|
7 | {
|
8 | *(tempbuff + count) = SDIO_ReadData();
|
9 | }
|
10 | tempbuff += 8;
|
11 | }
|
12 | }
|
Das Flag SDIO_FLAG_RXFIFOHF wird nie gesetzt. Was mache ich falsch oder
habe ich vergessen?