DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count) { DRESULT res = RES_ERROR; uint32_t timeout; uint8_t ret; #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) uint32_t alignedAddr; #endif /* * ensure the SDCard is ready for a new operation */ if (SD_CheckStatusWithTimeout(SD_TIMEOUT) < 0) { return res; } #if defined(ENABLE_SCRATCH_BUFFER) if (!((uint32_t)buff & 0x3)) { #endif if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff, (uint32_t) (sector), count) == MSD_OK) { ReadStatus = 0; /* 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-Byte aligned address, adjust the address and the D-Cache size to invalidate accordingly. */ alignedAddr = (uint32_t)buff & ~0x1F; SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr)); #endif break; } } } } #if defined(ENABLE_SCRATCH_BUFFER) else { /* Slow path, fetch each sector a part and memcpy to destination buffer */ int i; for (i = 0; i < count; i++) { ret = BSP_SD_ReadBlocks_DMA((uint32_t*)scratch, (uint32_t)sector++, 1); if (ret == MSD_OK) { /* wait until the read is successful or a timeout occurs */ ReadStatus = 0; timeout = HAL_GetTick(); while((ReadStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT)) { } if (ReadStatus == 0) { break; } #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) /* * * invalidate the scratch buffer before the next read to get the actual data instead of the cached one */ SCB_InvalidateDCache_by_Addr((uint32_t*)scratch, BLOCKSIZE); #endif memcpy(buff, scratch, BLOCKSIZE); buff += BLOCKSIZE; } else { break; } } if ((i == count) && (ret == MSD_OK)) res = RES_OK; } #endif } return res; } /** * @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; uint32_t timeout; uint8_t ret; int i; WriteStatus = 0; #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) uint32_t alignedAddr; #endif if (SD_CheckStatusWithTimeout(SD_TIMEOUT) < 0) { return res; } #if defined(ENABLE_SCRATCH_BUFFER) if (!((uint32_t)buff & 0x3)) { #endif #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) /* the SCB_CleanDCache_by_Addr() requires a 32-Byte aligned address adjust the address and the D-Cache size to clean accordingly. */ alignedAddr = (uint32_t)buff & ~0x1F; 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 writing process is completed or a timeout occurs */ 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; } } } } else { /* Slow path, fetch each sector a part and memcpy to destination buffer */ #if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1) /* * invalidate the scratch buffer before the next write to get the actual data instead of the cached one */ SCB_InvalidateDCache_by_Addr((uint32_t*)scratch, BLOCKSIZE); #endif for (i = 0; i < count; i++) { WriteStatus = 0; ret = BSP_SD_WriteBlocks_DMA((uint32_t*)scratch, (uint32_t)sector++, 1); if (ret == MSD_OK) { /* wait for a message from the queue or a timeout */ timeout = HAL_GetTick(); while((WriteStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT)) { } if (WriteStatus == 0) { break; } memcpy((void *)buff, (void *)scratch, BLOCKSIZE); buff += BLOCKSIZE; } else { break; } } if ((i == count) && (ret == MSD_OK)) res = RES_OK; } } return res; }