2017-04-12 09:25:37 +08:00
|
|
|
|
#include "drv_sdio_sd.h"
|
|
|
|
|
#include "string.h"
|
|
|
|
|
#include <rtthread.h>
|
|
|
|
|
#include <dfs_fs.h>
|
|
|
|
|
|
|
|
|
|
SD_HandleTypeDef SDCARD_Handler;
|
|
|
|
|
HAL_SD_CardInfoTypedef SDCardInfo; //SD<53><44><EFBFBD><EFBFBD>Ϣ<EFBFBD>ṹ<EFBFBD><E1B9B9>
|
|
|
|
|
DMA_HandleTypeDef SDTxDMAHandler,SDRxDMAHandler; //SD<53><44>DMA<4D><41><EFBFBD>ͺͽ<CDBA><CDBD>վ<EFBFBD><D5BE><EFBFBD>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//SD<53><44><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֵ:0 <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2017-10-16 13:23:03 +08:00
|
|
|
|
rt_uint8_t SD_Init(void)
|
2017-04-12 09:25:37 +08:00
|
|
|
|
{
|
|
|
|
|
rt_uint8_t SD_Error;
|
|
|
|
|
|
|
|
|
|
//<2F><>ʼ<EFBFBD><CABC>ʱ<EFBFBD><CAB1>ʱ<EFBFBD>Ӳ<EFBFBD><D3B2>ܴ<EFBFBD><DCB4><EFBFBD>400KHZ
|
|
|
|
|
SDCARD_Handler.Instance=SDIO;
|
|
|
|
|
SDCARD_Handler.Init.ClockEdge=SDIO_CLOCK_EDGE_RISING; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
SDCARD_Handler.Init.ClockBypass=SDIO_CLOCK_BYPASS_DISABLE; //<2F><>ʹ<EFBFBD><CAB9>bypassģʽ<C4A3><CABD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD>HCLK<4C><4B><EFBFBD>з<EFBFBD>Ƶ<EFBFBD>õ<EFBFBD>SDIO_CK
|
|
|
|
|
SDCARD_Handler.Init.ClockPowerSave=SDIO_CLOCK_POWER_SAVE_DISABLE; //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ر<EFBFBD>ʱ<EFBFBD>ӵ<EFBFBD>Դ
|
|
|
|
|
SDCARD_Handler.Init.BusWide=SDIO_BUS_WIDE_1B; //1λ<31><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
SDCARD_Handler.Init.HardwareFlowControl=SDIO_HARDWARE_FLOW_CONTROL_DISABLE;//<2F>ر<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
SDCARD_Handler.Init.ClockDiv=SDIO_TRANSFER_CLK_DIV; //SD<53><44><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>25MHZ
|
|
|
|
|
|
|
|
|
|
SD_Error=HAL_SD_Init(&SDCARD_Handler,&SDCardInfo);
|
|
|
|
|
if(SD_Error!=SD_OK) return 1;
|
|
|
|
|
|
|
|
|
|
SD_Error=HAL_SD_WideBusOperation_Config(&SDCARD_Handler,SDIO_BUS_WIDE_4B);//ʹ<>ܿ<EFBFBD><DCBF><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
|
|
|
|
if(SD_Error!=SD_OK) return 2;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//SDMMC<4D>ײ<EFBFBD><D7B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>ʹ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>DMA<4D><41><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F>˺<EFBFBD><CBBA><EFBFBD><EFBFBD>ᱻHAL_SD_Init()<29><><EFBFBD><EFBFBD>
|
|
|
|
|
//hsd:SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
|
|
|
|
|
{
|
|
|
|
|
DMA_HandleTypeDef TxDMAHandler,RxDMAHandler;
|
|
|
|
|
GPIO_InitTypeDef GPIO_Initure;
|
|
|
|
|
|
|
|
|
|
__HAL_RCC_SDIO_CLK_ENABLE(); //ʹ<><CAB9>SDIOʱ<4F><CAB1>
|
|
|
|
|
__HAL_RCC_DMA2_CLK_ENABLE(); //ʹ<><CAB9>DMA2ʱ<32><CAB1>
|
|
|
|
|
__HAL_RCC_GPIOC_CLK_ENABLE(); //ʹ<><CAB9>GPIOCʱ<43><CAB1>
|
|
|
|
|
__HAL_RCC_GPIOD_CLK_ENABLE(); //ʹ<><CAB9>GPIODʱ<44><CAB1>
|
|
|
|
|
|
|
|
|
|
//PC8,9,10,11,12
|
|
|
|
|
GPIO_Initure.Pin=GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
|
|
|
|
|
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //<2F><><EFBFBD>츴<EFBFBD><ECB8B4>
|
|
|
|
|
GPIO_Initure.Pull=GPIO_PULLUP; //<2F><><EFBFBD><EFBFBD>
|
|
|
|
|
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //<2F><><EFBFBD><EFBFBD>
|
|
|
|
|
GPIO_Initure.Alternate=GPIO_AF12_SDIO; //<2F><><EFBFBD><EFBFBD>ΪSDIO
|
|
|
|
|
HAL_GPIO_Init(GPIOC,&GPIO_Initure); //<2F><>ʼ<EFBFBD><CABC>
|
|
|
|
|
|
|
|
|
|
//PD2
|
|
|
|
|
GPIO_Initure.Pin=GPIO_PIN_2;
|
|
|
|
|
HAL_GPIO_Init(GPIOD,&GPIO_Initure); //<2F><>ʼ<EFBFBD><CABC>
|
|
|
|
|
|
|
|
|
|
#if (SD_DMA_MODE==1) //ʹ<><CAB9>DMAģʽ
|
|
|
|
|
HAL_NVIC_SetPriority(SDMMC1_IRQn,2,0); //<2F><><EFBFBD><EFBFBD>SDMMC1<43>жϣ<D0B6><CFA3><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>ȼ<EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>0
|
|
|
|
|
HAL_NVIC_EnableIRQ(SDMMC1_IRQn); //ʹ<><CAB9>SDMMC1<43>ж<EFBFBD>
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD>DMA
|
|
|
|
|
SDRxDMAHandler.Instance=DMA2_Stream3;
|
|
|
|
|
SDRxDMAHandler.Init.Channel=DMA_CHANNEL_4;
|
|
|
|
|
SDRxDMAHandler.Init.Direction=DMA_PERIPH_TO_MEMORY;
|
|
|
|
|
SDRxDMAHandler.Init.PeriphInc=DMA_PINC_DISABLE;
|
|
|
|
|
SDRxDMAHandler.Init.MemInc=DMA_MINC_ENABLE;
|
|
|
|
|
SDRxDMAHandler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;
|
|
|
|
|
SDRxDMAHandler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;
|
|
|
|
|
SDRxDMAHandler.Init.Mode=DMA_PFCTRL;
|
|
|
|
|
SDRxDMAHandler.Init.Priority=DMA_PRIORITY_VERY_HIGH;
|
|
|
|
|
SDRxDMAHandler.Init.FIFOMode=DMA_FIFOMODE_ENABLE;
|
|
|
|
|
SDRxDMAHandler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
|
|
|
|
|
SDRxDMAHandler.Init.MemBurst=DMA_MBURST_INC4;
|
|
|
|
|
SDRxDMAHandler.Init.PeriphBurst=DMA_PBURST_INC4;
|
|
|
|
|
|
|
|
|
|
__HAL_LINKDMA(hsd, hdmarx, SDRxDMAHandler); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DMA<4D><41>SD<53><44><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD>DMA<4D><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
HAL_DMA_DeInit(&SDRxDMAHandler);
|
|
|
|
|
HAL_DMA_Init(&SDRxDMAHandler); //<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DMA
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ý<EFBFBD><C3BD><EFBFBD>DMA
|
|
|
|
|
SDTxDMAHandler.Instance=DMA2_Stream6;
|
|
|
|
|
SDTxDMAHandler.Init.Channel=DMA_CHANNEL_4;
|
|
|
|
|
SDTxDMAHandler.Init.Direction=DMA_MEMORY_TO_PERIPH;
|
|
|
|
|
SDTxDMAHandler.Init.PeriphInc=DMA_PINC_DISABLE;
|
|
|
|
|
SDTxDMAHandler.Init.MemInc=DMA_MINC_ENABLE;
|
|
|
|
|
SDTxDMAHandler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;
|
|
|
|
|
SDTxDMAHandler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;
|
|
|
|
|
SDTxDMAHandler.Init.Mode=DMA_PFCTRL;
|
|
|
|
|
SDTxDMAHandler.Init.Priority=DMA_PRIORITY_VERY_HIGH;
|
|
|
|
|
SDTxDMAHandler.Init.FIFOMode=DMA_FIFOMODE_ENABLE;
|
|
|
|
|
SDTxDMAHandler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
|
|
|
|
|
SDTxDMAHandler.Init.MemBurst=DMA_MBURST_INC4;
|
|
|
|
|
SDTxDMAHandler.Init.PeriphBurst=DMA_PBURST_INC4;
|
|
|
|
|
|
|
|
|
|
__HAL_LINKDMA(hsd, hdmatx, SDTxDMAHandler);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DMA<4D><41>SD<53><44><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD>DMA<4D><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
HAL_DMA_DeInit(&SDTxDMAHandler);
|
|
|
|
|
HAL_DMA_Init(&SDTxDMAHandler); //<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DMA
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 3, 0); //<2F><><EFBFBD><EFBFBD>DMA<4D>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>ȼ<EFBFBD>
|
|
|
|
|
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
|
|
|
|
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 3, 0); //<2F><><EFBFBD><EFBFBD>DMA<4D>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>ȼ<EFBFBD>
|
|
|
|
|
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
|
|
|
|
//cardinfo:<3A><><EFBFBD><EFBFBD>Ϣ<EFBFBD>洢<EFBFBD><E6B4A2>
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
|
|
|
|
|
rt_uint8_t SD_GetCardInfo(HAL_SD_CardInfoTypedef *cardinfo)
|
|
|
|
|
{
|
|
|
|
|
rt_uint8_t sta;
|
|
|
|
|
sta=HAL_SD_Get_CardInfo(&SDCARD_Handler,cardinfo);
|
|
|
|
|
return sta;
|
|
|
|
|
}
|
|
|
|
|
#if (SD_DMA_MODE==1) //DMAģʽ
|
|
|
|
|
|
|
|
|
|
//ͨ<><CDA8>DMA<4D><41>ȡSD<53><44>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//buf:<3A><><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//sector:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
|
|
|
|
//blocksize:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С(һ<>㶼<EFBFBD><E3B6BC>512<31>ֽ<EFBFBD>)
|
|
|
|
|
//cnt:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬;0,<2C><><EFBFBD><EFBFBD>;<3B><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
rt_uint8_t SD_ReadBlocks_DMA(uint32_t *buf,uint64_t sector ,uint32_t cnt)
|
|
|
|
|
{
|
|
|
|
|
rt_uint8_t err=SD_OK;
|
|
|
|
|
err=HAL_SD_ReadBlocks_DMA(&SDCARD_Handler,buf,sector,SECTOR_SIZE,cnt);//ͨ<><CDA8>DMA<4D><41>ȡSD<53><44>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if(err==SD_OK)//<2F><>ȡ<EFBFBD>ɹ<EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
//<2F>ȴ<EFBFBD><C8B4><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
|
|
|
|
err=HAL_SD_CheckReadOperation(&SDCARD_Handler,(uint32_t)SD_TIMEOUT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//дSD<53><44>
|
|
|
|
|
//buf:д<><D0B4><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//sector:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
|
|
|
|
//blocksize:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С(һ<>㶼<EFBFBD><E3B6BC>512<31>ֽ<EFBFBD>)
|
|
|
|
|
//cnt:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬;0,<2C><><EFBFBD><EFBFBD>;<3B><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
rt_uint8_t SD_WriteBlocks_DMA(uint32_t *buf,uint64_t sector,uint32_t cnt)
|
|
|
|
|
{
|
|
|
|
|
rt_uint8_t err=SD_OK;
|
|
|
|
|
err=HAL_SD_WriteBlocks_DMA(&SDCARD_Handler,buf,sector,SECTOR_SIZE,cnt);//ͨ<><CDA8>DMAдSD<53><44>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if(err==SD_OK)//д<>ɹ<EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
err=HAL_SD_CheckWriteOperation(&SDCARD_Handler,(uint32_t)SD_TIMEOUT);//<2F>ȴ<EFBFBD><C8B4><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>/
|
|
|
|
|
}
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//SDMMC1<43>жϷ<D0B6><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
void SDMMC1_IRQHandler(void)
|
|
|
|
|
{
|
|
|
|
|
HAL_SD_IRQHandler(&SDCARD_Handler);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//DMA2<41><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>6<EFBFBD>жϷ<D0B6><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
void DMA2_Stream6_IRQHandler(void)
|
|
|
|
|
{
|
|
|
|
|
HAL_DMA_IRQHandler(SDCARD_Handler.hdmatx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//DMA2<41><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD>жϷ<D0B6><CFB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
void DMA2_Stream3_IRQHandler(void)
|
|
|
|
|
{
|
|
|
|
|
HAL_DMA_IRQHandler(SDCARD_Handler.hdmarx);
|
|
|
|
|
}
|
|
|
|
|
#else //<2F><>ѵģʽ
|
|
|
|
|
|
|
|
|
|
//<2F><>ȡSD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//buf:<3A><><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//sector:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
|
|
|
|
//cnt:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬;0,<2C><><EFBFBD><EFBFBD>;<3B><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
rt_uint8_t SD_ReadBlocks(uint32_t *buf,uint64_t sector ,uint32_t cnt)
|
|
|
|
|
{
|
|
|
|
|
rt_uint8_t err=SD_OK;
|
|
|
|
|
err=HAL_SD_ReadBlocks(&SDCARD_Handler,buf,sector,SECTOR_SIZE,cnt);//ͨ<><CDA8>DMA<4D><41>ȡSD<53><44>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//дSD<53><44><EFBFBD><EFBFBD>
|
|
|
|
|
//buf:д<><D0B4><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//sector:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
|
|
|
|
//cnt:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬;0,<2C><><EFBFBD><EFBFBD>;<3B><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
|
|
|
|
rt_uint8_t SD_WriteBlocks(uint32_t *buf,uint64_t sector,uint32_t cnt)
|
|
|
|
|
{
|
|
|
|
|
return HAL_SD_WriteBlocks(&SDCARD_Handler,buf,sector,SECTOR_SIZE,cnt);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* RT-Thread SD Card Driver
|
|
|
|
|
* 20100715 Bernard support SDHC card great than 4G.
|
|
|
|
|
* 20110905 JoyChen support to STM32F2xx
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct rt_device sdcard_device;
|
|
|
|
|
static struct rt_semaphore sd_lock;
|
|
|
|
|
|
|
|
|
|
/* RT-Thread Device Driver Interface */
|
|
|
|
|
static rt_err_t rt_sdcard_init(rt_device_t dev)
|
|
|
|
|
{
|
|
|
|
|
if (rt_sem_init(&sd_lock, "sdlock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
rt_kprintf("init sd lock semaphore failed\n");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
rt_kprintf("SD Card init OK\n");
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
|
|
|
|
|
{
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static rt_err_t rt_sdcard_close(rt_device_t dev)
|
|
|
|
|
{
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint32_t sdio_buffer[512/sizeof(uint32_t)];
|
|
|
|
|
static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
|
|
|
|
{
|
|
|
|
|
rt_uint8_t status = SD_OK;
|
|
|
|
|
|
|
|
|
|
rt_sem_take(&sd_lock, RT_WAITING_FOREVER);
|
|
|
|
|
|
|
|
|
|
if(((uint32_t)buffer & 0x03) != 0)
|
|
|
|
|
{
|
|
|
|
|
/* non-aligned. */
|
|
|
|
|
uint32_t i;
|
2017-09-14 17:23:09 +08:00
|
|
|
|
uint64_t sector_adr;
|
2017-04-12 09:25:37 +08:00
|
|
|
|
uint8_t* copy_buffer;
|
|
|
|
|
|
2017-09-14 17:23:09 +08:00
|
|
|
|
sector_adr = (uint64_t)pos*SECTOR_SIZE;
|
2017-04-12 09:25:37 +08:00
|
|
|
|
copy_buffer = (uint8_t*)buffer;
|
|
|
|
|
|
|
|
|
|
for(i=0; i<size; i++)
|
|
|
|
|
{
|
|
|
|
|
#if (SD_DMA_MODE==1)
|
|
|
|
|
status=SD_ReadBlocks_DMA(sdio_buffer,sector_adr,1);//ͨ<><CDA8>DMAдSD<53><44>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
#else
|
|
|
|
|
status=SD_ReadBlocks(sdio_buffer,sector_adr,1);
|
|
|
|
|
#endif
|
|
|
|
|
memcpy(copy_buffer, sdio_buffer, SECTOR_SIZE);
|
|
|
|
|
sector_adr += SECTOR_SIZE;
|
|
|
|
|
copy_buffer += SECTOR_SIZE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#if (SD_DMA_MODE==1)
|
2017-09-14 17:23:09 +08:00
|
|
|
|
status=SD_ReadBlocks_DMA(buffer,(uint64_t)pos*SECTOR_SIZE,size);//ͨ<><CDA8>DMAдSD<53><44>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2017-04-12 09:25:37 +08:00
|
|
|
|
#else
|
2017-09-14 17:23:09 +08:00
|
|
|
|
SD_ReadBlocks(buffer,(uint64_t)pos*SECTOR_SIZE,size);
|
2017-04-12 09:25:37 +08:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rt_sem_release(&sd_lock);
|
|
|
|
|
if (status == SD_OK) return size;
|
|
|
|
|
|
|
|
|
|
rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
|
|
|
|
{
|
|
|
|
|
rt_uint8_t status = SD_OK;
|
|
|
|
|
rt_sem_take(&sd_lock, RT_WAITING_FOREVER);
|
|
|
|
|
|
|
|
|
|
if(((uint32_t)buffer & 0x03) != 0)
|
|
|
|
|
{
|
|
|
|
|
/* non-aligned. */
|
|
|
|
|
uint32_t i;
|
2017-09-14 17:23:09 +08:00
|
|
|
|
uint64_t sector_adr;
|
2017-04-12 09:25:37 +08:00
|
|
|
|
uint8_t* copy_buffer;
|
|
|
|
|
|
2017-09-14 17:23:09 +08:00
|
|
|
|
sector_adr = (uint64_t)pos*SECTOR_SIZE;
|
2017-04-12 09:25:37 +08:00
|
|
|
|
copy_buffer = (uint8_t*)buffer;
|
|
|
|
|
|
|
|
|
|
for(i=0; i<size; i++)
|
|
|
|
|
{
|
|
|
|
|
memcpy(sdio_buffer, copy_buffer, SECTOR_SIZE);
|
|
|
|
|
#if (SD_DMA_MODE==1)
|
|
|
|
|
status=SD_WriteBlocks_DMA((uint32_t*)sdio_buffer,sector_adr,1);
|
|
|
|
|
#else
|
|
|
|
|
status=SD_WriteBlocks((uint32_t*)sdio_buffer,sector_adr,1);
|
|
|
|
|
#endif
|
|
|
|
|
sector_adr += SECTOR_SIZE;
|
|
|
|
|
copy_buffer += SECTOR_SIZE;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#if (SD_DMA_MODE==1)
|
2017-09-14 17:23:09 +08:00
|
|
|
|
status=SD_WriteBlocks_DMA((uint32_t*)buffer,(uint64_t)pos*SECTOR_SIZE,size);
|
2017-04-12 09:25:37 +08:00
|
|
|
|
#else
|
2017-09-14 17:23:09 +08:00
|
|
|
|
status=SD_WriteBlocks((uint32_t*)buffer,(uint64_t)pos*SECTOR_SIZE,size);
|
2017-04-12 09:25:37 +08:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
// }
|
|
|
|
|
rt_sem_release(&sd_lock);
|
|
|
|
|
if (status == SD_OK) return size;
|
|
|
|
|
rt_kprintf("write failed: %d, buffer 0x%08x\n", status, buffer);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-16 13:23:03 +08:00
|
|
|
|
static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
|
2017-04-12 09:25:37 +08:00
|
|
|
|
{
|
|
|
|
|
RT_ASSERT(dev != RT_NULL);
|
|
|
|
|
|
|
|
|
|
if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
|
|
|
|
|
{
|
|
|
|
|
struct rt_device_blk_geometry *geometry;
|
|
|
|
|
|
|
|
|
|
geometry = (struct rt_device_blk_geometry *)args;
|
|
|
|
|
if (geometry == RT_NULL) return -RT_ERROR;
|
|
|
|
|
|
|
|
|
|
geometry->bytes_per_sector = 512;
|
|
|
|
|
geometry->block_size = SDCardInfo.CardBlockSize;
|
|
|
|
|
geometry->sector_count = SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int rt_hw_sdcard_init(void)
|
|
|
|
|
{
|
|
|
|
|
if (SD_Init() == SD_OK)
|
|
|
|
|
{
|
|
|
|
|
/* register sdcard device */
|
|
|
|
|
sdcard_device.type = RT_Device_Class_Block;
|
|
|
|
|
sdcard_device.init = rt_sdcard_init;
|
|
|
|
|
sdcard_device.open = rt_sdcard_open;
|
|
|
|
|
sdcard_device.close = rt_sdcard_close;
|
|
|
|
|
sdcard_device.read = rt_sdcard_read;
|
|
|
|
|
sdcard_device.write = rt_sdcard_write;
|
|
|
|
|
sdcard_device.control = rt_sdcard_control;
|
|
|
|
|
|
|
|
|
|
/* no private */
|
|
|
|
|
sdcard_device.user_data = &SDCardInfo;
|
|
|
|
|
|
|
|
|
|
rt_device_register(&sdcard_device, "sd0",
|
|
|
|
|
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
|
|
|
|
|
|
|
|
|
|
return RT_EOK;
|
|
|
|
|
}
|
|
|
|
|
rt_kprintf("sdcard init failed\n");
|
|
|
|
|
return RT_ERROR;
|
|
|
|
|
}
|
|
|
|
|
INIT_BOARD_EXPORT(rt_hw_sdcard_init);
|