STM32H750XB_RT-THREAD/37-SDMMC—FatFs移植与读写测试/User/FATFS/drivers/fatfs_sd_sdio.c

243 lines
5.9 KiB
C
Raw Permalink Normal View History

2025-07-21 06:34:29 +00:00
/**
******************************************************************************
* @file bsp_sdio_sd.c
* @author fire
* @version V1.0
* @date 2018-xx-xx
* @brief SDIO sd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ϵͳ<EFBFBD><EFBFBD>
******************************************************************************
* @attention
*
* ʵ<EFBFBD><EFBFBD>ƽ̨:<EFBFBD><EFBFBD><EFBFBD><EFBFBD> STM32 H743 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD>̳ :http://www.firebbs.cn
* <EFBFBD>Ա<EFBFBD> :http://firestm32.taobao.com
*
******************************************************************************
*/
#include "./drivers/fatfs_sd_sdio.h"
#include <stdio.h>
#include <string.h>
#include "./sd_card/bsp_sdio_sd.h"
#include "ff_gen_drv.h"
#include "./led/bsp_led.h"
/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;
extern SD_HandleTypeDef uSdHandle;
//<2F><><EFBFBD>ͱ<EFBFBD>־λ
extern volatile uint8_t TX_Flag;
//<2F><><EFBFBD>ܱ<EFBFBD>־λ
extern volatile uint8_t RX_Flag;
const Diskio_drvTypeDef SD_Driver =
{
SD_initialize,
SD_status,
SD_read,
#if _USE_WRITE == 1
SD_write,
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
SD_ioctl,
#endif /* _USE_IOCTL == 1 */
};
DSTATUS SD_initialize(BYTE lun)
{
Stat = STA_NOINIT;
if(BSP_SD_Init() == HAL_OK)
{
Stat &= ~STA_NOINIT;
}
return Stat;
}
DSTATUS SD_status(BYTE lun){
Stat = STA_NOINIT;
if(HAL_SD_GetCardState(&uSdHandle) == HAL_SD_CARD_TRANSFER)
{
Stat &= ~STA_NOINIT;
}
return Stat;
}
DRESULT SD_read(BYTE lun,//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸ʱ<E8B1B8>õ<EFBFBD>(0...)
BYTE *buff,//<2F><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
DWORD sector, //<2F><><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ
UINT count)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(1..128)
{
DRESULT res = RES_ERROR;
uint32_t timeout;
uint32_t alignedAddr;
RX_Flag = 0;
if((DWORD)buff&3)
{
DRESULT res = RES_OK;
DWORD scratch[BLOCKSIZE / 4];
while (count--)
{
res = disk_read(0,(void *)scratch, sector++, 1);
if (res != RES_OK)
{
break;
}
memcpy(buff, scratch, BLOCKSIZE);
buff += BLOCKSIZE;
}
return res;
}
alignedAddr = (uint32_t)buff & ~0x1F;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>DCache
// SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
if(HAL_SD_ReadBlocks_DMA(&uSdHandle, (uint8_t*)buff,
(uint32_t) (sector),
count) == HAL_OK)
{
/* Wait that the reading process is completed or a timeout occurs */
timeout = HAL_GetTick();
while((RX_Flag == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))
{
}
/* incase of a timeout return error */
if (RX_Flag == 0)
{
res = RES_ERROR;
}
else
{
RX_Flag = 0;
timeout = HAL_GetTick();
while((HAL_GetTick() - timeout) < SD_TIMEOUT)
{
if (HAL_SD_GetCardState(&uSdHandle) == HAL_SD_CARD_TRANSFER)
{
res = RES_OK;
/*
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;
//ʹ<><CAB9>Ӧ<EFBFBD><D3A6>DCache<68><65>Ч
SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
break;
}
}
}
}
return res;
}
DRESULT SD_write(BYTE lun,//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>豸ʱ<E8B1B8>õ<EFBFBD>(0...)
const BYTE *buff,//<2F><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
DWORD sector, //<2F><><EFBFBD><EFBFBD><EFBFBD>׵<EFBFBD>ַ
UINT count)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(1..128)
{
DRESULT res = RES_ERROR;
uint32_t timeout;
TX_Flag = 0;
if((DWORD)buff&3)
{
DRESULT res = RES_OK;
DWORD scratch[BLOCKSIZE / 4];
while (count--)
{
memcpy( scratch,buff,BLOCKSIZE);
res = disk_write(0,(void *)scratch, sector++, 1);
if (res != RES_OK)
{
break;
}
buff += BLOCKSIZE;
}
return res;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>DCache
// SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
if(HAL_SD_WriteBlocks_DMA(&uSdHandle, (uint8_t*)buff,
(uint32_t) (sector),
count) == HAL_OK)
{
/* Wait that the reading process is completed or a timeout occurs */
timeout = HAL_GetTick();
while((TX_Flag == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))
{
}
/* incase of a timeout return error */
if (TX_Flag == 0)
{
res = RES_ERROR;
}
else
{
TX_Flag = 0;
timeout = HAL_GetTick();
while((HAL_GetTick() - timeout) < SD_TIMEOUT)
{
if (HAL_SD_GetCardState(&uSdHandle) == HAL_SD_CARD_TRANSFER)
{
res = RES_OK;
//ʹ<><CAB9>Ӧ<EFBFBD><D3A6>DCache<68><65>Ч
// SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
break;
}
}
}
}
return res;
}
DRESULT SD_ioctl(BYTE lun,BYTE cmd, void *buff){
DRESULT res = RES_ERROR;
HAL_SD_CardInfoTypeDef CardInfo;
if (Stat & STA_NOINIT) return RES_NOTRDY;
switch (cmd)
{
/* Make sure that no pending write process */
case CTRL_SYNC :
res = RES_OK;
break;
/* Get number of sectors on the disk (DWORD) */
case GET_SECTOR_COUNT :
HAL_SD_GetCardInfo(&uSdHandle, &CardInfo);
*(DWORD*)buff = CardInfo.LogBlockNbr;
res = RES_OK;
break;
/* Get R/W sector size (WORD) */
case GET_SECTOR_SIZE :
HAL_SD_GetCardInfo(&uSdHandle, &CardInfo);
*(WORD*)buff = CardInfo.LogBlockSize;
res = RES_OK;
break;
/* Get erase block size in unit of sector (DWORD) */
case GET_BLOCK_SIZE :
HAL_SD_GetCardInfo(&uSdHandle, &CardInfo);
*(DWORD*)buff = CardInfo.LogBlockSize / BLOCK_SIZE;
res = RES_OK;
break;
default:
res = RES_PARERR;
}
return res;
}
/*****************************END OF FILE****************************/