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.
/* 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