cancel
Showing results for 
Search instead for 
Did you mean: 

Problem using µSD card with SDIO and FatFs

KMach.2
Associate II

 I'm trying to make a program one of the features of which is SD card support. I'm using HAL libraries entirely, it's hard to find an example that combines SD card, SDIO communication and HAL libraries.

1. problem is that function f_mkdir, f_open returns FR_DISK_ERR no matter what order they are used.

I checked the physical connections, the signals show up in the communication. If there is no SD card in the slot it returns FR_NOT_READY.

2. i don't use an SD Card detect switch, could it be because of this? How can I bypass Dtetect_SDIO? Or make it so that the program works?

MCU: STM32F103VETxLQFP100

CubeIDE v1.7.0

CubaMX v6.3.0

The target program looks different, but with this code I tried to find errors.

uint32_t wbytes; //File write counts

 uint8_t wtext[] = "text to write logical drive"; //file write buffer

 short int res[5];

 res[0] = f_mount(&SDFatFS, (TCHAR const*)SDPath, 0);

 if(res[0] == FR_OK)

 {

 res[1] = f_mkdir("sd_test"); //daje FR_DISK_ERR

 res[2] = f_open(&SDFile, "test.txt", FA_CREATE_ALWAYS | FA_WRITE | FA_READ); //daje FR_DISK_ERR

 if(res[2] == FR_OK)

 res[3] = f_write(&SDFile, wtext, sizeof(wtext), (void *)&wbytes);

 else

 res[3] = 21;

 res[4] = f_close(&SDFile);

 }

13 REPLIES 13
magene
Senior II

Is this for a custom board of your design? I've had a raft of problems trying to get uSD and FatFs working on a variety of STM32 Nucleo boards. Here's what's I'm trying now.

1) Buy the ST Disco or Eval board for my target processor. The Disco and Eval boards do have uSD cards built in.

2) Run the ST provided uSD example. I typically use the "FatFs-uSD-DMAStandalone example and they've worked as provided by ST for the 2 or 3 different STM32 processors I've used. Both in STM32CubeIDE and VisualGDB.

3) Make sure my target board is laid out exactly (or as close as possible) to the Disco or Eval board. Both with respect to layout and making sure you're using the same pins in hardware that your software is using. If I'm using different pins for the SDIO than the ST example code, I'll use STM32CUbeIDE to generate the startup code. Signal integrity is an issue with uSD cards and using jumpers to connect an off the shelf uSD card is a hit or miss proposition. I'm right in the middle of this step for a new board.

You can comment out the bits of code in the STM examples to bypass the SD Detect process. You can also jumper whatever GPIO you've defined as the SD Detect line high or low to fake the processor into thinking there's always a SD card installed. I can't remember if you have to jumper it high or low but you can check the Disco or Eval schematic to find out.

Good luck, I've torn out a lot of hair trying to get this working on several Nucleo boards that don't have native uSD slots.

I tried, I tried an empty file to open at all. Read the full file. I even used the f_stat function, but I don't see any change. I need to bite into the low level api. Generally it's that the first attempt to access the card ends with an FR_NOT_READY error and every subsequent attempt with FR_DISK_ERR.

And the same is displayed when there is no SD card in the slot.

KMach.2
Associate II

Ok, I did some work on the problem, I traced the program on two cards and two different boards, one my production one from the manufacturer.

I tried to initialize the card with disk_initialize function and it works fine. Each card on each board throws error in same place f_mount->find_volume->check_fs->move_window->disk_read->SD_read->BSP_SD_ReadBlock->HAL_SD_ReadBlocks->SDIO_ConfigData

The problem is that in HAL_SD_ReadBlocks during configuration 

  /* Configure the SD DPSM (Data Path State Machine) */.
  config.DataTimeOut = SDMMC_DATATIMEOUT;
  config.DataLength = NumberOfBlocks * BLOCKSIZE;
  config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
  config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
  config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
  config.DPSM = SDIO_DPSM_ENABLE;
  (void)SDIO_ConfigData(hsd->Instance, &config);

the called function has a macro at the end

/* Write to SDMMC DCTRL */
  MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);

When this macro is executed, a flag 1 (SDIO_FLAG_RXOVERR) appears in the SDIO.STA.RXOVERR register. Which in the rest of the program generates an error.

I am currently going to read the documentation of the function and if I can learn anything more from it about the problem.

KMach.2
Associate II

I still discovered an interesting relation, that by enabling hardware flow control in SDIO. f_mount returns FR_OK. However, on the next step an error is shown.