Skip to main content
Bardeen Lai
Associate
January 2, 2018
Solved

Solution to fix STM32F4xxx STMCubeMX Firmware V1.18 SDIO FATFS DMA not working issue

  • January 2, 2018
  • 31 replies
  • 9121 views
Posted on January 02, 2018 at 12:18

Hi all,

Recently I use STM32CubeMX Ver 4.0 (STMCube V1.0), firmware V1.18 to generate codes for STM32F407 by using SDIO 4-bit bus to access SD card via DMA or standard IO. The generated codes could not function probably.

In order to make it work, you have to modify three files generated by STM32CubeMX:

1. bsp_driver_sd.c

2. sd_diskio.c

3. fatfs.c

Here are the procedures:

1.

bsp_driver_sd.c

Modify the

BSP_SD_WriteBlocks() and

BSP_SD_ReadBlocks_DMA() to support DMA or standard I/O:

// A flag indicating if to use DMA for read/write
uint8_t BSP_SD_Ext_UseDMA = 1;
/*==========================================================================
 Description
 DMA or polling mode of Reads block(s) from a specified address in an SD card
* @param pData: Pointer to the buffer that will contain the data to transmit
 * @param ReadAddr: Address from where data is to be read 
 * @param NumOfBlocks: Number of SD blocks to read 
 * @param Timeout: Timeout for read operation
 * @retval SD status
---------------------------------------------------------------------------*/
uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout)
{
 HAL_SD_StateTypeDef state_return;
 uint32_t timeout = 0;
 if (BSP_SD_Ext_UseDMA == 0) {
 if (HAL_SD_ReadBlocks(&hsd, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout) != HAL_OK)
 return MSD_ERROR;
 } else {
// Read block(s) in DMA transfer mode
 if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t*) pData, ReadAddr, NumOfBlocks) != HAL_OK)
 return MSD_ERROR;
 // Wait until the SDIO/SDMMC and DMA finish the read/write
 timeout = 0;
 do {
 state_return = HAL_SD_GetState(&hsd);
 timeout++;
 } while((state_return == HAL_SD_STATE_BUSY) && (timeout < SD_DATATIMEOUT));
 if (HAL_SD_STATE_READY != state_return)
 return MSD_ERROR;
 }
 return MSD_OK;
}
/*==========================================================================
 Description
 DMA or polling mode of Write block(s) to a specified address in an SD card
* @param pData: Pointer to the buffer that will contain the data to transmit
 * @param WriteAddr: Address from where data is to be written
 * @param NumOfBlocks: Number of SD blocks to write
 * @param Timeout: Timeout for write operation
 * @retval SD status
---------------------------------------------------------------------------*/
uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout)
{
 HAL_SD_StateTypeDef state_return;
 uint32_t timeout = 0;
 if(BSP_SD_Ext_UseDMA == 0) {
 if (HAL_SD_WriteBlocks(&hsd, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) != HAL_OK)
 return MSD_ERROR;
 } else {
// Read block(s) in DMA transfer mode
 if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t*) pData, WriteAddr, NumOfBlocks) != HAL_OK)
 return MSD_ERROR;
 // Wait until the SDIO/SDMMC and DMA finish the read/write
timeout = 0;
 do {
 state_return = HAL_SD_GetState(&hsd);
 timeout++;
 } 
 while((state_return == HAL_SD_STATE_BUSY) && (timeout < SD_DATATIMEOUT));
if (HAL_SD_STATE_READY != state_return)
 return MSD_ERROR;
 }
 return MSD_OK;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

2. sd_diskio.c

i) fix the missing initialization code for SDIO

Original generated code:

DSTATUS SD_initialize(BYTE lun)
{
 return SD_CheckStatus(lun);
}�?�?�?�?

