cancel
Showing results for 
Search instead for 
Did you mean: 

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

Bardeen Lai
Associate III
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

31 REPLIES 31
FYang.2
Associate

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
Associate

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.