1

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.

George Waller
  • 95
  • 3
  • 4
  • 13
  • 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 Nov 12 '15 at 21:04
  • 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 Nov 12 '15 at 21:17
  • 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 Nov 12 '15 at 21:38
  • 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 Nov 12 '15 at 21:46
  • 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 Nov 12 '15 at 22:48
  • the sequence of calls seems to be missing an initial call to `f_mkfs()`: (Create a file system on the drive) – user3629249 Nov 13 '15 at 08:44
  • Post code in the question, not in the comments. This link: describes how to configure/link/use the FATFS module. I do not see any of its' directions implemented in the posted code. – user3629249 Nov 13 '15 at 09:00
  • See the edit in the OP. – George Waller Nov 13 '15 at 10:31
  • @user3629249 the link you provided doesn't work. I would love to see the document. – George Waller Nov 13 '15 at 10:38
  • I googled `documentation for FATFS` the third hit is a pdf file: `http://www.st.com/st-web-ui/static/active/en/resource/technical/document/user_manual/DM00105259.pdf>` Stackoverflow was 'trimming' the link incorrectly – user3629249 Nov 14 '15 at 04:51
  • @user3629249 Thanks I had found it but this document doesn't talk about the low level aspects of the code which is where I think things are going wrong. Could someone explain to me or describe possible ways of how the function 'disk_initialize():' calls other pieces of code? Thanks – George Waller Nov 14 '15 at 11:30
  • @GeorgeWaller, please ask the question as an edit to the original question, otherwise most people will not see your new question. – user3629249 Nov 14 '15 at 16:31
  • First you have to make working and test SD card read/write operations at block level. Then try to start FatFs lib. I suspect you don't have working communication. PS: Download newer version of FatFs from its site. CubeMX usually includes very old version. – i486 May 05 '17 at 12:31

3 Answers3

2

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.

Marcel
  • 137
  • 1
  • 8
0

For those still looking for answer:

I had exact same issue on this. Turns out I didn't call init function...

In Main.c Add:

MX_FATFS_Init();

If using C++, in app_fatfs.h Add:

#ifdef __cplusplus
extern "C" {
#endif

#ifdef __cplusplus
}
#endif

There were some fatfs or diskio file that I had to add the extern "C", please check all files if you are using C++.

Jason
  • 1
-2

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!

HXE
  • 1