#include <string.h>
#include "ff_gen_drv.h"
#include "SDdriver.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Disk status */static volatile DSTATUS Stat =STA_NOINIT;/* USER CODE END DECL *//* Private function prototypes -----------------------------------------------*/DSTATUSUSER_initialize(BYTE pdrv);DSTATUSUSER_status(BYTE pdrv);DRESULTUSER_read(BYTE pdrv,BYTE*buff,DWORD sector,UINT count);
#if _USE_WRITE ==1DRESULTUSER_write(BYTE pdrv,constBYTE*buff,DWORD sector,UINT count);
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL ==1DRESULTUSER_ioctl(BYTE pdrv,BYTE cmd,void*buff);
#endif /* _USE_IOCTL == 1 */
Diskio_drvTypeDef USER_Driver ={
USER_initialize,
USER_status,
USER_read,
#if _USE_WRITE
USER_write,
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL ==1
USER_ioctl,
#endif /* _USE_IOCTL == 1 */};/* Private functions ---------------------------------------------------------*//**
* @brief Initializes a Drive
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/DSTATUSUSER_initialize(BYTE pdrv /* Physical drive nmuber to identify the drive */){/* USER CODE BEGIN INIT */
uint8_t res;
res =SD_init();//SD_Initialize() if(res)//STM32 SPI的bug,在sd卡操作失败的时候如果不执行下面的语句,可能导致SPI读写异常{SPI_setspeed(SPI_BAUDRATEPRESCALER_256);spi_readwrite(0xff);//提供额外的8个时钟SPI_setspeed(SPI_BAUDRATEPRESCALER_2);}if(res)returnSTA_NOINIT;elsereturnRES_OK;//初始化成功/* USER CODE END INIT */}/**
* @brief Gets Disk Status
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/DSTATUSUSER_status(BYTE pdrv /* Physical drive number to identify the drive */){/* USER CODE BEGIN STATUS */switch(pdrv){case0:returnRES_OK;case1:returnRES_OK;case2:returnRES_OK;default:returnSTA_NOINIT;}/* USER CODE END STATUS */}/**
* @brief Reads Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data buffer to store read data
* @param sector: Sector address (LBA)
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/DRESULTUSER_read(BYTE pdrv,/* Physical drive nmuber to identify the drive */BYTE*buff,/* Data buffer to store read data */DWORD sector,/* Sector address in LBA */UINT count /* Number of sectors to read */){/* USER CODE BEGIN READ */
uint8_t res;if(!count ){returnRES_PARERR;/* count不能等于0,否则返回参数错误 */}switch(pdrv){case0:
res=SD_ReadDisk(buff,sector,count);//需要改写以提升速度if(res ==0){returnRES_OK;}else{returnRES_ERROR;}default:returnRES_ERROR;}/* USER CODE END READ */}/**
* @brief Writes Sector(s)
* @param pdrv: Physical drive number (0..)
* @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 ==1DRESULTUSER_write(BYTE pdrv,/* Physical drive nmuber to identify the drive */constBYTE*buff,/* Data to be written */DWORD sector,/* Sector address in LBA */UINT count /* Number of sectors to write */){/* USER CODE BEGIN WRITE *//* USER CODE HERE */
uint8_t res;if(!count ){returnRES_PARERR;/* count不能等于0,否则返回参数错误 */}switch(pdrv){case0:
res=SD_WriteDisk((uint8_t *)buff,sector,count);//需要改写以提升速度if(res ==0){returnRES_OK;}else{returnRES_ERROR;}default:returnRES_ERROR;}/* USER CODE END WRITE */}
#endif /* _USE_WRITE == 1 *//**
* @brief I/O control operation
* @param pdrv: Physical drive number (0..)
* @param cmd: Control code
* @param *buff: Buffer to send/receive control data
* @retval DRESULT: Operation result
*/
#if _USE_IOCTL ==1DRESULTUSER_ioctl(BYTE pdrv,/* Physical drive nmuber (0..) */BYTE cmd,/* Control code */void*buff /* Buffer to send/receive control data */){/* USER CODE BEGIN IOCTL */DRESULT res;switch(cmd){caseCTRL_SYNC:SD_CS(1);do{HAL_Delay(20);}while(spi_readwrite(0xFF)!=0xFF);
res=RES_OK;SD_CS(0);break;caseGET_SECTOR_SIZE:*(WORD*)buff =512;
res =RES_OK;break;caseGET_BLOCK_SIZE:*(WORD*)buff =8;
res =RES_OK;break;caseGET_SECTOR_COUNT:*(DWORD*)buff =SD_GetSectorCount();
res =RES_OK;break;default:
res =RES_PARERR;break;}return res;/* USER CODE END IOCTL */}
#endif /* _USE_IOCTL == 1 */