cancel
Showing results for 
Search instead for 
Did you mean: 

SD_Read bug?

con3
Senior
Posted on November 29, 2017 at 14:53

Good day everyone,

I'm not sure if this is a bug or I'm looking at this incorrectly, but It seems to be a bug.

While calling the f_mount function there is a point where SD_read is called.

DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)

{

DRESULT res = RES_ERROR;

ReadStatus = 0;

uint32_t timeout;

if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)

uint32_t alignedAddr;

endif

if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,

(uint32_t) (sector),

count) == MSD_OK)

{

/* Wait that the reading process is completed or a timeout occurs */

timeout = HAL_GetTick();

while((ReadStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))

{

}

/* incase of a timeout return error */

if (ReadStatus == 0)

{

res = RES_ERROR;

}

else

{

ReadStatus = 0;

timeout = HAL_GetTick();

while((HAL_GetTick() - timeout) < SD_TIMEOUT)

{

if (BSP_SD_GetCardState() == SD_TRANSFER_OK)

{

res = RES_OK;

if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)

/*

the SCB_InvalidateDCache_by_Addr() requires a 32-Bit aligned address,

adjust the address and the D-Cache size to invalidate accordingly.

*/

alignedAddr = (uint32_t)buff & ~3;

SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));

endif

break;

}

}

}

}

return res;

}

After this call my code enters

f(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,(uint32_t) (sector),count) == MSD_OK)

and passes it successfully, after which it gets stuck in the while loop.

while((ReadStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))

{

}

After this the problem occurs and that is:

if (ReadStatus == 0)

{

res = RES_ERROR;

}

the function always gets stuck here no matter what. So i went and looked at all the calls for ReadStatus in my project and this popped up:

0690X00000604DJQAY.jpg

From here it seems there's one callback that will ensure the SD_Read passes and thats BSP_SD_ReadCpltCallback. Although this is never called anywhere in the project and therefore SD_Read always fails. Therefore it always remain 0 and the LL read function fails. This is cube generated.

Is this a mistake from my side or CubeMX??

I'm using the latest cube(V 4.0 and the latest Hal(1.8.0) for the stm32F7

f_mount-sdcard sdcard cubemx-project stm32f7-hal stm32f7

14 REPLIES 14
Posted on May 15, 2018 at 10:27

hi piet t how do you fix 

SD_initialize to mount and open file?

Posted on May 15, 2018 at 10:36

Hi

moeinmovafagh

,

Your initialization function should look as follows:

DSTATUS SD_initialize(BYTE lun)

{

Stat = STA_NOINIT;

#if !defined(DISABLE_SD_INIT)

if(BSP_SD_Init() == MSD_OK)

{

Stat = SD_CheckStatus(lun);

}

#else

Stat = SD_CheckStatus(lun);

#endif

return Stat;

}

Posted on May 15, 2018 at 11:45

thank you for helping.i watched

SD_initialize function

  and its correct. ReadStatus in sd_read never set to 1.this is my problem
Posted on May 16, 2018 at 20:31

Hi

moeinmovafagh

,

Just give me a bit and I'll help you. I just saw your message.

Regards

Piet

Posted on May 16, 2018 at 20:41

Hi

,

Here's a quick implementation which should fix your issues for both read and writes:

Writing:

/* USER CODE BEGIN beforeWriteSection */ /* can be used to modify previous code / undefine following code / add new code */ /* USER CODE END beforeWriteSection */ /** * @brief Writes Sector(s) * @param lun : not used * @param *buff: Data to be written * @param sector: Sector address (LBA) * @param count: Number of sectors to write (1..128) * @retval DRESULT: Operation result */ #if _USE_WRITE == 1 DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count) { DRESULT res = RES_ERROR; WriteStatus = 0; uint32_t timeout; #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) uint32_t alignedAddr; /* the SCB_CleanDCache_by_Addr() requires a 32-Bit aligned address adjust the address and the D-Cache size to clean accordingly. */ alignedAddr = (uint32_t)buff & ~3; SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr)); #endif if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff, (uint32_t) (sector), count) == MSD_OK) { /* Wait that the writing process is completed or a timeout occurs */ WriteStatus = 1; timeout = HAL_GetTick(); while((WriteStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT)) { } /* incase of a timeout return error */ if (WriteStatus == 0) { res = RES_ERROR; } else { WriteStatus = 0; timeout = HAL_GetTick(); while((HAL_GetTick() - timeout) < SD_TIMEOUT) { if (BSP_SD_GetCardState() == SD_TRANSFER_OK) { res = RES_OK; break; } } } } return res; } #endif /* _USE_WRITE == 1 */

Reading:

DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count) { DRESULT res = RES_ERROR; ReadStatus = 0; uint32_t timeout; #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) uint32_t alignedAddr; #endif if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff, (uint32_t) (sector), count) == MSD_OK) { /* Wait that the reading process is completed or a timeout occurs */ ReadStatus = 1; timeout = HAL_GetTick(); while((ReadStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT)) { } /* incase of a timeout return error */ if (ReadStatus == 0) { res = RES_ERROR; } else { ReadStatus = 0; timeout = HAL_GetTick(); while((HAL_GetTick() - timeout) < SD_TIMEOUT) { if (BSP_SD_GetCardState() == SD_TRANSFER_OK) { res = RES_OK; #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) /* the SCB_InvalidateDCache_by_Addr() requires a 32-Bit aligned address, adjust the address and the D-Cache size to invalidate accordingly. */ alignedAddr = (uint32_t)buff & ~3; SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr)); #endif break; } } } } return res; }