2017-11-29 05:53 AM
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; endifif(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:
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 stm32f7Solved! Go to Solution.
2018-05-15 03:27 AM
hi piet t how do you fix
SD_initialize to mount and open file?
2018-05-15 03:36 AM
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; }2018-05-15 04:45 AM
thank you for helping.i watched
SD_initialize function
and its correct. ReadStatus in sd_read never set to 1.this is my problem2018-05-16 01:31 PM
Hi
moeinmovafagh
,Just give me a bit and I'll help you. I just saw your message.
Regards
Piet
2018-05-16 01:41 PM
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; }