Shoud be modified (I have no idea

why BSP_SD_Init() was missing!

:(

DSTATUS SD_initialize(BYTE lun)
{
 Stat = STA_NOINIT;
 if (BSP_SD_Init() == MSD_OK)
 Stat = SD_CheckStatus(lun);
 return Stat;
}�?�?�?�?�?�?�?�?�?

Otherwise, it could not initialize the SDIOvia HAL_SD_Init()!

ii) modifySD_read() andSD_write:

DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
{
 DRESULT res = RES_ERROR;
 if (BSP_SD_ReadBlocks((uint32_t*)buff,
 (uint32_t) (sector),
 count,
 SDMMC_DATATIMEOUT) == MSD_OK) {
 // wait until the read operation is finished
 while (BSP_SD_GetCardState()!= MSD_OK);
 res = RES_OK;
 }
 return res;
}
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
 DRESULT res = RES_ERROR;
 if (BSP_SD_WriteBlocks((uint32_t*)buff,
 (uint32_t)(sector),
 count,
 SDMMC_DATATIMEOUT) == MSD_OK) {
 // wait until the Write operation is finished
 while (BSP_SD_GetCardState() != MSD_OK);
 res = RES_OK;
 }
 return res;
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

3.

fatfs.c

Add a mounting procedure to mount thefile system of SD card

Original generated code:

void MX_FATFS_Init(void) 
{
 /*## FatFS: Link the SD driver ###########################*/
 retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
 /* USER CODE BEGIN Init */
 /* additional user code for init */ 
 
 /* USER CODE END Init */
}�?�?�?�?�?�?�?�?�?�?

Modified code:

void MX_FATFS_Init(void) 
{
 /*## FatFS: Link the SD driver ###########################*/
 retSD = FATFS_LinkDriver(&SD_Driver, SDPath);
 /* USER CODE BEGIN Init */
 /* additional user code for init */ 
 if (retSD != 0)
 Error_Handler();
 if (f_mount(&SDFatFS, (TCHAR const*)SDPath, 0) != FR_OK)
 Error_Handler();
 /* USER CODE END Init */
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Finally, we could write codes to test the FATFS :

void SDFileTest(void)
{
 FIL MyFile;
 FRESULT res; /* FatFs function common result code */
 uint32_t byteswritten, bytesread; /* File write/read counts */
 uint8_t wtext[] = 'Hello, STM32F4 FatFs!'; /* File write buffer */
 uint8_t rtext[100]; /* File read buffer */
 printf('SD File create\n');
 // Create file test
 if (f_open(&MyFile, 'STMTXT', FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
 Error_Handler();
 res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);
 if ((byteswritten == 0) || (res != FR_OK))
 Error_Handler();
 f_close(&MyFile);
 printf('done!\n');
 printf('SD File open\n');
 // Read file test
 if (f_open(&MyFile, 'STMTXT', FA_READ) != FR_OK)
 Error_Handler();
 res = f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread);
 
 if ((bytesread == 0) || (res != FR_OK))
 Error_Handler();
 f_close(&MyFile);
 
 if ((bytesread != byteswritten))
 Error_Handler();
 printf('done!\n');
}
int main(void)
{
.
.
 MX_DMA_Init();
 .
 .
 MX_SDIO_SD_Init();
 .
 .
 MX_FATFS_Init();
 .
 .
 SDFileTest();
 while (1);
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

It works and note that I have reported this kind of issue to ST on-line support team.

Best regards

This topic has been closed for replies.
Best answer by Bardeen Lai
Posted on February 22, 2018 at 07:16

Hi,

I have tested FATFS by use of DMA under FreeRTOS, it works!

Here is the screen capture of setting STM32CubeMX V4.24

0690X00000609MwQAI.png

Project Setting:

0690X00000609k3QAA.png

Make sure FATFS configuration ''Use dma template'' enabled:

0690X00000609m8QAA.png

SDIO settings:

Enable NVIC

0690X00000609mDQAQ.png

and DMA settings

0690X00000609mIQAQ.png

Then, tune the FreeRTOS, stack and heap sizes

0690X00000609htQAA.png

After generating codes, you have to modify the following files:

A. sd_diskio.c (as told by

), you have to insert the following code at the end of the file

#endif /* _USE_IOCTL == 1 *//* USER CODE BEGIN afterIoctlSection *//* can be used to modify previous code / undefine following code / add new code *//* USER CODE END afterIoctlSection *//* USER CODE BEGIN callbackSection *//* can be used to modify / following code or add new code */void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd){ osMessagePut(SDQueueID, WRITE_CPLT_MSG, osWaitForever);}void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd){ osMessagePut(SDQueueID, READ_CPLT_MSG, osWaitForever);}/* USER CODE END callbackSection */�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

NOTE: HAL_SD_ReadBlocks_DMA and HAL_SD_WriteBlocks_DMA require DMA complete TX/RX interrupt to signal the foreground process whether the DMA TX/RX has been done or not.

B. If you are using MDK-ARM as your IDE, you should eliminate the ''U'', otherwise it would cause compiler error in port.c

Modify the stm32f407xx.h header file to fix error:

#define __NVIC_PRIO_BITS 4 /*!< STM32F4XX uses 4 Bits for the Priority Levels */�?

C. Modify the freertos.c file, insert the FATFS file test procedure:

/* USER CODE BEGIN FunctionPrototypes */void SDFileTest(void){ FIL MyFile; FRESULT res; /* FatFs function common result code */ uint32_t byteswritten, bytesread; /* File write/read counts */ uint8_t wtext[] = ''Hello, STM32F4 FatFs!''; /* File write buffer */ uint8_t rtext[100]; /* File read buffer */// printf(''SD File create''); // Create file test if (f_open(&MyFile, ''STMTXT'', FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) Error_Handler(); res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten); if ((byteswritten == 0) || (res != FR_OK)) Error_Handler(); f_close(&MyFile);// printf(''done!'');// printf(''SD File open''); // Read file test if (f_open(&MyFile, ''STMTXT'', FA_READ) != FR_OK) Error_Handler(); res = f_read(&MyFile, rtext, sizeof(rtext), (UINT*)&bytesread); if ((bytesread == 0) || (res != FR_OK)) Error_Handler(); f_close(&MyFile); if ((bytesread != byteswritten)) Error_Handler();// printf(''done!'');}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

and insert the following piece of code to

/* StartDefaultTask function */void StartDefaultTask(void const * argument){ /* init code for FATFS */ MX_FATFS_Init(); /* USER CODE BEGIN StartDefaultTask */ if (f_mount(&SDFatFS, (TCHAR const*)SDPath, 0) != FR_OK) Error_Handler(); SDFileTest(); /* Infinite loop */ for(;;) { osDelay(1); } /* USER CODE END StartDefaultTask */}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I could email you the complete project file if you need.

Good luck and cheers

Bardeen LAI

31 replies

Vagni
Associate III
May 2, 2018
Posted on May 02, 2018 at 19:29

Dear all,

The issue is still present in the lastSTM32F4 Firmware Package v1.0.

I have my custom board based on STM32F401xx cpu and my old SDIO+DMA+FATFS+FreeRTOS application developed with STM32CubeMX v4.0 and

STM32F4 Firmware Package v1.0 that runs without problems, reading and writing files on a SD card.

Now I have to develope a new application on the same board. I decided to start my new project withSTM32CubeMX v4.0 and

STM32F4 Firmware Package v1.0, the last released versions.

Testing SD card accesses with the new created code always fails in the f_mount() function, because anSD_TIMEOUT event (30 seconds) occurs.

Then I followed the excellent help of

bardeenlai

, I use the same settings in my STM32CubeMX project for SDIO, FATFS and FreeRTOS, but f_mount() always fails for theSD_TIMEOUT event.

The generated code just includes the callback functions at the end of

sd_diskio.c source file, but again there is still somethingwrong/missing in the generated code.

Should I useSTM32F4 Firmware Package v1.0 to solve my SD card issue?

Should I keep usingSTM3

2F4 Firmware Package v1.0, waiting for SDIO+DMA+FATFS+FreeRTOS handling to be fixed?

aasa
Visitor II
September 12, 2018

I'm frustrated to find myself impacted by this same bug, and on top of it the STM forums are broken.

All I see is "The original post was too long to process for migration; we will restore it soon."

It's been like this for over a week now.

@Bardeen Lai​ Is there any chance you can re post your solution? I would be very grateful.

Lionel1
Associate III
July 12, 2019

Hi

I use CubeMX V5.2.1 and firmware is V1.24.1.

I would like to know if the problems you said are corrected or if I must use your workaround ?

Thanks,

Lionel

FYang.2
Visitor II
December 24, 2020

I m not sure this issue closed or not . But the problem similarity has been occured in my board . it is using F407 ,FreeRtos CMSIS V1 , Fatfs r0,12c and cubemax 6.1.0. it probably due to the cubemax 6.1.0 , because of under the same configuration, generated by cubemax 5.0.1 the SD card function is run good, 6.0.1 and 6.1.0 cannot mount the same SD card. i hope experts give me some help about that.

Yuyty.1
Visitor II
May 29, 2021

Yes its very complicated issue I am also facing the same issue but tried to solve it also but its not working well please help me to solve it you can see here every one is facing the similar issue.