1346 lines
40 KiB
C
Raw Permalink Normal View History

2021-07-28 13:15:22 +08:00
#include "sdmmc_sdcard.h"
#include "string.h"
#include "usart.h"
//////////////////////////////////////////////////////////////////////////////////
/*************************************************************************/
//SDMMC <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><E1B9A9>ѯģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
//////////////////////////////////////////////////////////////////////////////////
static u8 CardType=STD_CAPACITY_SD_CARD_V1_1; //SD<53><44><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD>Ĭ<EFBFBD><C4AC>Ϊ1.x<><78><EFBFBD><EFBFBD>
static u32 CSD_Tab[4],CID_Tab[4],RCA=0; //SD<53><44>CSD,CID<49>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD>Ե<EFBFBD>ַ(RCA)<29><><EFBFBD><EFBFBD>
SD_CardInfo SDCardInfo; //SD<53><44><EFBFBD><EFBFBD>Ϣ
//SD_ReadDisk/SD_WriteDisk<73><6B><EFBFBD><EFBFBD>ר<EFBFBD><D7A8>buf,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>4<EFBFBD>ֽڶ<D6BD><DAB6><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>,
//<2F><>Ҫ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><C8B7><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>4<EFBFBD>ֽڶ<D6BD><DAB6><EFBFBD><EFBFBD><EFBFBD>.
__align(4) u8 SDMMC_DATA_BUFFER[512];
/*************************************************************************/
//SD<53><44><EFBFBD><EFBFBD>I/O<><4F>Ӧ
//PC8--SDIO_D0,
//PC9--SDIO_D1,
//PC10--SDIO_D2 ,
//PC11--SDIO_D3,
//PC11--SDIO_SCK,
//PD2--SDIO_CMD
//<2F><>ʼ<EFBFBD><CABC>SD<53><44>
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;(0,<2C>޴<EFBFBD><DEB4><EFBFBD>)
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_Init(void)
{
SD_Error errorstatus=SD_OK;
u8 clkdiv=0;
//SDMMC1 IO<49>ڳ<EFBFBD>ʼ<EFBFBD><CABC>
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_SDMMC1_CLK_ENABLE(); //ʹ<><CAB9>SDMMC1ʱ<31><CAB1>
__HAL_RCC_GPIOC_CLK_ENABLE(); //ʹ<><CAB9>GPIOCʱ<43><CAB1>
__HAL_RCC_GPIOD_CLK_ENABLE(); //ʹ<><CAB9>GPIODʱ<44><CAB1>
//SD<53><44><EFBFBD><EFBFBD>I/O<><4F>Ӧ
//PC8--SDIO_D0
//PC9--SDIO_D1
//PC10--SDIO_D2
//PC11--SDIO_D3
//PC11--SDIO_SCK
//PD2--SDIO_CMD
//PC8--D0, PC9--D1,PC10--D2 ,PC11--D3,PC11--SCK,
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_NOPULL; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH; //<2F><><EFBFBD><EFBFBD>
GPIO_Initure.Alternate=GPIO_AF12_SDIO1; //<2F><><EFBFBD><EFBFBD>ΪSDIO
HAL_GPIO_Init(GPIOC,&GPIO_Initure); //<2F><>ʼ<EFBFBD><CABC>
//PD2--CMD
GPIO_Initure.Pin=GPIO_PIN_2;
HAL_GPIO_Init(GPIOD,&GPIO_Initure); //<2F><>ʼ<EFBFBD><CABC>
//SDMMC<4D><43><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪĬ<CEAA><C4AC>ֵ
SDMMC1->POWER=0x00000000;
SDMMC1->CLKCR=0x00000000;
SDMMC1->ARG=0x00000000;
SDMMC1->CMD=0x00000000;
SDMMC1->DTIMER=0x00000000;
SDMMC1->DLEN=0x00000000;
SDMMC1->DCTRL=0x00000000;
SDMMC1->ICR=0X1FE00FFF;
SDMMC1->MASK=0x00000000;
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>
errorstatus=SD_PowerON(); //SD<53><44><EFBFBD>ϵ<EFBFBD>
if(errorstatus==SD_OK)errorstatus=SD_InitializeCards(); //<2F><>ʼ<EFBFBD><CABC>SD<53><44>
if(errorstatus==SD_OK)errorstatus=SD_GetCardInfo(&SDCardInfo); //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>Ϣ
if(errorstatus==SD_OK)errorstatus=SD_SelectDeselect((u32)(SDCardInfo.RCA<<16));//ѡ<><D1A1>SD<53><44>
if(errorstatus==SD_OK)errorstatus=SD_EnableWideBusOperation(1); //4λ<34><CEBB><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MMC<4D><43>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>4λģʽ
if((errorstatus==SD_OK)||(MULTIMEDIA_CARD==CardType))
{
if(SDCardInfo.CardType==STD_CAPACITY_SD_CARD_V1_1||SDCardInfo.CardType==STD_CAPACITY_SD_CARD_V2_0)
{
clkdiv=SDMMC_TRANSFER_CLK_DIV+2; //V1.1/V2.0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>48/4=12Mhz
}
else clkdiv=SDMMC_TRANSFER_CLK_DIV; //SDHC<48><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>48/2=24Mhz
SDMMC_Clock_Set(clkdiv); //<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ƶ<EFBFBD><C6B5>,SDMMCʱ<43>Ӽ<EFBFBD><D3BC>ʽ:SDMMC_CKʱ<4B><CAB1>=SDMMCCLK/[clkdiv+2];<3B><><EFBFBD><EFBFBD>,SDMMCCLK<4C>̶<EFBFBD>Ϊ48Mhz
}
return errorstatus;
}
/*************************************************************************/
//SDMMCʱ<43>ӳ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//clkdiv:ʱ<>ӷ<EFBFBD>Ƶϵ<C6B5><CFB5>
//CKʱ<4B><CAB1>=sdmmc_ker_ck/[2*clkdiv];(sdmmc_ker_ck<63>ӹ̶<D3B9>Ϊ400Mhz)
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
void SDMMC_Clock_Set(u16 clkdiv)
{
u32 tmpreg=SDMMC1->CLKCR;
tmpreg&=0XFFFFFC00;
tmpreg|=clkdiv;
SDMMC1->CLKCR=tmpreg;
}
/*************************************************************************/
//SDMMC<4D><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEBAAF>
//cmdindex:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>Ч
//waitrsp:<3A>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>Ӧ.00/10,<2C><><EFBFBD><EFBFBD>Ӧ;01,<2C><><EFBFBD><EFBFBD>Ӧ;11,<2C><><EFBFBD><EFBFBD>Ӧ
//arg:<3A><><EFBFBD><EFBFBD>
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
void SDMMC_Send_Cmd(u8 cmdindex,u8 waitrsp,u32 arg)
{
u32 tmpreg=0;
SDMMC1->ARG=arg;
tmpreg|=cmdindex&0X3F; //<2F><><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>index
tmpreg|=(u32)waitrsp<<8;//<2F><><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>wait rsp
tmpreg|=0<<10; //<2F>޵ȴ<DEB5>
tmpreg|=1<<12; //<2F><><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>״̬<D7B4><CCAC>ʹ<EFBFBD><CAB9>
SDMMC1->CMD=tmpreg;
}
/*************************************************************************/
//SDMMC<4D><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ú<EFBFBD><C3BA><EFBFBD>
//datatimeout:<3A><>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//datalen:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>,<2C><>25λ<35><CEBB>Ч,<2C><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//blksize:<3A><><EFBFBD><EFBFBD>С<>ʴ<EFBFBD>СΪ:2^blksize<7A>ֽ<EFBFBD>
//dir:<3A><><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><E4B7BD>:0,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;1,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
void SDMMC_Send_Data_Cfg(u32 datatimeout,u32 datalen,u8 blksize,u8 dir)
{
u32 tmpreg;
SDMMC1->DTIMER=datatimeout;
SDMMC1->DLEN=datalen&0X1FFFFFF; //<2F><>25λ<35><CEBB>Ч
tmpreg=SDMMC1->DCTRL;
tmpreg&=0xFFFFFF00; //<2F><><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
tmpreg|=blksize<<4; //<2F><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>С
tmpreg|=0<<2; //<2F><><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>
tmpreg|=(dir&0X01)<<1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tmpreg|=1<<0; //<2F><><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>ʹ<EFBFBD><CAB9>,DPSM״̬<D7B4><CCAC>
SDMMC1->DCTRL=tmpreg;
}
/*************************************************************************/
//<2F><><EFBFBD>ϵ<EFBFBD>
//<2F><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD>SDMMC<4D>ӿ<EFBFBD><D3BF>ϵĿ<CFB5><C4BF>豸,<2C><><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;(0,<2C>޴<EFBFBD><DEB4><EFBFBD>)
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_PowerON(void)
{
u8 i=0;
u32 tempreg=0;
SD_Error errorstatus=SD_OK;
u32 response=0,count=0,validvoltage=0;
u32 SDType=SD_STD_CAPACITY;
//<2F><><EFBFBD><EFBFBD>CLKCR<43>Ĵ<EFBFBD><C4B4><EFBFBD>
tempreg|=0<<12; //PWRSAV=0,<2C><>ʡ<EFBFBD><CAA1>ģʽ
tempreg|=0<<14; //WIDBUS[1:0]=0,1λ<31><CEBB><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD>
tempreg|=0<<16; //NEGEDGE=0,SDMMCCK<43>½<EFBFBD><C2BD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tempreg|=0<<17; //HWFC_EN=0,<2C>ر<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SDMMC1->CLKCR=tempreg;
SDMMC_Clock_Set(SDMMC_INIT_CLK_DIV);//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>Ƶ<EFBFBD><C6B5>(<28><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>,<2C><><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>400Khz)
SDMMC1->POWER=0X03; //<2F>ϵ<EFBFBD>״̬,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
for(i=0;i<74;i++)
{
SDMMC_Send_Cmd(SD_CMD_GO_IDLE_STATE,0,0);//<2F><><EFBFBD><EFBFBD>CMD0<44><30><EFBFBD><EFBFBD>IDLE STAGEģʽ<C4A3><CABD><EFBFBD><EFBFBD>.
errorstatus=CmdError();
if(errorstatus==SD_OK)break;
}
if(errorstatus)return errorstatus;//<2F><><EFBFBD>ش<EFBFBD><D8B4><EFBFBD>״̬
SDMMC_Send_Cmd(SD_SDMMC_SEND_IF_COND,1,SD_CHECK_PATTERN);//<2F><><EFBFBD><EFBFBD>CMD8,<2C><><EFBFBD><EFBFBD>Ӧ,<2C><><EFBFBD><EFBFBD>SD<53><44><EFBFBD>ӿ<EFBFBD><D3BF><EFBFBD><EFBFBD><EFBFBD>.
//arg[11:8]:01,֧<>ֵ<EFBFBD>ѹ<EFBFBD><D1B9>Χ,2.7~3.6V
//arg[7:0]:Ĭ<><C4AC>0XAA
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ7
errorstatus=CmdResp7Error(); //<2F>ȴ<EFBFBD>R7<52><37>Ӧ
if(errorstatus==SD_OK) //R7<52><37>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
{
CardType=STD_CAPACITY_SD_CARD_V2_0; //SD 2.0<EFBFBD><EFBFBD>
SDType=SD_HIGH_CAPACITY; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
SDMMC_Send_Cmd(SD_CMD_APP_CMD,1,0); //<2F><><EFBFBD><EFBFBD>CMD55,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_APP_CMD); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus==SD_OK)//SD2.0/SD 1.1,<2C><><EFBFBD><EFBFBD>ΪMMC<4D><43>
{
//SD<53><44>,<2C><><EFBFBD><EFBFBD>ACMD41 SD_APP_OP_COND,<2C><><EFBFBD><EFBFBD>Ϊ:0x80100000
while((!validvoltage)&&(count<SD_MAX_VOLT_TRIAL))
{
SDMMC_Send_Cmd(SD_CMD_APP_CMD,1,0); //<2F><><EFBFBD><EFBFBD>CMD55,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_APP_CMD); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
SDMMC_Send_Cmd(SD_CMD_SD_APP_OP_COND,1,SD_VOLTAGE_WINDOW_SD|SDType);//<2F><><EFBFBD><EFBFBD>ACMD41,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp3Error(); //<2F>ȴ<EFBFBD>R3<52><33>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
response=SDMMC1->RESP1;; //<2F>õ<EFBFBD><C3B5><EFBFBD>Ӧ
validvoltage=(((response>>31)==1)?1:0); //<2F>ж<EFBFBD>SD<53><44><EFBFBD>ϵ<EFBFBD><CFB5>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
count++;
}
if(count>=SD_MAX_VOLT_TRIAL)
{
errorstatus=SD_INVALID_VOLTRANGE;
return errorstatus;
}
if(response&=SD_HIGH_CAPACITY)
{
CardType=HIGH_CAPACITY_SD_CARD;
}
}else//MMC<4D><43>
{
//MMC<4D><43>,<2C><><EFBFBD><EFBFBD>CMD1 SDMMC_SEND_OP_COND,<2C><><EFBFBD><EFBFBD>Ϊ:0x80FF8000
while((!validvoltage)&&(count<SD_MAX_VOLT_TRIAL))
{
SDMMC_Send_Cmd(SD_CMD_SEND_OP_COND,1,SD_VOLTAGE_WINDOW_MMC);//<2F><><EFBFBD><EFBFBD>CMD1,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp3Error(); //<2F>ȴ<EFBFBD>R3<52><33>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
response=SDMMC1->RESP1;; //<2F>õ<EFBFBD><C3B5><EFBFBD>Ӧ
validvoltage=(((response>>31)==1)?1:0);
count++;
}
if(count>=SD_MAX_VOLT_TRIAL)
{
errorstatus=SD_INVALID_VOLTRANGE;
return errorstatus;
}
CardType=MULTIMEDIA_CARD;
}
return(errorstatus);
}
/*************************************************************************/
//SD<53><44> Power OFF
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;(0,<2C>޴<EFBFBD><DEB4><EFBFBD>)
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_PowerOFF(void)
{
SDMMC1->POWER&=~(3<<0);//SDMMC<4D><43>Դ<EFBFBD>ر<EFBFBD><><CAB1>ֹͣ
return SD_OK;
}
/*************************************************************************/
//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>еĿ<D0B5>,<2C><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_InitializeCards(void)
{
SD_Error errorstatus=SD_OK;
u16 rca = 0x01;
if((SDMMC1->POWER&0X03)==0)return SD_REQUEST_NOT_APPLICABLE;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ״̬,ȷ<><C8B7>Ϊ<EFBFBD>ϵ<EFBFBD>״̬
if(SECURE_DIGITAL_IO_CARD!=CardType) //<2F><>SECURE_DIGITAL_IO_CARD
{
SDMMC_Send_Cmd(SD_CMD_ALL_SEND_CID,3,0); //<2F><><EFBFBD><EFBFBD>CMD2,ȡ<><C8A1>CID,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp2Error(); //<2F>ȴ<EFBFBD>R2<52><32>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
CID_Tab[0]=SDMMC1->RESP1;
CID_Tab[1]=SDMMC1->RESP2;
CID_Tab[2]=SDMMC1->RESP3;
CID_Tab[3]=SDMMC1->RESP4;
}
if((STD_CAPACITY_SD_CARD_V1_1==CardType)||(STD_CAPACITY_SD_CARD_V2_0==CardType)||(SECURE_DIGITAL_IO_COMBO_CARD==CardType)||(HIGH_CAPACITY_SD_CARD==CardType))//<2F>жϿ<D0B6><CFBF><EFBFBD><EFBFBD><EFBFBD>
{
SDMMC_Send_Cmd(SD_CMD_SET_REL_ADDR,1,0); //<2F><><EFBFBD><EFBFBD>CMD3,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp6Error(SD_CMD_SET_REL_ADDR,&rca);//<2F>ȴ<EFBFBD>R6<52><36>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
}
if (MULTIMEDIA_CARD==CardType)
{
SDMMC_Send_Cmd(SD_CMD_SET_REL_ADDR,1,(u32)(rca<<16));//<2F><><EFBFBD><EFBFBD>CMD3,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp2Error(); //<2F>ȴ<EFBFBD>R2<52><32>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
}
if (SECURE_DIGITAL_IO_CARD!=CardType) //<2F><>SECURE_DIGITAL_IO_CARD
{
RCA = rca;
SDMMC_Send_Cmd(SD_CMD_SEND_CSD,3,(u32)(rca<<16));//<2F><><EFBFBD><EFBFBD>CMD9+<2B><>RCA,ȡ<><C8A1>CSD,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp2Error(); //<2F>ȴ<EFBFBD>R2<52><32>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
CSD_Tab[0]=SDMMC1->RESP1;
CSD_Tab[1]=SDMMC1->RESP2;
CSD_Tab[2]=SDMMC1->RESP3;
CSD_Tab[3]=SDMMC1->RESP4;
}
return SD_OK;//<2F><><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ɹ<EFBFBD>
}
/*************************************************************************/
//<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>Ϣ
//cardinfo:<3A><><EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD><E6B4A2>
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo)
{
SD_Error errorstatus=SD_OK;
u8 tmp=0;
cardinfo->CardType=(u8)CardType; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cardinfo->RCA=(u16)RCA; //<2F><>RCAֵ
tmp=(u8)((CSD_Tab[0]&0xFF000000)>>24);
cardinfo->SD_csd.CSDStruct=(tmp&0xC0)>>6; //CSD<53>
cardinfo->SD_csd.SysSpecVersion=(tmp&0x3C)>>2; //2.0Э<EFBFBD>黹û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD><EFBFBD><><CEAA><EFBFBD><EFBFBD>),Ӧ<><D3A6><EFBFBD>Ǻ<EFBFBD><C7BA><EFBFBD>Э<EFBFBD><EFBFBD><E9B6A8><EFBFBD><EFBFBD>
cardinfo->SD_csd.Reserved1=tmp&0x03; //2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
tmp=(u8)((CSD_Tab[0]&0x00FF0000)>>16); //<2F><>1<EFBFBD><31><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.TAAC=tmp; //<2F><><EFBFBD>ݶ<EFBFBD>ʱ<EFBFBD><CAB1>1
tmp=(u8)((CSD_Tab[0]&0x0000FF00)>>8); //<2F><>2<EFBFBD><32><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.NSAC=tmp; //<2F><><EFBFBD>ݶ<EFBFBD>ʱ<EFBFBD><CAB1>2
tmp=(u8)(CSD_Tab[0]&0x000000FF); //<2F><>3<EFBFBD><33><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.MaxBusClkFrec=tmp; //<2F><><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>
tmp=(u8)((CSD_Tab[1]&0xFF000000)>>24); //<2F><>4<EFBFBD><34><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.CardComdClasses=tmp<<4; //<2F><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
tmp=(u8)((CSD_Tab[1]&0x00FF0000)>>16); //<2F><>5<EFBFBD><35><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.CardComdClasses|=(tmp&0xF0)>>4;//<2F><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
cardinfo->SD_csd.RdBlockLen=tmp&0x0F; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
tmp=(u8)((CSD_Tab[1]&0x0000FF00)>>8); //<2F><>6<EFBFBD><36><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.PartBlockRead=(tmp&0x80)>>7; //<2F><><EFBFBD><EFBFBD><EFBFBD>ֿ<EFBFBD><D6BF><EFBFBD>
cardinfo->SD_csd.WrBlockMisalign=(tmp&0x40)>>6; //д<><D0B4><EFBFBD><EFBFBD>λ
cardinfo->SD_csd.RdBlockMisalign=(tmp&0x20)>>5; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ
cardinfo->SD_csd.DSRImpl=(tmp&0x10)>>4;
cardinfo->SD_csd.Reserved2=0; //<2F><><EFBFBD><EFBFBD>
if((CardType==STD_CAPACITY_SD_CARD_V1_1)||(CardType==STD_CAPACITY_SD_CARD_V2_0)||(MULTIMEDIA_CARD==CardType))//<2F><>׼1.1/2.0<EFBFBD><EFBFBD>/MMC<4D><43>
{
cardinfo->SD_csd.DeviceSize=(tmp&0x03)<<10; //C_SIZE(12λ)
tmp=(u8)(CSD_Tab[1]&0x000000FF); //<2F><>7<EFBFBD><37><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.DeviceSize|=(tmp)<<2;
tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24); //<2F><>8<EFBFBD><38><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.DeviceSize|=(tmp&0xC0)>>6;
cardinfo->SD_csd.MaxRdCurrentVDDMin=(tmp&0x38)>>3;
cardinfo->SD_csd.MaxRdCurrentVDDMax=(tmp&0x07);
tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16); //<2F><>9<EFBFBD><39><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.MaxWrCurrentVDDMin=(tmp&0xE0)>>5;
cardinfo->SD_csd.MaxWrCurrentVDDMax=(tmp&0x1C)>>2;
cardinfo->SD_csd.DeviceSizeMul=(tmp&0x03)<<1;//C_SIZE_MULT
tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8); //<2F><>10<31><30><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.DeviceSizeMul|=(tmp&0x80)>>7;
cardinfo->CardCapacity=(cardinfo->SD_csd.DeviceSize+1);//<2F><><EFBFBD><EFBFBD><E3BFA8><EFBFBD><EFBFBD>
cardinfo->CardCapacity*=(1<<(cardinfo->SD_csd.DeviceSizeMul+2));
cardinfo->CardBlockSize=1<<(cardinfo->SD_csd.RdBlockLen);//<2F><><EFBFBD><EFBFBD>С
cardinfo->CardCapacity*=cardinfo->CardBlockSize;
}else if(CardType==HIGH_CAPACITY_SD_CARD) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
tmp=(u8)(CSD_Tab[1]&0x000000FF); //<2F><>7<EFBFBD><37><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.DeviceSize=(tmp&0x3F)<<16;//C_SIZE
tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24); //<2F><>8<EFBFBD><38><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.DeviceSize|=(tmp<<8);
tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16); //<2F><>9<EFBFBD><39><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.DeviceSize|=(tmp);
tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8); //<2F><>10<31><30><EFBFBD>ֽ<EFBFBD>
cardinfo->CardCapacity=(long long)(cardinfo->SD_csd.DeviceSize+1)*512*1024;//<2F><><EFBFBD><EFBFBD><E3BFA8><EFBFBD><EFBFBD>
cardinfo->CardBlockSize=512; //<2F><><EFBFBD><EFBFBD>С<EFBFBD>̶<EFBFBD>Ϊ512<31>ֽ<EFBFBD>
}
cardinfo->SD_csd.EraseGrSize=(tmp&0x40)>>6;
cardinfo->SD_csd.EraseGrMul=(tmp&0x3F)<<1;
tmp=(u8)(CSD_Tab[2]&0x000000FF); //<2F><>11<31><31><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.EraseGrMul|=(tmp&0x80)>>7;
cardinfo->SD_csd.WrProtectGrSize=(tmp&0x7F);
tmp=(u8)((CSD_Tab[3]&0xFF000000)>>24); //<2F><>12<31><32><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.WrProtectGrEnable=(tmp&0x80)>>7;
cardinfo->SD_csd.ManDeflECC=(tmp&0x60)>>5;
cardinfo->SD_csd.WrSpeedFact=(tmp&0x1C)>>2;
cardinfo->SD_csd.MaxWrBlockLen=(tmp&0x03)<<2;
tmp=(u8)((CSD_Tab[3]&0x00FF0000)>>16); //<2F><>13<31><33><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.MaxWrBlockLen|=(tmp&0xC0)>>6;
cardinfo->SD_csd.WriteBlockPaPartial=(tmp&0x20)>>5;
cardinfo->SD_csd.Reserved3=0;
cardinfo->SD_csd.ContentProtectAppli=(tmp&0x01);
tmp=(u8)((CSD_Tab[3]&0x0000FF00)>>8); //<2F><>14<31><34><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.FileFormatGrouop=(tmp&0x80)>>7;
cardinfo->SD_csd.CopyFlag=(tmp&0x40)>>6;
cardinfo->SD_csd.PermWrProtect=(tmp&0x20)>>5;
cardinfo->SD_csd.TempWrProtect=(tmp&0x10)>>4;
cardinfo->SD_csd.FileFormat=(tmp&0x0C)>>2;
cardinfo->SD_csd.ECC=(tmp&0x03);
tmp=(u8)(CSD_Tab[3]&0x000000FF); //<2F><>15<31><35><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_csd.CSD_CRC=(tmp&0xFE)>>1;
cardinfo->SD_csd.Reserved4=1;
tmp=(u8)((CID_Tab[0]&0xFF000000)>>24); //<2F><>0<EFBFBD><30><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ManufacturerID=tmp;
tmp=(u8)((CID_Tab[0]&0x00FF0000)>>16); //<2F><>1<EFBFBD><31><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.OEM_AppliID=tmp<<8;
tmp=(u8)((CID_Tab[0]&0x000000FF00)>>8); //<2F><>2<EFBFBD><32><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.OEM_AppliID|=tmp;
tmp=(u8)(CID_Tab[0]&0x000000FF); //<2F><>3<EFBFBD><33><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdName1=tmp<<24;
tmp=(u8)((CID_Tab[1]&0xFF000000)>>24); //<2F><>4<EFBFBD><34><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdName1|=tmp<<16;
tmp=(u8)((CID_Tab[1]&0x00FF0000)>>16); //<2F><>5<EFBFBD><35><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdName1|=tmp<<8;
tmp=(u8)((CID_Tab[1]&0x0000FF00)>>8); //<2F><>6<EFBFBD><36><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdName1|=tmp;
tmp=(u8)(CID_Tab[1]&0x000000FF); //<2F><>7<EFBFBD><37><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdName2=tmp;
tmp=(u8)((CID_Tab[2]&0xFF000000)>>24); //<2F><>8<EFBFBD><38><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdRev=tmp;
tmp=(u8)((CID_Tab[2]&0x00FF0000)>>16); //<2F><>9<EFBFBD><39><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdSN=tmp<<24;
tmp=(u8)((CID_Tab[2]&0x0000FF00)>>8); //<2F><>10<31><30><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdSN|=tmp<<16;
tmp=(u8)(CID_Tab[2]&0x000000FF); //<2F><>11<31><31><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdSN|=tmp<<8;
tmp=(u8)((CID_Tab[3]&0xFF000000)>>24); //<2F><>12<31><32><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ProdSN|=tmp;
tmp=(u8)((CID_Tab[3]&0x00FF0000)>>16); //<2F><>13<31><33><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.Reserved1|=(tmp&0xF0)>>4;
cardinfo->SD_cid.ManufactDate=(tmp&0x0F)<<8;
tmp=(u8)((CID_Tab[3]&0x0000FF00)>>8); //<2F><>14<31><34><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.ManufactDate|=tmp;
tmp=(u8)(CID_Tab[3]&0x000000FF); //<2F><>15<31><35><EFBFBD>ֽ<EFBFBD>
cardinfo->SD_cid.CID_CRC=(tmp&0xFE)>>1;
cardinfo->SD_cid.Reserved2=1;
return errorstatus;
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>SDMMC<4D><43><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>(MMC<4D><43><EFBFBD><EFBFBD>֧<EFBFBD><D6A7>4bitģʽ)
//wmode:λ<><CEBB>ģʽ.0,1λ<31><CEBB><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD>;1,4λ<34><CEBB><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD>;2,8λ<38><CEBB><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ֵ:SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_EnableWideBusOperation(u32 wmode)
{
SD_Error errorstatus=SD_OK;
u16 clkcr=0;
if(MULTIMEDIA_CARD==CardType)return SD_UNSUPPORTED_FEATURE;//MMC<4D><43><EFBFBD><EFBFBD>֧<EFBFBD><D6A7>
else if((STD_CAPACITY_SD_CARD_V1_1==CardType)||(STD_CAPACITY_SD_CARD_V2_0==CardType)||(HIGH_CAPACITY_SD_CARD==CardType))
{
if(wmode>=2)return SD_UNSUPPORTED_FEATURE;//<2F><>֧<EFBFBD><D6A7>8λģʽ
else
{
errorstatus=SDEnWideBus(wmode);
if(SD_OK==errorstatus)
{
clkcr=SDMMC1->CLKCR; //<2F><>ȡCLKCR<43><52>ֵ
clkcr&=~(3<<14); //<2F><><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
clkcr|=(u32)wmode<<14; //1λ/4λ<34><CEBB><EFBFBD>߿<EFBFBD><DFBF><EFBFBD>
clkcr|=0<<17; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SDMMC1->CLKCR=clkcr; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CLKCRֵ
}
}
}
return errorstatus;
}
/*************************************************************************/
//ѡ<><D1A1>
//<2F><><EFBFBD><EFBFBD>CMD7,ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD>ַ(rca)Ϊaddr<64>Ŀ<EFBFBD><><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<2E><><EFBFBD><EFBFBD>Ϊ0,<2C>򶼲<EFBFBD>ѡ<EFBFBD><D1A1>.
//addr:<3A><><EFBFBD><EFBFBD>RCA<43><41>ַ
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_SelectDeselect(u32 addr)
{
SDMMC_Send_Cmd(SD_CMD_SEL_DESEL_CARD,1,addr); //<2F><><EFBFBD><EFBFBD>CMD7,ѡ<><D1A1><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ӧ
return CmdResp1Error(SD_CMD_SEL_DESEL_CARD);
}
/*************************************************************************/
//SD<53><44><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//buf:<3A><><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
//addr:<3A><>ȡ<EFBFBD><C8A1>ַ
//blksize:<3A><><EFBFBD><EFBFBD>С
//nblks:Ҫ<><D2AA>ȡ<EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>,1,<2C><>ʾ<EFBFBD><CABE>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_ReadBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks)
{
SD_Error errorstatus=SD_OK;
u32 count=0;
u32 timeout=SDMMC_DATATIMEOUT;
u32 *tempbuff=(u32*)buf; //ת<><D7AA>Ϊu32ָ<32><D6B8>
SDMMC1->DCTRL=0x0; //<2F><><EFBFBD>ݿ<EFBFBD><DDBF>ƼĴ<C6BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><>DMA)
if(CardType==HIGH_CAPACITY_SD_CARD)//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
blksize=512;
addr>>=9;
}
SDMMC_Send_Cmd(SD_CMD_SET_BLOCKLEN,1,blksize); //<2F><><EFBFBD><EFBFBD>CMD16+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>Ϊblksize,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)
{
printf("SDMMC_Send_Cmd=%d\r\n",errorstatus);
return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
}
SDMMC_Send_Data_Cfg(SD_DATATIMEOUT,nblks*blksize,9,1); //nblks*blksize,<2C><><EFBFBD><EFBFBD>С<EFBFBD><D0A1>Ϊ512,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SDMMC1->CMD|=1<<6; //CMDTRANS=1,<2C><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(nblks>1) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
SDMMC_Send_Cmd(SD_CMD_READ_MULT_BLOCK,1,addr); //<2F><><EFBFBD><EFBFBD>CMD18+<2B><>addr<64><72>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_READ_MULT_BLOCK); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)
{
printf("SD_CMD_READ_MULT_BLOCK Error\r\n");
return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
}
}else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
SDMMC_Send_Cmd(SD_CMD_READ_SINGLE_BLOCK,1,addr); //<2F><><EFBFBD><EFBFBD>CMD17+<2B><>addr<64><72>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);//<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
}
INTX_DISABLE();//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD>ж<EFBFBD>(POLLINGģʽ,<2C>Ͻ<EFBFBD><CFBD>жϴ<D0B6><CFB4><EFBFBD>SDMMC<4D><43>д<EFBFBD><D0B4><EFBFBD><EFBFBD>!!!)
while(!(SDMMC1->STA&((1<<5)|(1<<1)|(1<<3)|(1<<8))))//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/CRC/<2F><>ʱ/<2F><><EFBFBD><EFBFBD>(<28><>־)
{
if(SDMMC1->STA&(1<<15)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>ʾ<EFBFBD><CABE><EFBFBD>ٴ<EFBFBD><D9B4><EFBFBD>8<EFBFBD><38><EFBFBD><EFBFBD>
{
for(count=0;count<8;count++) //ѭ<><D1AD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
{
*(tempbuff+count)=SDMMC1->FIFO;
}
tempbuff+=8;
timeout=0X7FFFFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
}else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
{
if(timeout==0)return SD_DATA_TIMEOUT;
timeout--;
}
}
SDMMC1->CMD&=~(1<<6); //CMDTRANS=0,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>
INTX_ENABLE(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
if(SDMMC1->STA&(1<<3)) //<2F><><EFBFBD>ݳ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<3; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
return SD_DATA_TIMEOUT;
}else if(SDMMC1->STA&(1<<1))//<2F><><EFBFBD>ݿ<EFBFBD>CRC<52><43><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
if(nblks>1) //<2F><><EFBFBD>Կ<EFBFBD><D4BF>ܳ<EFBFBD><DCB3>ֵ<EFBFBD>CRC<52><43><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><C7B6><EFBFBD><EFBFBD><EFBFBD>ȡ,<2C><><EFBFBD><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!
{
SDMMC_Send_Cmd(SD_CMD_STOP_TRANSMISSION,1,0); //<2F><><EFBFBD><EFBFBD>CMD12+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
errorstatus=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//<2F>ȴ<EFBFBD>R1<52><31>Ӧ
}
return SD_DATA_CRC_FAIL;
}else if(SDMMC1->STA&(1<<5))//<2F><><EFBFBD><EFBFBD>fifo<66><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<5; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
return SD_RX_OVERRUN;
}
if((SDMMC1->STA&(1<<8))&&(nblks>1))//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ս<EFBFBD><D5BD><EFBFBD>,<2C><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>ָ<EFBFBD><D6B8>
{
if((STD_CAPACITY_SD_CARD_V1_1==CardType)||(STD_CAPACITY_SD_CARD_V2_0==CardType)||(HIGH_CAPACITY_SD_CARD==CardType))
{
SDMMC_Send_Cmd(SD_CMD_STOP_TRANSMISSION,1,0); //<2F><><EFBFBD><EFBFBD>CMD12+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
errorstatus=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus;
}
}
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
return errorstatus;
}
/*************************************************************************/
//SD<53><44>д<EFBFBD><D0B4><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//buf:<3A><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
//addr:д<><D0B4>ַ
//blksize:<3A><><EFBFBD><EFBFBD>С
//nblks:Ҫ<><D2AA>ȡ<EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>,1,<2C><>ʾ<EFBFBD><CABE>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_WriteBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks)
{
SD_Error errorstatus = SD_OK;
u8 cardstate=0;
u32 timeout=0,bytestransferred=0;
u32 cardstatus=0,count=0,restwords=0;
u32 tlen=nblks*blksize; //<2F>ܳ<EFBFBD><DCB3><EFBFBD>(<28>ֽ<EFBFBD>)
u32*tempbuff=(u32*)buf;
if(buf==NULL)return SD_INVALID_PARAMETER; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SDMMC1->DCTRL=0x0; //<2F><><EFBFBD>ݿ<EFBFBD><DDBF>ƼĴ<C6BC><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><>DMA)
if(CardType==HIGH_CAPACITY_SD_CARD) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
blksize=512;
addr>>=9;
}
SDMMC_Send_Cmd(SD_CMD_SET_BLOCKLEN,1,blksize); //<2F><><EFBFBD><EFBFBD>CMD16+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>Ϊblksize,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus; //<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
if(nblks>1) //<2F><><EFBFBD><EFBFBD>д
{
if(nblks*blksize>SD_MAX_DATA_LENGTH)return SD_INVALID_PARAMETER;
if((STD_CAPACITY_SD_CARD_V1_1==CardType)||(STD_CAPACITY_SD_CARD_V2_0==CardType)||(HIGH_CAPACITY_SD_CARD==CardType))
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SDMMC_Send_Cmd(SD_CMD_APP_CMD,1,(u32)RCA<<16); //<2F><><EFBFBD><EFBFBD>ACMD55,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_APP_CMD); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus;
SDMMC_Send_Cmd(SD_CMD_SET_BLOCK_COUNT,1,nblks); //<2F><><EFBFBD><EFBFBD>CMD23,<2C><><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_SET_BLOCK_COUNT);//<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus;
}
SDMMC_Send_Cmd(SD_CMD_WRITE_MULT_BLOCK,1,addr); //<2F><><EFBFBD><EFBFBD>CMD25,<2C><><EFBFBD><EFBFBD>дָ<D0B4><D6B8>,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_WRITE_MULT_BLOCK); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
}else //<2F><><EFBFBD><EFBFBD>д
{
SDMMC_Send_Cmd(SD_CMD_SEND_STATUS,1,(u32)RCA<<16); //<2F><><EFBFBD><EFBFBD>CMD13,<2C><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD>״̬,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus;
cardstatus=SDMMC1->RESP1;
timeout=SD_DATATIMEOUT;
while(((cardstatus&0x00000100)==0)&&(timeout>0)) //<2F><><EFBFBD><EFBFBD>READY_FOR_DATAλ<41>Ƿ<EFBFBD><C7B7><EFBFBD>λ
{
timeout--;
SDMMC_Send_Cmd(SD_CMD_SEND_STATUS,1,(u32)RCA<<16);//<2F><><EFBFBD><EFBFBD>CMD13,<2C><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD>״̬,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS); //<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus;
cardstatus=SDMMC1->RESP1;
}
if(timeout==0)return SD_ERROR;
SDMMC_Send_Cmd(SD_CMD_WRITE_SINGLE_BLOCK,1,addr); //<2F><><EFBFBD><EFBFBD>CMD24,д<><D0B4><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_WRITE_SINGLE_BLOCK);//<2F>ȴ<EFBFBD>R1<52><31>Ӧ
}
if(errorstatus!=SD_OK)return errorstatus;
SDMMC_Send_Data_Cfg(SD_DATATIMEOUT,nblks*blksize,9,0); //blksize,<2C><><EFBFBD><EFBFBD>С<EFBFBD><D0A1>Ϊ512<31>ֽ<EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SDMMC1->CMD|=1<<6; //CMDTRANS=1,<2C><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
timeout=SDMMC_DATATIMEOUT;
INTX_DISABLE();//<2F>ر<EFBFBD><D8B1><EFBFBD><EFBFBD>ж<EFBFBD>(POLLINGģʽ,<2C>Ͻ<EFBFBD><CFBD>жϴ<D0B6><CFB4><EFBFBD>SDMMC<4D><43>д<EFBFBD><D0B4><EFBFBD><EFBFBD>!!!)
while(!(SDMMC1->STA&((1<<4)|(1<<1)|(1<<8)|(1<<3))))//<2F><><EFBFBD><EFBFBD>/CRC/<2F><><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD>/<2F><>ʱ
{
if(SDMMC1->STA&(1<<14)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><>ʾ<EFBFBD><CABE><EFBFBD>ٴ<EFBFBD><D9B4><EFBFBD>8<EFBFBD><38>(32<33>ֽ<EFBFBD>)
{
if((tlen-bytestransferred)<SD_HALFFIFOBYTES)//<2F><><EFBFBD><EFBFBD>32<33>ֽ<EFBFBD><D6BD><EFBFBD>
{
restwords=((tlen-bytestransferred)%4==0)?((tlen-bytestransferred)/4):((tlen-bytestransferred)/4+1);
for(count=0;count<restwords;count++,tempbuff++,bytestransferred+=4)
{
SDMMC1->FIFO=*tempbuff;
}
}else //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD>Է<EFBFBD><D4B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8<EFBFBD><38>(32<33>ֽ<EFBFBD>)<29><><EFBFBD><EFBFBD>
{
for(count=0;count<SD_HALFFIFO;count++)
{
SDMMC1->FIFO=*(tempbuff+count);
}
tempbuff+=SD_HALFFIFO;
bytestransferred+=SD_HALFFIFOBYTES;
}
timeout=0X3FFFFFFF; //д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
}else
{
if(timeout==0)return SD_DATA_TIMEOUT;
timeout--;
}
}
SDMMC1->CMD&=~(1<<6); //CMDTRANS=0,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>
INTX_ENABLE(); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
if(SDMMC1->STA&(1<<3)) //<2F><><EFBFBD>ݳ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<3; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
return SD_DATA_TIMEOUT;
}else if(SDMMC1->STA&(1<<1)) //<2F><><EFBFBD>ݿ<EFBFBD>CRC<52><43><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
if(nblks>1) //<2F><><EFBFBD>Կ<EFBFBD><D4BF>ܳ<EFBFBD><DCB3>ֵ<EFBFBD>CRC<52><43><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD>Ƕ<EFBFBD><C7B6><EFBFBD><EFBFBD><EFBFBD>ȡ,<2C><><EFBFBD><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!
{
SDMMC_Send_Cmd(SD_CMD_STOP_TRANSMISSION,1,0); //<2F><><EFBFBD><EFBFBD>CMD12+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
errorstatus=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//<2F>ȴ<EFBFBD>R1<52><31>Ӧ
}
return SD_DATA_CRC_FAIL;
}else if(SDMMC1->STA&(1<<4)) //<2F><><EFBFBD><EFBFBD>fifo<66><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<4; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
return SD_TX_UNDERRUN;
}
if((SDMMC1->STA&(1<<8))&&(nblks>1))//<2F><><EFBFBD><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>,<2C><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>ָ<EFBFBD><D6B8>
{
if((STD_CAPACITY_SD_CARD_V1_1==CardType)||(STD_CAPACITY_SD_CARD_V2_0==CardType)||(HIGH_CAPACITY_SD_CARD==CardType))
{
SDMMC_Send_Cmd(SD_CMD_STOP_TRANSMISSION,1,0); //<2F><><EFBFBD><EFBFBD>CMD12+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
errorstatus=CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//<2F>ȴ<EFBFBD>R1<52><31>Ӧ
if(errorstatus!=SD_OK)return errorstatus;
}
}
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
errorstatus=IsCardProgramming(&cardstate);
while((errorstatus==SD_OK)&&((cardstate==SD_CARD_PROGRAMMING)||(cardstate==SD_CARD_RECEIVING)))
{
errorstatus=IsCardProgramming(&cardstate);
}
return errorstatus;
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>CMD0<44><30>ִ<EFBFBD><D6B4>״̬
//<2F><><EFBFBD><EFBFBD>ֵ:sd<73><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error CmdError(void)
{
SD_Error errorstatus = SD_OK;
u32 timeout=SDMMC_CMD0TIMEOUT;
while(timeout--)
{
if(SDMMC1->STA&(1<<7))break;//<2F><><EFBFBD><EFBFBD><EFBFBD>ѷ<EFBFBD><D1B7><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ)
}
if(timeout==0)return SD_CMD_RSP_TIMEOUT;
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return errorstatus;
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>R7<52><37>Ӧ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>״̬
//<2F><><EFBFBD><EFBFBD>ֵ:sd<73><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error CmdResp7Error(void)
{
SD_Error errorstatus=SD_OK;
u32 status;
u32 timeout=SDMMC_CMD0TIMEOUT;
while(timeout--)
{
status=SDMMC1->STA;
if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC<52><43><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ/<2F>Ѿ<EFBFBD><D1BE>յ<EFBFBD><D5B5><EFBFBD>Ӧ(CRCУ<43><D0A3><EFBFBD>ɹ<EFBFBD>)
}
if((timeout==0)||(status&(1<<2))) //<2F><>Ӧ<EFBFBD><D3A6>ʱ
{
errorstatus=SD_CMD_RSP_TIMEOUT; //<2F><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2.0<EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD>,<2C><><EFBFBD>߲<EFBFBD>֧<EFBFBD><D6A7><EFBFBD><EFBFBD>ĵ<EFBFBD>ѹ<EFBFBD><D1B9>Χ
SDMMC1->ICR|=1<<2; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ<EFBFBD><CAB1>־
return errorstatus;
}
if(status&1<<6) //<2F>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD>Ӧ
{
errorstatus=SD_OK;
SDMMC1->ICR|=1<<6; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>־
}
return errorstatus;
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>R1<52><31>Ӧ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>״̬
//cmd:<3A><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD>ֵ:sd<73><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error CmdResp1Error(u8 cmd)
{
u32 status;
while(1)
{
status=SDMMC1->STA;
if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC<52><43><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ/<2F>Ѿ<EFBFBD><D1BE>յ<EFBFBD><D5B5><EFBFBD>Ӧ(CRCУ<43><D0A3><EFBFBD>ɹ<EFBFBD>)
}
if(status&(1<<2)) //<2F><>Ӧ<EFBFBD><D3A6>ʱ
{
SDMMC1->ICR=1<<2; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ<EFBFBD><CAB1>־
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return SD_CMD_RSP_TIMEOUT;
}
if(status&(1<<0)) //CRC<52><43><EFBFBD><EFBFBD>
{
SDMMC1->ICR=1<<0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
return SD_CMD_CRC_FAIL;
}
if(SDMMC1->RESPCMD!=cmd)return SD_ILLEGAL_CMD;//<2F><><EFBFBD>ƥ<EEB2BB><C6A5>
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return (SD_Error)(SDMMC1->RESP1&SD_OCR_ERRORBITS);//<2F><><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD>Ӧ
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>R3<52><33>Ӧ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>״̬
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error CmdResp3Error(void)
{
u32 status;
while(1)
{
status=SDMMC1->STA;
if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC<52><43><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ/<2F>Ѿ<EFBFBD><D1BE>յ<EFBFBD><D5B5><EFBFBD>Ӧ(CRCУ<43><D0A3><EFBFBD>ɹ<EFBFBD>)
}
if(status&(1<<2)) //<2F><>Ӧ<EFBFBD><D3A6>ʱ
{
SDMMC1->ICR|=1<<2; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ<EFBFBD><CAB1>־
return SD_CMD_RSP_TIMEOUT;
}
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return SD_OK;
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>R2<52><32>Ӧ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>״̬
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error CmdResp2Error(void)
{
SD_Error errorstatus=SD_OK;
u32 status;
u32 timeout=SDMMC_CMD0TIMEOUT;
while(timeout--)
{
status=SDMMC1->STA;
if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC<52><43><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ/<2F>Ѿ<EFBFBD><D1BE>յ<EFBFBD><D5B5><EFBFBD>Ӧ(CRCУ<43><D0A3><EFBFBD>ɹ<EFBFBD>)
}
if((timeout==0)||(status&(1<<2))) //<2F><>Ӧ<EFBFBD><D3A6>ʱ
{
errorstatus=SD_CMD_RSP_TIMEOUT;
SDMMC1->ICR|=1<<2; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ<EFBFBD><CAB1>־
return errorstatus;
}
if(status&1<<0) //CRC<52><43><EFBFBD><EFBFBD>
{
errorstatus=SD_CMD_CRC_FAIL;
SDMMC1->ICR|=1<<0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>־
}
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return errorstatus;
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>R6<52><36>Ӧ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>״̬
//cmd:֮ǰ<D6AE><C7B0><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
//prca:<3A><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>RCA<43><41>ַ
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error CmdResp6Error(u8 cmd,u16*prca)
{
SD_Error errorstatus=SD_OK;
u32 status;
u32 rspr1;
while(1)
{
status=SDMMC1->STA;
if(status&((1<<0)|(1<<2)|(1<<6)))break;//CRC<52><43><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ/<2F>Ѿ<EFBFBD><D1BE>յ<EFBFBD><D5B5><EFBFBD>Ӧ(CRCУ<43><D0A3><EFBFBD>ɹ<EFBFBD>)
}
if(status&(1<<2)) //<2F><>Ӧ<EFBFBD><D3A6>ʱ
{
SDMMC1->ICR|=1<<2; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʱ<EFBFBD><CAB1>־
return SD_CMD_RSP_TIMEOUT;
}
if(status&1<<0) //CRC<52><43><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>־
return SD_CMD_CRC_FAIL;
}
if(SDMMC1->RESPCMD!=cmd) //<2F>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>Ӧcmd<6D><64><EFBFBD><EFBFBD>
{
return SD_ILLEGAL_CMD;
}
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
rspr1=SDMMC1->RESP1; //<2F>õ<EFBFBD><C3B5><EFBFBD>Ӧ
if(SD_ALLZERO==(rspr1&(SD_R6_GENERAL_UNKNOWN_ERROR|SD_R6_ILLEGAL_CMD|SD_R6_COM_CRC_FAILED)))
{
*prca=(u16)(rspr1>>16); //<2F><><EFBFBD><EFBFBD>16λ<36>õ<EFBFBD>,rca
return errorstatus;
}
if(rspr1&SD_R6_GENERAL_UNKNOWN_ERROR)return SD_GENERAL_UNKNOWN_ERROR;
if(rspr1&SD_R6_ILLEGAL_CMD)return SD_ILLEGAL_CMD;
if(rspr1&SD_R6_COM_CRC_FAILED)return SD_COM_CRC_FAILED;
return errorstatus;
}
/*************************************************************************/
//SDMMCʹ<43>ܿ<EFBFBD><DCBF><EFBFBD><EFBFBD><EFBFBD>ģʽ
//enx:0,<2C><>ʹ<EFBFBD><CAB9>;1,ʹ<><CAB9>;
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SDEnWideBus(u8 enx)
{
SD_Error errorstatus = SD_OK;
u32 scr[2]={0,0};
u8 arg=0X00;
if(enx)arg=0X02;
else arg=0X00;
if(SDMMC1->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>LOCKED״̬
errorstatus=FindSCR(RCA,scr); //<2F>õ<EFBFBD>SCR<43>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(errorstatus!=SD_OK)return errorstatus;
if((scr[1]&SD_WIDE_BUS_SUPPORT)!=SD_ALLZERO) //֧<>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD><EFBFBD>
{
SDMMC_Send_Cmd(SD_CMD_APP_CMD,1,(u32)RCA<<16); //<2F><><EFBFBD><EFBFBD>CMD55+RCA,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
if(errorstatus!=SD_OK)return errorstatus;
SDMMC_Send_Cmd(SD_CMD_APP_SD_SET_BUSWIDTH,1,arg);//<2F><><EFBFBD><EFBFBD>ACMD6,<2C><><EFBFBD><EFBFBD>Ӧ,<2C><><EFBFBD><EFBFBD>:10,4λ;00,1λ.
errorstatus=CmdResp1Error(SD_CMD_APP_SD_SET_BUSWIDTH);
return errorstatus;
}else return SD_REQUEST_NOT_APPLICABLE; //<2F><>֧<EFBFBD>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
//pstatus:<3A><>ǰ״̬.
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error IsCardProgramming(u8 *pstatus)
{
vu32 respR1 = 0, status = 0;
SDMMC_Send_Cmd(SD_CMD_SEND_STATUS,1,(u32)RCA<<16); //<2F><><EFBFBD><EFBFBD>CMD13
status=SDMMC1->STA;
while(!(status&((1<<0)|(1<<6)|(1<<2))))status=SDMMC1->STA;//<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(status&(1<<0)) //CRC<52><43><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
{
SDMMC1->ICR|=1<<0; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return SD_CMD_CRC_FAIL;
}
if(status&(1<<2)) //<2F><><EFBFBD>ʱ
{
SDMMC1->ICR|=1<<2; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return SD_CMD_RSP_TIMEOUT;
}
if(SDMMC1->RESPCMD!=SD_CMD_SEND_STATUS)return SD_ILLEGAL_CMD;
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
respR1=SDMMC1->RESP1;
*pstatus=(u8)((respR1>>9)&0x0000000F);
return SD_OK;
}
/*************************************************************************/
//<2F><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0>״̬
//pcardstatus:<3A><>״̬
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error SD_SendStatus(uint32_t *pcardstatus)
{
SD_Error errorstatus = SD_OK;
if(pcardstatus==NULL)
{
errorstatus=SD_INVALID_PARAMETER;
return errorstatus;
}
SDMMC_Send_Cmd(SD_CMD_SEND_STATUS,1,RCA<<16); //<2F><><EFBFBD><EFBFBD>CMD13,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS); //<2F><>ѯ<EFBFBD><D1AF>Ӧ״̬
if(errorstatus!=SD_OK)return errorstatus;
*pcardstatus=SDMMC1->RESP1;//<2F><>ȡ<EFBFBD><C8A1>Ӧֵ
return errorstatus;
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>SD<53><44><EFBFBD><EFBFBD>״̬
//<2F><><EFBFBD><EFBFBD>ֵ:SD<53><44>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SDCardState SD_GetState(void)
{
u32 resp1=0;
if(SD_SendStatus(&resp1)!=SD_OK)return SD_CARD_ERROR;
else return (SDCardState)((resp1>>9) & 0x0F);
}
/*************************************************************************/
//<2F><><EFBFBD><EFBFBD>SD<53><44><EFBFBD><EFBFBD>SCR<43>Ĵ<EFBFBD><C4B4><EFBFBD>ֵ
//rca:<3A><><EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD>ַ
//pscr:<3A><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>(<28>洢SCR<43><52><EFBFBD><EFBFBD>)
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD>״̬
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
SD_Error FindSCR(u16 rca,u32 *pscr)
{
SD_Error errorstatus = SD_OK;
u32 tempscr[2]={0,0};
SDMMC_Send_Cmd(SD_CMD_SET_BLOCKLEN,1,8); //<2F><><EFBFBD><EFBFBD>CMD16,<2C><><EFBFBD><EFBFBD>Ӧ,<2C><><EFBFBD><EFBFBD>Block SizeΪ8<CEAA>ֽ<EFBFBD>
errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);
if(errorstatus!=SD_OK)return errorstatus;
SDMMC_Send_Cmd(SD_CMD_APP_CMD,1,(u32)rca<<16); //<2F><><EFBFBD><EFBFBD>CMD55,<2C><><EFBFBD><EFBFBD>Ӧ
errorstatus=CmdResp1Error(SD_CMD_APP_CMD);
if(errorstatus!=SD_OK)return errorstatus;
SDMMC_Send_Data_Cfg(SD_DATATIMEOUT,8,3,1); //8<><38><EFBFBD>ֽڳ<D6BD><DAB3><EFBFBD>,blockΪ8<CEAA>ֽ<EFBFBD>,SD<53><44><EFBFBD><EFBFBD>SDMMC.
SDMMC_Send_Cmd(SD_CMD_SD_APP_SEND_SCR,1,0); //<2F><><EFBFBD><EFBFBD>ACMD51,<2C><><EFBFBD><EFBFBD>Ӧ,<2C><><EFBFBD><EFBFBD>Ϊ0
errorstatus=CmdResp1Error(SD_CMD_SD_APP_SEND_SCR);
if(errorstatus!=SD_OK)return errorstatus;
while(!(SDMMC1->STA&(SDMMC_STA_RXOVERR|SDMMC_STA_DCRCFAIL|SDMMC_STA_DTIMEOUT|SDMMC_STA_DBCKEND|SDMMC_STA_DATAEND)))
{
if(!(SDMMC1->STA&(1<<19))) //<2F><><EFBFBD><EFBFBD>FIFO<46><4F><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD>
{
tempscr[0]=SDMMC1->FIFO; //<2F><>ȡFIFO<46><4F><EFBFBD><EFBFBD>
tempscr[1]=SDMMC1->FIFO; //<2F><>ȡFIFO<46><4F><EFBFBD><EFBFBD>
break;
}
}
if(SDMMC1->STA&(1<<3)) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD>ʱ
{
SDMMC1->ICR|=1<<3; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return SD_DATA_TIMEOUT;
}else if(SDMMC1->STA&(1<<1))//<2F>ѷ<EFBFBD><D1B7><EFBFBD>/<2F><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ݿ<EFBFBD>CRCУ<43><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return SD_DATA_CRC_FAIL;
}else if(SDMMC1->STA&(1<<5))//<2F><><EFBFBD><EFBFBD>FIFO<46><4F><EFBFBD><EFBFBD>
{
SDMMC1->ICR|=1<<5; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return SD_RX_OVERRUN;
}
SDMMC1->ICR=0X1FE00FFF; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD>8λΪ<CEBB><CEAA>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
*(pscr+1)=((tempscr[0]&SD_0TO7BITS)<<24)|((tempscr[0]&SD_8TO15BITS)<<8)|((tempscr[0]&SD_16TO23BITS)>>8)|((tempscr[0]&SD_24TO31BITS)>>24);
*(pscr)=((tempscr[1]&SD_0TO7BITS)<<24)|((tempscr[1]&SD_8TO15BITS)<<8)|((tempscr[1]&SD_16TO23BITS)>>8)|((tempscr[1]&SD_24TO31BITS)>>24);
return errorstatus;
}
/*************************************************************************/
//<2F><>SD<53><44>
//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>;
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
u8 SD_ReadDisk(u8*buf,u32 sector,u32 cnt)
{
u8 sta=SD_OK;
long long lsector=sector;
u32 n;
if(CardType!=STD_CAPACITY_SD_CARD_V1_1)lsector<<=9;
if((u32)buf%4!=0)
{
for(n=0;n<cnt;n++)
{
sta=SD_ReadBlocks(SDMMC_DATA_BUFFER,lsector+512*n,512,1);//<2F><><EFBFBD><EFBFBD>sector<6F>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD>
memcpy(buf,SDMMC_DATA_BUFFER,512);
buf+=512;
}
}
else sta=SD_ReadBlocks(buf,lsector,512,cnt); //<2F><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>sector
return sta;
}
/*************************************************************************/
//дSD<53><44>
//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>;
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/
u8 SD_WriteDisk(u8*buf,u32 sector,u32 cnt)
{
u8 sta=SD_OK;
u32 n;
long long lsector=sector;
if(CardType!=STD_CAPACITY_SD_CARD_V1_1)lsector<<=9;
if((u32)buf%4!=0)
{
for(n=0;n<cnt;n++)
{
memcpy(SDMMC_DATA_BUFFER,buf,512);
sta=SD_WriteBlocks(SDMMC_DATA_BUFFER,lsector+512*n,512,1);//<2F><><EFBFBD><EFBFBD>sector<6F><72>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
buf+=512;
}
}else sta=SD_WriteBlocks(buf,lsector,512,cnt); //<2F><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>sector
return sta;
}
/*************************************************************************/
//STM32H7<48><37><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>-HAL<41><EFBFBD><E2BAAF><EFBFBD>
//DevEBox <20><>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>mcudev.taobao.com
//<2F>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>̣<EFBFBD>shop389957290.taobao.com
/*************************************************************************/