0
votes

So I'm using an STM32F407 and trying to write to an SD card with FATFS. I have used the CubeMX to generate the code for both the FAT layer and 4bit SDIO configuration software. I have added the following code to main to test whether the code works.

UINT bw;

f_mount(&FatFs, "", 0);     /* Give a work area to the default drive */

/*           Create a file */
if(f_open(&Fil, "newfile.txt", FA_WRITE | FA_CREATE_ALWAYS) == FR_OK) { 

   f_write(&Fil, "It works!\r\n", 11, &bw); /* Write data to the file */
   f_close(&Fil);                               /* Close the file */
   if (bw == 11) {      /* Lights green LED if data written well */
      //Celebrate
   }
}

However I can't initialize the SD card. When I step through the code I get to the disk initialization function which returns an error. Due to my lack of experience writing C I'm not sure how to the following function works and how it calls other pieces of code to initialize the card as I assume the card needs to be configured for 4 bit mode.

/**
 * @brief  Initializes a Drive
 * @param  pdrv: Physical drive number (0..)
 * @retval DSTATUS: Operation status
*/
DSTATUS disk_initialize (
   BYTE pdrv                /* Physical drive nmuber to identify the drive */
)
{
   DSTATUS stat = RES_OK;

   if(disk.is_initialized[pdrv] == 0){ 
      disk.is_initialized[pdrv] = 1;
      stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);
   }
return stat;
}

At this point due to having never got FAT working I'm a but stuck. I'm using a 2GB micro SD card in an adapter and formatted fully with FAT32. I'm using an STM32F4 discovery board. I have checked the connections from the SD card to the board thoroughly. I can see on my logic analyzer that I do get communication when the 'disk_initialize' function is called but as far as I can tell it's one nible and nothing being sent back to the micro. Could someone help me by suggesting what to look for?

Thanks

UPDATE

Okay so now it's hard to see what's going wrong. If want the drive to be mounted immediately or not then I get the error at 'disk_initialize'. When stepping through I get to the line:

stat = disk.drv[pdrv]->disk_initialize(disk.lun[pdrv]);

Then some how it immediately it jumps to:

if((response_r1 & SD_OCR_ILLEGAL_CMD) == SD_OCR_ILLEGAL_CMD)
{
    return(SD_ILLEGAL_CMD);
}

then returns this error.

I'll keep looking but any help is appreciated.

2
Initializing SD cards on embedded boards is a major PITA, as I know only too well. Quadruple-check all your initialization commands, delays, protocols and driver code. You have a jtag debugger?Martin James
Hi, thanks for the reply. So just having a look now through the software the SDIO is initialized in 1bit mode but not SPI. Looking at the scope I get information sent from the micro to the MOSI pin of the SD card but, again, I get nothing back from the card (on the MISO pin). So it seems either the data sent to the SD card is incorrect or there's something wrong with the SD card or the setup. The thing is I don't know where the code is sending the data. The IO is currently at a clk f of 350kHz so not exactly blazing. The CS asserts seem to be very short though, fine I imagine. I'm using SWD.George Waller
Even 350kHz may be too fast for initialization with some cards. IIRC, I initialize at 100k and then boost to 10M when all that CMDxx is over with and I have mounted the card OK.Martin James
In main.c I have this function which is called before everything else. /* SDIO init function */ void MX_SDIO_SD_Init(void) { hsd.Instance = SDIO; hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; hsd.Init.BusWide = SDIO_BUS_WIDE_1B; hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; hsd.Init.ClockDiv = 4; } Any changes I make to this doesn't change the output I get however.George Waller
Now I decided to regenerate my code from CubeMX and now, interestingly, I'm getting a different error. I'll check what it is in the morning - too tired now!George Waller

2 Answers

0
votes

I had the same issue with my own board. I got it to work after seting the "SDIOCLK clock divide factor" parameter in CubeMX from 0 to 4 for the SDIO hardware.

-2
votes

Initially, by default I went with the default setting hsd.Init.ClockDiv = 0; I changed this to hsd.Init.ClockDiv = 2;, and I was able to write to an 8GB micro sd Card. SPEED FOR OUR ROBOTS PURPOSE DOESN'T NEED TO BE ROCKET FAST SINCE THIS SD CARD WILL RUN WITH MULTIPLE PROCESSORS. THIS SD CARD,Uc, and SENSOR ARE STAND ALONE.

Settings:

Cube MX = SDIO-SD 1B, RX SDIO_RX DMA2 Stream 3 Peripheral To Memory Low SDIO_TX DMA2 Stream 6 Memory To Peripheral Low

FATFS LFN - Enabled with static working buffer on the BSS

Clock 16Mhz HSI PLATFORM STM32F469-DISCO FOR IN HOUSE BOARD MANUFACTURING.

HOPE THIS HELPS! DON'T STOP TRYING!