推荐电商网站建设,拼多多网店怎么开,购物网站建设和使用,网站编程培训机构排名前十3.2 SPI硬件时序方式 上面的3.1小节是采用SPI模拟时序驱动SD NAND#xff0c;STM32本身集成有SPI硬件模块#xff0c;可以直接利用STM32硬件SPI接口读写。 下面贴出底层的适配代码。 上面贴出的驱动代码里#xff0c;已经将驱动接口部分和协议逻辑部分区分开了#xff0c;替…3.2 SPI硬件时序方式 上面的3.1小节是采用SPI模拟时序驱动SD NANDSTM32本身集成有SPI硬件模块可以直接利用STM32硬件SPI接口读写。 下面贴出底层的适配代码。 上面贴出的驱动代码里已经将驱动接口部分和协议逻辑部分区分开了替换底层的SIP读写代码非常方便。 1主要替换的代码
/*
函数功能SPI初始化(模拟SPI)
硬件连接
MISO---PB14
MOSI---PB15
SCLK---PB13
*/
void SPI_Init(void)
{
/*开启时钟*/
RCC-APB1ENR|114; //开启SPI2时钟
RCC-APB2ENR|13; //PB
GPIOB-CRH0X000FFFFF; //清除寄存器
GPIOB-CRH|0XB8B00000;
GPIOB-ODR|0X713; //PB13/14/15上拉--输出高电平
/*SPI2基本配置*/
SPI2-CR10X0; //清空寄存器
SPI2-CR1|015; //选择“双线双向”模式
SPI2-CR1|011; //使用8位数据帧格式进行发送/接收
SPI2-CR1|010; //全双工(发送和接收)
SPI2-CR1|19; //启用软件从设备管理
SPI2-CR1|18; //NSS
SPI2-CR1|07; //帧格式先发送高位
SPI2-CR1|0x03;//当总线频率为36MHZ时SPI速度为18MHZ高速。
SPI2-CR1|12; //配置为主设备
SPI2-CR1|11; //空闲状态时 SCK保持高电平。
SPI2-CR1|10; //数据采样从第二个时钟边沿开始。
SPI2-CR1|16; //开启SPI设备。
} /*
函数功能SPI读写一个字节
*/
u8 SPI_ReadWriteOneByte(u8 data_tx)
{ u16 cnt0; while((SPI2-SR11)0) //等待发送区空--等待发送缓冲为空 { cnt; if(cnt65530)return 0; //超时退出 u162个字节 } SPI2-DRdata_tx; //发送一个byte cnt0; while((SPI2-SR10)0) //等待接收完一个byte { cnt; if(cnt65530)return 0; //超时退出 } return SPI2-DR; //返回收到的数据
} 函数功能SD卡底层接口,通过SPI时序向SD卡读写一个字节
函数参数data是要写入的数据
返 回 值读到的数据
*/
u8 SDCardReadWriteOneByte(u8 DataTx)
{ return SPI_ReadWriteOneByte(DataTx);
} 2运行效果 3.3 SDIO方式
如果想提高SD NAND的读写速度可以采用SDIO协议STM32本身有SDIO的硬件支持配置好SDIO的寄存器即可完成SD NAND的操作。 SDIO的数据线都比SPI多读写速度自然没法比的。 下面贴出STM32F103ZE上面编写的SDIO协议读写SD NAND的驱动代码。 1整体工程代码 2sdio.c
#include sdio_sdcard.h
#include string.h
#include sys.h
#include usart.h static u8 CardTypeSDIO_STD_CAPACITY_SD_CARD_V1_1; //SD卡类型默认为1.x卡
static u32 CSD_Tab[4],CID_Tab[4],RCA0; //SD卡CSD,CID以及相对地址(RCA)数据
static u8 DeviceModeSD_DMA_MODE; //工作模式,注意,工作模式必须通过SDIO_SdCardSetDeviceMode,后才算数.这里只是定义一个默认的模式(SD_DMA_MODE)
static u8 StopCondition0; //是否发送停止传输标志位,DMA多块读写的时候用到
volatile SDIO_SD_ERROR_INFO TransferErrorSD_OK; //数据传输错误标志,DMA读写时使用
volatile u8 TransferEnd0; //传输结束标志,DMA读写时使用
SD_CardInfo SDCardInfo; //SD卡信息 //SDIO_SdCardReadDiskSector/SDIO_SdCardWriteDiskSector函数专用buf,当这两个函数的数据缓存区地址不是4字节对齐的时候,
//需要用到该数组,确保数据缓存区地址是4字节对齐的.
__align(4) u8 SDIO_DATA_BUFFER[512]; /*
SD卡与开发板的SDIO方式接线关系如下:
DATA0---PC8
DATA1---PC9
DATA2---PC10
DATA3---PC11
CLK-----PC1
CMD-----PD2
*/ /*
函数功能:SDIO方式初始化SD卡
返回值 :错误代码;(0,无错误)
*/
SDIO_SD_ERROR_INFO SDIO_SdCardInit(void)
{
u8 clkdiv0;
SDIO_SD_ERROR_INFO errorstatusSD_OK;
//SDIO IO口初始化
RCC-APB2ENR|14; //使能PORTC时钟
RCC-APB2ENR|15; //使能PORTD时钟 RCC-AHBENR|110; //使能SDIO时钟 RCC-AHBENR|11; //使能DMA2时钟 GPIOC-CRH0XFFF00000;
GPIOC-CRH|0X000BBBBB; //PC.8~12 复用输出 GPIOD-CRL0XFFFFF0FF;
GPIOD-CRL|0X00000B00; //PD2复用输出,PD7 上拉输入 //SDIO外设寄存器设置为默认值
SDIO-POWER0x00000000;
SDIO-CLKCR0x00000000;
SDIO-ARG0x00000000;
SDIO-CMD0x00000000;
SDIO-DTIMER0x00000000;
SDIO-DLEN0x00000000;
SDIO-DCTRL0x00000000;
SDIO-ICR0x00C007FF;
SDIO-MASK0x00000000; STM32_NVIC_SetPriority(SDIO_IRQn,0,0); //SDIO中断配置 errorstatusSDIO_SdPowerON(); //SD卡上电 SDIO_SdCardInitializeCards(); //初始化SD卡 SDIO_SdCardGetInfo(SDCardInfo); //获取卡信息 SDIO_SdCardSelectAddr((u32)(SDCardInfo.RCA16));//选中SD卡 SDIO_SdCardEnableWideBusOperation(1); //4位宽度,如果是MMC卡,则不能用4位模式 if((errorstatusSD_OK)||(SDIO_MULTIMEDIA_CARDCardType)) { if(SDCardInfo.CardTypeSDIO_STD_CAPACITY_SD_CARD_V1_1||SDCardInfo.CardTypeSDIO_STD_CAPACITY_SD_CARD_V2_0) { clkdivSDIO_TRANSFER_CLK_DIV6; //V1.1/V2.0卡设置最高72/126Mhz }else clkdivSDIO_TRANSFER_CLK_DIV; //SDHC等其他卡设置最高72/612Mhz SDIO_ClockSet(clkdiv); //设置时钟频率,SDIO时钟计算公式:SDIO_CK时钟SDIOCLK/[clkdiv2];其中,SDIOCLK固定为48Mhz errorstatusSDIO_SdCardSetDeviceMode(SD_POLLING_MODE); //设置为查询模式 }
return errorstatus;
} /*
函数功能: SDIO时钟初始化设置
函数参数: clkdiv:时钟分频系数 CK时钟SDIOCLK/[clkdiv2];(SDIOCLK时钟固定为48Mhz)
*/
void SDIO_ClockSet(u8 clkdiv)
{
u32 tmpregSDIO-CLKCR; tmpreg0XFFFFFF00; tmpreg|clkdiv;
SDIO-CLKCRtmpreg;
} /*
函数功能: SDIO发送命令函数
函数参数: cmdindex:命令索引,低六位有效 waitrsp:期待的相应.00/10,无响应;01,短响应;11,长响应 arg:参数
*/
void SDIO_SendCmd(u8 cmdindex,u8 waitrsp,u32 arg)
{
u32 tmpreg;
SDIO-ARGarg;
tmpregSDIO-CMD;
tmpreg0XFFFFF800; //清除index和waitrsp
tmpreg|cmdindex0X3F; //设置新的index
tmpreg|waitrsp6; //设置新的wait rsp
tmpreg|08; //无等待 tmpreg|110; //命令通道状态机使能
SDIO-CMDtmpreg;
} /*
函数功能: SDIO发送数据配置函数
函数参数: datatimeout:超时时间设置 datalen:传输数据长度,低25位有效,必须为块大小的整数倍 blksize:块大小.实际大小为:2^blksize字节 dir:数据传输方向:0,控制器到卡;1,卡到控制器;
*/
void SDIO_SendDataConfig(u32 datatimeout,u32 datalen,u8 blksize,u8 dir)
{
u32 tmpreg;
SDIO-DTIMERdatatimeout; SDIO-DLENdatalen0X1FFFFFF; //低25位有效
tmpregSDIO-DCTRL;
tmpreg0xFFFFFF08; //清除之前的设置.
tmpreg|blksize4; //设置块大小
tmpreg|02; //块数据传输
tmpreg|(dir0X01)1; //方向控制
tmpreg|10; //数据传输使能,DPSM状态机
SDIO-DCTRLtmpreg;
} /*
函数功能:卡上电 查询所有SDIO接口上的卡设备,并查询其电压和配置时钟
返回值:错误代码;(0,无错误)
*/
SDIO_SD_ERROR_INFO SDIO_SdPowerON(void)
{ u8 i0;
SDIO_SD_ERROR_INFO errorstatusSD_OK;
u32 response0,count0,validvoltage0;
u32 SDTypeSD_STD_CAPACITY;
//配置CLKCR寄存器
SDIO-CLKCR0; //清空CLKCR之前的设置
SDIO-CLKCR|09; //非省电模式
SDIO-CLKCR|010; //关闭旁路,CK根据分频设置输出
SDIO-CLKCR|011; //1位数据宽度
SDIO-CLKCR|013; //SDIOCLK上升沿产生SDIOCK
SDIO-CLKCR|014; //关闭硬件流控制
SDIO_ClockSet(SDIO_INIT_CLK_DIV);//设置时钟频率(初始化的时候,不能超过400Khz) SDIO-POWER0X03; //上电状态,开启卡时钟 SDIO-CLKCR|18; //SDIOCK使能 for(i0;i74;i)
{
SDIO_SendCmd(SD_CMD_GO_IDLE_STATE,0,0);//发送CMD0进入IDLE STAGE模式命令.
errorstatusSDIO_CmdErrorCheck();
if(errorstatusSD_OK)break; } if(errorstatus)return errorstatus;//返回错误状态
SDIO_SendCmd(SDIO_SEND_IF_COND,1,SD_CHECK_PATTERN);//发送CMD8,短响应,检查SD卡接口特性. //arg[11:8]:01,支持电压范围,2.7~3.6V
//arg[7:0]:默认0XAA
//返回响应7 errorstatusSDIO_CmdResp7Error(); //等待R7响应 if(errorstatusSD_OK) //R7响应正常
{
CardTypeSDIO_STD_CAPACITY_SD_CARD_V2_0; //SD 2.0卡
SDTypeSD_HIGH_CAPACITY; //高容量卡
}
SDIO_SendCmd(SD_CMD_APP_CMD,1,0); //发送CMD55,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_APP_CMD); //等待R1响应
if(errorstatusSD_OK)//SD2.0/SD 1.1
{
//SD卡,发送ACMD41 SD_APP_OP_COND,参数为:0x80100000
while((!validvoltage)(countSD_MAX_VOLT_TRIAL))
{
SDIO_SendCmd(SD_CMD_APP_CMD,1,0); //发送CMD55,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_APP_CMD); //等待R1响应 if(errorstatus!SD_OK)return errorstatus; //响应错误
SDIO_SendCmd(SD_CMD_SD_APP_OP_COND,1,SD_VOLTAGE_WINDOW_SD|SDType);//发送ACMD41,短响应
errorstatusSDIO_CmdResp3Error(); //等待R3响应 if(errorstatus!SD_OK)return errorstatus; //响应错误
responseSDIO-RESP1;; //得到响应
validvoltage(((response31)1)?1:0); //判断SD卡上电是否完成
count;
}
if(countSD_MAX_VOLT_TRIAL)
{
errorstatusSD_INVALID_VOLTRANGE;
return errorstatus;
}
if(responseSD_HIGH_CAPACITY)
{
CardTypeSDIO_HIGH_CAPACITY_SD_CARD;
} } return(errorstatus);
} /*
函数功能: SD卡断电
返回值:错误代码;(0,无错误)
*/
SDIO_SD_ERROR_INFO SD_PowerOFF(void)
{ SDIO-POWER~(30);//SDIO电源关闭,时钟停止
return SD_OK;
} /*
函数功能:初始化所有的卡,并让卡进入就绪状态
返回值:错误代码
*/
SDIO_SD_ERROR_INFO SDIO_SdCardInitializeCards(void)
{ SDIO_SD_ERROR_INFO errorstatusSD_OK;
u16 rca 0x01; if((SDIO-POWER0X03)0)return SD_REQUEST_NOT_APPLICABLE;//检查电源状态,确保为上电状态 if(SDIO_SECURE_DIGITAL_IO_CARD!CardType) //非SECURE_DIGITAL_IO_CARD
{
SDIO_SendCmd(SD_CMD_ALL_SEND_CID,3,0); //发送CMD2,取得CID,长响应
errorstatusSDIO_CmdResp2Error(); //等待R2响应
if(errorstatus!SD_OK)return errorstatus; //响应错误 CID_Tab[0]SDIO-RESP1;
CID_Tab[1]SDIO-RESP2;
CID_Tab[2]SDIO-RESP3;
CID_Tab[3]SDIO-RESP4;
}
if((SDIO_STD_CAPACITY_SD_CARD_V1_1CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0CardType)||(SDIO_SECURE_DIGITAL_IO_COMBO_CARDCardType)||(SDIO_HIGH_CAPACITY_SD_CARDCardType))//判断卡类型
{
SDIO_SendCmd(SD_CMD_SET_REL_ADDR,1,0); //发送CMD3,短响应
errorstatusSDIO_CmdResp6Error(SD_CMD_SET_REL_ADDR,rca);//等待R6响应
if(errorstatus!SD_OK)return errorstatus; //响应错误
} if(SDIO_MULTIMEDIA_CARDCardType) { SDIO_SendCmd(SD_CMD_SET_REL_ADDR,1,(u32)(rca16));//发送CMD3,短响应 errorstatusSDIO_CmdResp2Error(); //等待R2响应 if(errorstatus!SD_OK)return errorstatus; //响应错误 }
if(SDIO_SECURE_DIGITAL_IO_CARD!CardType) //非SECURE_DIGITAL_IO_CARD
{
RCA rca;
SDIO_SendCmd(SD_CMD_SEND_CSD,3,(u32)(rca16));//发送CMD9卡RCA,取得CSD,长响应
errorstatusSDIO_CmdResp2Error(); //等待R2响应
if(errorstatus!SD_OK)return errorstatus; //响应错误 CSD_Tab[0]SDIO-RESP1;
CSD_Tab[1]SDIO-RESP2;
CSD_Tab[2]SDIO-RESP3;
CSD_Tab[3]SDIO-RESP4;
}
return SD_OK;//卡初始化成功
} /*
函数功能:得到卡信息
函数参数: cardinfo:卡信息存储区
返回值:错误状态
*/
SDIO_SD_ERROR_INFO SDIO_SdCardGetInfo(SD_CardInfo *cardinfo)
{ SDIO_SD_ERROR_INFO errorstatusSD_OK;
u8 tmp0;
cardinfo-CardType(u8)CardType; //卡类型
cardinfo-RCA(u16)RCA; //卡RCA值
tmp(u8)((CSD_Tab[0]0xFF000000)24);
cardinfo-SD_csd.CSDStruct(tmp0xC0)6; //CSD结构
cardinfo-SD_csd.SysSpecVersion(tmp0x3C)2; //2.0协议还没定义这部分(为保留),应该是后续协议定义的
cardinfo-SD_csd.Reserved1tmp0x03; //2个保留位
tmp(u8)((CSD_Tab[0]0x00FF0000)16); //第1个字节
cardinfo-SD_csd.TAACtmp; //数据读时间1
tmp(u8)((CSD_Tab[0]0x0000FF00)8); //第2个字节
cardinfo-SD_csd.NSACtmp; //数据读时间2
tmp(u8)(CSD_Tab[0]0x000000FF); //第3个字节
cardinfo-SD_csd.MaxBusClkFrectmp; //传输速度
tmp(u8)((CSD_Tab[1]0xFF000000)24); //第4个字节
cardinfo-SD_csd.CardComdClassestmp4; //卡指令类高四位
tmp(u8)((CSD_Tab[1]0x00FF0000)16); //第5个字节
cardinfo-SD_csd.CardComdClasses|(tmp0xF0)4;//卡指令类低四位
cardinfo-SD_csd.RdBlockLentmp0x0F; //最大读取数据长度
tmp(u8)((CSD_Tab[1]0x0000FF00)8); //第6个字节
cardinfo-SD_csd.PartBlockRead(tmp0x80)7; //允许分块读
cardinfo-SD_csd.WrBlockMisalign(tmp0x40)6; //写块错位
cardinfo-SD_csd.RdBlockMisalign(tmp0x20)5; //读块错位
cardinfo-SD_csd.DSRImpl(tmp0x10)4;
cardinfo-SD_csd.Reserved20; //保留 if((CardTypeSDIO_STD_CAPACITY_SD_CARD_V1_1)||(CardTypeSDIO_STD_CAPACITY_SD_CARD_V2_0)||(SDIO_MULTIMEDIA_CARDCardType))//标准1.1/2.0卡/MMC卡
{
cardinfo-SD_csd.DeviceSize(tmp0x03)10; //C_SIZE(12位) tmp(u8)(CSD_Tab[1]0x000000FF); //第7个字节
cardinfo-SD_csd.DeviceSize|(tmp)2; tmp(u8)((CSD_Tab[2]0xFF000000)24); //第8个字节
cardinfo-SD_csd.DeviceSize|(tmp0xC0)6; cardinfo-SD_csd.MaxRdCurrentVDDMin(tmp0x38)3;
cardinfo-SD_csd.MaxRdCurrentVDDMax(tmp0x07); tmp(u8)((CSD_Tab[2]0x00FF0000)16); //第9个字节
cardinfo-SD_csd.MaxWrCurrentVDDMin(tmp0xE0)5;
cardinfo-SD_csd.MaxWrCurrentVDDMax(tmp0x1C)2;
cardinfo-SD_csd.DeviceSizeMul(tmp0x03)1;//C_SIZE_MULT tmp(u8)((CSD_Tab[2]0x0000FF00)8); //第10个字节
cardinfo-SD_csd.DeviceSizeMul|(tmp0x80)7; cardinfo-CardCapacity(cardinfo-SD_csd.DeviceSize1);//计算卡容量
cardinfo-CardCapacity*(1(cardinfo-SD_csd.DeviceSizeMul2));
cardinfo-CardBlockSize1(cardinfo-SD_csd.RdBlockLen);//块大小
cardinfo-CardCapacity*cardinfo-CardBlockSize;
}else if(CardTypeSDIO_HIGH_CAPACITY_SD_CARD) //高容量卡
{ tmp(u8)(CSD_Tab[1]0x000000FF); //第7个字节
cardinfo-SD_csd.DeviceSize(tmp0x3F)16;//C_SIZE tmp(u8)((CSD_Tab[2]0xFF000000)24); //第8个字节 cardinfo-SD_csd.DeviceSize|(tmp8); tmp(u8)((CSD_Tab[2]0x00FF0000)16); //第9个字节 cardinfo-SD_csd.DeviceSize|(tmp); tmp(u8)((CSD_Tab[2]0x0000FF00)8); //第10个字节 cardinfo-CardCapacity(long long)(cardinfo-SD_csd.DeviceSize1)*512*1024;//计算卡容量
cardinfo-CardBlockSize512; //块大小固定为512字节
}
cardinfo-SD_csd.EraseGrSize(tmp0x40)6;
cardinfo-SD_csd.EraseGrMul(tmp0x3F)1;
tmp(u8)(CSD_Tab[2]0x000000FF); //第11个字节
cardinfo-SD_csd.EraseGrMul|(tmp0x80)7;
cardinfo-SD_csd.WrProtectGrSize(tmp0x7F); tmp(u8)((CSD_Tab[3]0xFF000000)24); //第12个字节
cardinfo-SD_csd.WrProtectGrEnable(tmp0x80)7;
cardinfo-SD_csd.ManDeflECC(tmp0x60)5;
cardinfo-SD_csd.WrSpeedFact(tmp0x1C)2;
cardinfo-SD_csd.MaxWrBlockLen(tmp0x03)2;
tmp(u8)((CSD_Tab[3]0x00FF0000)16); //第13个字节
cardinfo-SD_csd.MaxWrBlockLen|(tmp0xC0)6;
cardinfo-SD_csd.WriteBlockPaPartial(tmp0x20)5;
cardinfo-SD_csd.Reserved30;
cardinfo-SD_csd.ContentProtectAppli(tmp0x01);
tmp(u8)((CSD_Tab[3]0x0000FF00)8); //第14个字节
cardinfo-SD_csd.FileFormatGrouop(tmp0x80)7;
cardinfo-SD_csd.CopyFlag(tmp0x40)6;
cardinfo-SD_csd.PermWrProtect(tmp0x20)5;
cardinfo-SD_csd.TempWrProtect(tmp0x10)4;
cardinfo-SD_csd.FileFormat(tmp0x0C)2;
cardinfo-SD_csd.ECC(tmp0x03);
tmp(u8)(CSD_Tab[3]0x000000FF); //第15个字节
cardinfo-SD_csd.CSD_CRC(tmp0xFE)1;
cardinfo-SD_csd.Reserved41;
tmp(u8)((CID_Tab[0]0xFF000000)24); //第0个字节
cardinfo-SD_cid.ManufacturerIDtmp;
tmp(u8)((CID_Tab[0]0x00FF0000)16); //第1个字节
cardinfo-SD_cid.OEM_AppliIDtmp8;
tmp(u8)((CID_Tab[0]0x000000FF00)8); //第2个字节
cardinfo-SD_cid.OEM_AppliID|tmp;
tmp(u8)(CID_Tab[0]0x000000FF); //第3个字节
cardinfo-SD_cid.ProdName1tmp24;
tmp(u8)((CID_Tab[1]0xFF000000)24); //第4个字节
cardinfo-SD_cid.ProdName1|tmp16;
tmp(u8)((CID_Tab[1]0x00FF0000)16); //第5个字节
cardinfo-SD_cid.ProdName1|tmp8;
tmp(u8)((CID_Tab[1]0x0000FF00)8); //第6个字节
cardinfo-SD_cid.ProdName1|tmp;
tmp(u8)(CID_Tab[1]0x000000FF); //第7个字节
cardinfo-SD_cid.ProdName2tmp;
tmp(u8)((CID_Tab[2]0xFF000000)24); //第8个字节
cardinfo-SD_cid.ProdRevtmp;
tmp(u8)((CID_Tab[2]0x00FF0000)16); //第9个字节
cardinfo-SD_cid.ProdSNtmp24;
tmp(u8)((CID_Tab[2]0x0000FF00)8); //第10个字节
cardinfo-SD_cid.ProdSN|tmp16;
tmp(u8)(CID_Tab[2]0x000000FF); //第11个字节
cardinfo-SD_cid.ProdSN|tmp8;
tmp(u8)((CID_Tab[3]0xFF000000)24); //第12个字节
cardinfo-SD_cid.ProdSN|tmp;
tmp(u8)((CID_Tab[3]0x00FF0000)16); //第13个字节
cardinfo-SD_cid.Reserved1|(tmp0xF0)4;
cardinfo-SD_cid.ManufactDate(tmp0x0F)8;
tmp(u8)((CID_Tab[3]0x0000FF00)8); //第14个字节
cardinfo-SD_cid.ManufactDate|tmp;
tmp(u8)(CID_Tab[3]0x000000FF); //第15个字节
cardinfo-SD_cid.CID_CRC(tmp0xFE)1;
cardinfo-SD_cid.Reserved21;
return errorstatus;
} /*
函数功能: 设置SDIO总线宽度
函数参数: wmode:位宽模式.0,1位数据宽度;1,4位数据宽度;2,8位数据宽度
返回值:SD卡错误状态
*/
SDIO_SD_ERROR_INFO SDIO_SdCardEnableWideBusOperation(u32 wmode)
{ SDIO_SD_ERROR_INFO errorstatusSD_OK; if((SDIO_STD_CAPACITY_SD_CARD_V1_1CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0CardType)||(SDIO_HIGH_CAPACITY_SD_CARDCardType)) { if(wmode2)return SD_UNSUPPORTED_FEATURE;//不支持8位模式 else { errorstatusSDIO_SdCardEnWideBus(wmode); if(SD_OKerrorstatus) { SDIO-CLKCR~(311); //清除之前的位宽设置 SDIO-CLKCR|(u16)wmode11;//1位/4位总线宽度 SDIO-CLKCR|014; //不开启硬件流控制 } } } return errorstatus;
} /*
函数功能:设置SD卡工作模式
返回值:错误状态
*/
SDIO_SD_ERROR_INFO SDIO_SdCardSetDeviceMode(u32 Mode)
{
SDIO_SD_ERROR_INFO errorstatus SD_OK; if((ModeSD_DMA_MODE)||(ModeSD_POLLING_MODE))DeviceModeMode;
else errorstatusSD_INVALID_PARAMETER;
return errorstatus;
} /*
函数功能:选卡,发送CMD7,选择相对地址(rca)为addr的卡,取消其他卡.如果为0,则都不选择.
函数参数: addr:卡的RCA地址
*/
SDIO_SD_ERROR_INFO SDIO_SdCardSelectAddr(u32 addr)
{ SDIO_SendCmd(SD_CMD_SEL_DESEL_CARD,1,addr); //发送CMD7,选择卡,短响应 return SDIO_CmdResp1Error(SD_CMD_SEL_DESEL_CARD);
} /*
函数功能: SD卡读取一个块
函数参数: buf:读数据缓存区(必须4字节对齐!!) addr:读取地址 blksize:块大小
*/
SDIO_SD_ERROR_INFO SDIO_SdCardReadBlock(u8 *buf,long long addr,u16 blksize)
{ SDIO_SD_ERROR_INFO errorstatusSD_OK; u8 power; u32 count0,*tempbuff(u32*)buf;//转换为u32指针 u32 timeoutSDIO_DATATIMEOUT; if(NULLbuf)return SD_INVALID_PARAMETER; SDIO-DCTRL0x0; //数据控制寄存器清零(关DMA) if(CardTypeSDIO_HIGH_CAPACITY_SD_CARD)//大容量卡 { blksize512; addr9; } SDIO_SendDataConfig(SD_DATATIMEOUT,0,0,0); //清除DPSM状态机配置 if(SDIO-RESP1SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了 if((blksize0)(blksize2048)((blksize(blksize-1))0)) { powerconvert_from_bytes_to_power_of_two(blksize); SDIO_SendCmd(SD_CMD_SET_BLOCKLEN,1,blksize); //发送CMD16设置数据长度为blksize,短响应 errorstatusSDIO_CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应 if(errorstatus!SD_OK)return errorstatus; //响应错误 }else return SD_INVALID_PARAMETER; SDIO_SendDataConfig(SD_DATATIMEOUT,blksize,power,1); //blksize,卡到控制器 SDIO_SendCmd(SD_CMD_READ_SINGLE_BLOCK,1,addr); //发送CMD17从addr地址出读取数据,短响应 errorstatusSDIO_CmdResp1Error(SD_CMD_READ_SINGLE_BLOCK);//等待R1响应 if(errorstatus!SD_OK)return errorstatus; //响应错误 if(DeviceModeSD_POLLING_MODE) //查询模式,轮询数据 { // INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!) while(!(SDIO-STA((15)|(11)|(13)|(110)|(19))))//无上溢/CRC/超时/完成(标志)/起始位错误 { if(SDIO-STA(115)) //接收区半满,表示至少存了8个字 { for(count0;count8;count) //循环读取数据 { *(tempbuffcount)SDIO-FIFO; } tempbuff8; timeout0X7FFFFF; //读数据溢出时间 }else //处理超时 { if(timeout0)return SD_DATA_TIMEOUT; timeout--; } } if(SDIO-STA(13)) //数据超时错误 { SDIO-ICR|13; //清错误标志 return SD_DATA_TIMEOUT; }else if(SDIO-STA(11)) //数据块CRC错误 { SDIO-ICR|11; //清错误标志 return SD_DATA_CRC_FAIL; }else if(SDIO-STA(15)) //接收fifo上溢错误 { SDIO-ICR|15; //清错误标志 return SD_RX_OVERRUN; }else if(SDIO-STA(19)) //接收起始位错误 { SDIO-ICR|19; //清错误标志 return SD_START_BIT_ERR; } while(SDIO-STA(121)) //FIFO里面,还存在可用数据 { *tempbuffSDIO-FIFO; //循环读取数据 tempbuff; } // INTX_ENABLE();//开启总中断 SDIO-ICR0X5FF; //清除所有标记 }else if(DeviceModeSD_DMA_MODE) { SDIO_SdCard_DMAConfig((u32*)buf,blksize,0); TransferErrorSD_OK; StopCondition0; //单块读,不需要发送停止传输指令 TransferEnd0; //传输结束标置位在中断服务置1 SDIO-MASK|(11)|(13)|(18)|(15)|(19); //配置需要的中断 SDIO-DCTRL|13; //SDIO DMA使能 while(((DMA2-ISR0X2000)RESET)(TransferEnd0)(TransferErrorSD_OK)timeout)timeout--;//等待传输完成 if(timeout0)return SD_DATA_TIMEOUT;//超时 if(TransferError!SD_OK)errorstatusTransferError; } return errorstatus;
} /*
函数功能: SD卡读取多个块
函数参数: buf:读数据缓存区 addr:读取地址 blksize:块大小 nblks:要读取的块数
返回值:错误状态
*/
__align(4) u32 *tempbuff;
SDIO_SD_ERROR_INFO SDIO_SdCardReadMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks)
{ SDIO_SD_ERROR_INFO errorstatusSD_OK;
u8 power; u32 count0;
u32 timeoutSDIO_DATATIMEOUT;
tempbuff(u32*)buf; //转换为u32指针 SDIO-DCTRL0x0; //数据控制寄存器清零(关DMA)
if(CardTypeSDIO_HIGH_CAPACITY_SD_CARD)//大容量卡
{
blksize512;
addr9;
} SDIO_SendDataConfig(SD_DATATIMEOUT,0,0,0); //清除DPSM状态机配置
if(SDIO-RESP1SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了
if((blksize0)(blksize2048)((blksize(blksize-1))0))
{
powerconvert_from_bytes_to_power_of_two(blksize);
SDIO_SendCmd(SD_CMD_SET_BLOCKLEN,1,blksize); //发送CMD16设置数据长度为blksize,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应
if(errorstatus!SD_OK)return errorstatus; //响应错误
}else return SD_INVALID_PARAMETER;
if(nblks1) //多块读
{ if(nblks*blksizeSD_MAX_DATA_LENGTH)return SD_INVALID_PARAMETER;//判断是否超过最大接收长度
SDIO_SendDataConfig(SD_DATATIMEOUT,nblks*blksize,power,1);//nblks*blksize,512块大小,卡到控制器 SDIO_SendCmd(SD_CMD_READ_MULT_BLOCK,1,addr); //发送CMD18从addr地址出读取数据,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_READ_MULT_BLOCK);//等待R1响应
if(errorstatus!SD_OK)return errorstatus; //响应错误 if(DeviceModeSD_POLLING_MODE)
{
// INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!)
while(!(SDIO-STA((15)|(11)|(13)|(18)|(19))))//无上溢/CRC/超时/完成(标志)/起始位错误
{
if(SDIO-STA(115)) //接收区半满,表示至少存了8个字
{
for(count0;count8;count) //循环读取数据
{
*(tempbuffcount)SDIO-FIFO;
}
tempbuff8;
timeout0X7FFFFF; //读数据溢出时间
}else //处理超时
{
if(timeout0)return SD_DATA_TIMEOUT;
timeout--;
}
}
if(SDIO-STA(13)) //数据超时错误
{ SDIO-ICR|13; //清错误标志
return SD_DATA_TIMEOUT; }else if(SDIO-STA(11)) //数据块CRC错误
{ SDIO-ICR|11; //清错误标志
return SD_DATA_CRC_FAIL;
}else if(SDIO-STA(15)) //接收fifo上溢错误
{ SDIO-ICR|15; //清错误标志
return SD_RX_OVERRUN;
}else if(SDIO-STA(19)) //接收起始位错误
{ SDIO-ICR|19; //清错误标志
return SD_START_BIT_ERR;
}
while(SDIO-STA(121)) //FIFO里面,还存在可用数据
{
*tempbuffSDIO-FIFO; //循环读取数据
tempbuff;
} if(SDIO-STA(18)) //接收结束
{
if((SDIO_STD_CAPACITY_SD_CARD_V1_1CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0CardType)||(SDIO_HIGH_CAPACITY_SD_CARDCardType))
{
SDIO_SendCmd(SD_CMD_STOP_TRANSMISSION,1,0); //发送CMD12结束传输
errorstatusSDIO_CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//等待R1响应
if(errorstatus!SD_OK)return errorstatus;
} }
// INTX_ENABLE();//开启总中断 SDIO-ICR0X5FF; //清除所有标记 } else if(DeviceModeSD_DMA_MODE)
{ SDIO_SdCard_DMAConfig((u32*)buf,nblks*blksize,0); TransferErrorSD_OK;
StopCondition1; //多块读,需要发送停止传输指令
TransferEnd0; //传输结束标置位在中断服务置1
SDIO-MASK|(11)|(13)|(18)|(15)|(19); //配置需要的中断 SDIO-DCTRL|13; //SDIO DMA使能 while(((DMA2-ISR0X2000)RESET)timeout)timeout--;//等待传输完成
if(timeout0)return SD_DATA_TIMEOUT;//超时
while((TransferEnd0)(TransferErrorSD_OK));
if(TransferError!SD_OK)errorstatusTransferError;
} }
return errorstatus;
} /*
函数功能:SD卡写1个块
函数参数: buf:数据缓存区 addr:写地址 blksize:块大小
返回值:错误状态
*/
SDIO_SD_ERROR_INFO SDIO_SdCardWriteBlock(u8 *buf,long long addr, u16 blksize)
{
SDIO_SD_ERROR_INFO errorstatus SD_OK;
u8 power0,cardstate0;
u32 timeout0,bytestransferred0;
u32 cardstatus0,count0,restwords0;
u32 tlenblksize; //总长度(字节)
u32*tempbuff(u32*)buf; if(bufNULL)return SD_INVALID_PARAMETER;//参数错误 SDIO-DCTRL0x0; //数据控制寄存器清零(关DMA) SDIO_SendDataConfig(SD_DATATIMEOUT,0,0,0); //清除DPSM状态机配置
if(SDIO-RESP1SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了 if(CardTypeSDIO_HIGH_CAPACITY_SD_CARD) //大容量卡
{
blksize512;
addr9;
}
if((blksize0)(blksize2048)((blksize(blksize-1))0))
{
powerconvert_from_bytes_to_power_of_two(blksize);
SDIO_SendCmd(SD_CMD_SET_BLOCKLEN,1,blksize); //发送CMD16设置数据长度为blksize,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应
if(errorstatus!SD_OK)return errorstatus; //响应错误
}else return SD_INVALID_PARAMETER; SDIO_SendCmd(SD_CMD_SEND_STATUS,1,(u32)RCA16); //发送CMD13,查询卡的状态,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_SEND_STATUS); //等待R1响应
if(errorstatus!SD_OK)return errorstatus;
cardstatusSDIO-RESP1;
timeoutSD_DATATIMEOUT; while(((cardstatus0x00000100)0)(timeout0)) //检查READY_FOR_DATA位是否置位
{
timeout--; SDIO_SendCmd(SD_CMD_SEND_STATUS,1,(u32)RCA16);//发送CMD13,查询卡的状态,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_SEND_STATUS); //等待R1响应
if(errorstatus!SD_OK)return errorstatus;
cardstatusSDIO-RESP1;
}
if(timeout0)return SD_ERROR; SDIO_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK,1,addr); //发送CMD24,写单块指令,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_WRITE_SINGLE_BLOCK);//等待R1响应
if(errorstatus!SD_OK)return errorstatus;
StopCondition0; //单块写,不需要发送停止传输指令 SDIO_SendDataConfig(SD_DATATIMEOUT,blksize,power,0); //blksize, 控制器到卡
timeoutSDIO_DATATIMEOUT;
if(DeviceMode SD_POLLING_MODE)
{
// INTX_DISABLE();//关闭总中断(POLLING模式,严禁中断打断SDIO读写操作!!!)
while(!(SDIO-STA((110)|(14)|(11)|(13)|(19))))//数据块发送成功/下溢/CRC/超时/起始位错误
{
if(SDIO-STA(114)) //发送区半空,表示至少存了8个字
{
if((tlen-bytestransferred)SD_HALFFIFOBYTES)//不够32字节了
{
restwords((tlen-bytestransferred)%40)?((tlen-bytestransferred)/4):((tlen-bytestransferred)/41); for(count0;countrestwords;count,tempbuff,bytestransferred4)
{
SDIO-FIFO*tempbuff;
}
}else
{
for(count0;count8;count)
{
SDIO-FIFO*(tempbuffcount);
}
tempbuff8;
bytestransferred32;
}
timeout0X3FFFFFFF; //写数据溢出时间
}else
{
if(timeout0)return SD_DATA_TIMEOUT;
timeout--;
}
}
if(SDIO-STA(13)) //数据超时错误
{ SDIO-ICR|13; //清错误标志
return SD_DATA_TIMEOUT; }else if(SDIO-STA(11)) //数据块CRC错误
{ SDIO-ICR|11; //清错误标志
return SD_DATA_CRC_FAIL;
}else if(SDIO-STA(14)) //接收fifo下溢错误
{ SDIO-ICR|14; //清错误标志
return SD_TX_UNDERRUN;
}else if(SDIO-STA(19)) //接收起始位错误
{ SDIO-ICR|19; //清错误标志
return SD_START_BIT_ERR;
}
// INTX_ENABLE();//开启总中断
SDIO-ICR0X5FF; //清除所有标记
}else if(DeviceModeSD_DMA_MODE)
{
SDIO_SdCard_DMAConfig((u32*)buf,blksize,1);//SDIO DMA配置 TransferErrorSD_OK;
StopCondition0; //单块写,不需要发送停止传输指令
TransferEnd0; //传输结束标置位在中断服务置1
SDIO-MASK|(11)|(13)|(18)|(14)|(19); //配置产生数据接收完成中断 SDIO-DCTRL|13; //SDIO DMA使能. while(((DMA2-ISR0X2000)RESET)timeout)timeout--;//等待传输完成
if(timeout0)
{ SDIO_SdCardInit(); //重新初始化SD卡,可以解决写入死机的问题
return SD_DATA_TIMEOUT; //超时 }
timeoutSDIO_DATATIMEOUT;
while((TransferEnd0)(TransferErrorSD_OK)timeout)timeout--; if(timeout0)return SD_DATA_TIMEOUT; //超时 if(TransferError!SD_OK)return TransferError; } SDIO-ICR0X5FF; //清除所有标记 errorstatusSDIO_SdCardProgrammingState(cardstate); while((errorstatusSD_OK)((cardstateSD_CARD_PROGRAMMING)||(cardstateSD_CARD_RECEIVING)))
{
errorstatusSDIO_SdCardProgrammingState(cardstate);
}
return errorstatus;
} /*
函数功能:SD卡写多个块
函数参数: buf:数据缓存区 addr:写地址 blksize:块大小 nblks:要写入的块数
返回值:错误状态
*/
SDIO_SD_ERROR_INFO SDIO_SdCardWriteMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks)
{
SDIO_SD_ERROR_INFO errorstatus SD_OK;
u8 power 0, cardstate 0;
u32 timeout0,bytestransferred0;
u32 count 0, restwords 0;
u32 tlennblks*blksize; //总长度(字节)
u32 *tempbuff (u32*)buf; if(bufNULL)return SD_INVALID_PARAMETER; //参数错误 SDIO-DCTRL0x0; //数据控制寄存器清零(关DMA) SDIO_SendDataConfig(SD_DATATIMEOUT,0,0,0); //清除DPSM状态机配置
if(SDIO-RESP1SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了 if(CardTypeSDIO_HIGH_CAPACITY_SD_CARD)//大容量卡
{
blksize512;
addr9;
}
if((blksize0)(blksize2048)((blksize(blksize-1))0))
{
powerconvert_from_bytes_to_power_of_two(blksize);
SDIO_SendCmd(SD_CMD_SET_BLOCKLEN,1,blksize); //发送CMD16设置数据长度为blksize,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_SET_BLOCKLEN); //等待R1响应
if(errorstatus!SD_OK)return errorstatus; //响应错误
}else return SD_INVALID_PARAMETER;
if(nblks1)
{
if(nblks*blksizeSD_MAX_DATA_LENGTH)return SD_INVALID_PARAMETER; if((SDIO_STD_CAPACITY_SD_CARD_V1_1CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0CardType)||(SDIO_HIGH_CAPACITY_SD_CARDCardType)) {
//提高性能 SDIO_SendCmd(SD_CMD_APP_CMD,1,(u32)RCA16); //发送ACMD55,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_APP_CMD); //等待R1响应
if(errorstatus!SD_OK)return errorstatus; SDIO_SendCmd(SD_CMD_SET_BLOCK_COUNT,1,nblks); //发送CMD23,设置块数量,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_SET_BLOCK_COUNT);//等待R1响应
if(errorstatus!SD_OK)return errorstatus;
}
SDIO_SendCmd(SD_CMD_WRITE_MULT_BLOCK,1,addr); //发送CMD25,多块写指令,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_WRITE_MULT_BLOCK); //等待R1响应
if(errorstatus!SD_OK)return errorstatus; SDIO_SendDataConfig(SD_DATATIMEOUT,nblks*blksize,power,0);//blksize, 控制器到卡
if(DeviceModeSD_POLLING_MODE) {
timeoutSDIO_DATATIMEOUT;
while(!(SDIO-STA((14)|(11)|(18)|(13)|(19))))//下溢/CRC/数据结束/超时/起始位错误
{
if(SDIO-STA(114)) //发送区半空,表示至少存了8字(32字节)
{
if((tlen-bytestransferred)SD_HALFFIFOBYTES)//不够32字节了
{
restwords((tlen-bytestransferred)%40)?((tlen-bytestransferred)/4):((tlen-bytestransferred)/41);
for(count0;countrestwords;count,tempbuff,bytestransferred4)
{
SDIO-FIFO*tempbuff;
}
}else //发送区半空,可以发送至少8字(32字节)数据
{
for(count0;countSD_HALFFIFO;count)
{
SDIO-FIFO*(tempbuffcount);
}
tempbuffSD_HALFFIFO;
bytestransferredSD_HALFFIFOBYTES;
}
timeout0X3FFFFFFF; //写数据溢出时间
}else
{
if(timeout0)return SD_DATA_TIMEOUT;
timeout--;
}
}
if(SDIO-STA(13)) //数据超时错误
{ SDIO-ICR|13; //清错误标志
return SD_DATA_TIMEOUT; }else if(SDIO-STA(11)) //数据块CRC错误
{ SDIO-ICR|11; //清错误标志
return SD_DATA_CRC_FAIL;
}else if(SDIO-STA(14)) //接收fifo下溢错误
{ SDIO-ICR|14; //清错误标志
return SD_TX_UNDERRUN;
}else if(SDIO-STA(19)) //接收起始位错误
{ SDIO-ICR|19; //清错误标志
return SD_START_BIT_ERR;
}
if(SDIO-STA(18)) //发送结束
{
if((SDIO_STD_CAPACITY_SD_CARD_V1_1CardType)||(SDIO_STD_CAPACITY_SD_CARD_V2_0CardType)||(SDIO_HIGH_CAPACITY_SD_CARDCardType))
{
SDIO_SendCmd(SD_CMD_STOP_TRANSMISSION,1,0); //发送CMD12结束传输
errorstatusSDIO_CmdResp1Error(SD_CMD_STOP_TRANSMISSION);//等待R1响应
if(errorstatus!SD_OK)return errorstatus;
}
}
// INTX_ENABLE();//开启总中断 SDIO-ICR0X5FF; //清除所有标记 } else if(DeviceModeSD_DMA_MODE) { SDIO_SdCard_DMAConfig((u32*)buf,nblks*blksize,1);//SDIO DMA配置 TransferErrorSD_OK; StopCondition1; //多块写,需要发送停止传输指令 TransferEnd0; //传输结束标置位在中断服务置1 SDIO-MASK|(11)|(13)|(18)|(14)|(19); //配置产生数据接收完成中断 SDIO-DCTRL|13; //SDIO DMA使能. timeoutSDIO_DATATIMEOUT; while(((DMA2-ISR0X2000)RESET)timeout)timeout--;//等待传输完成 if(timeout0) //超时 { SDIO_SdCardInit(); //重新初始化SD卡,可以解决写入死机的问题 return SD_DATA_TIMEOUT; //超时 } timeoutSDIO_DATATIMEOUT; while((TransferEnd0)(TransferErrorSD_OK)timeout)timeout--; if(timeout0)return SD_DATA_TIMEOUT; //超时 if(TransferError!SD_OK)return TransferError; } } SDIO-ICR0X5FF; //清除所有标记 errorstatusSDIO_SdCardProgrammingState(cardstate); while((errorstatusSD_OK)((cardstateSD_CARD_PROGRAMMING)||(cardstateSD_CARD_RECEIVING)))
{
errorstatusSDIO_SdCardProgrammingState(cardstate);
}
return errorstatus;
} /*
函数功能: SDIO中断服务函数
*/
void SDIO_IRQHandler(void)
{ SDIO_SdCardProcessIRQSrc();//处理所有SDIO相关中断
} /*
函数功能: SDIO中断处理函数
函数参数: 处理SDIO传输过程中的各种中断事务
返回值:错误代码
*/
SDIO_SD_ERROR_INFO SDIO_SdCardProcessIRQSrc(void)
{
if(SDIO-STA(18))//接收完成中断
{
if(StopCondition1)
{
SDIO_SendCmd(SD_CMD_STOP_TRANSMISSION,1,0); //发送CMD12,结束传输
TransferErrorSDIO_CmdResp1Error(SD_CMD_STOP_TRANSMISSION);
}else TransferError SD_OK; SDIO-ICR|18;//清除完成中断标记
SDIO-MASK~((11)|(13)|(18)|(114)|(115)|(14)|(15)|(19));//关闭相关中断 TransferEnd 1;
return(TransferError);
} if(SDIO-STA(11))//数据CRC错误
{
SDIO-ICR|11;//清除中断标记
SDIO-MASK~((11)|(13)|(18)|(114)|(115)|(14)|(15)|(19));//关闭相关中断 TransferError SD_DATA_CRC_FAIL; return(SD_DATA_CRC_FAIL);
} if(SDIO-STA(13))//数据超时错误
{
SDIO-ICR|13;//清除中断标记
SDIO-MASK~((11)|(13)|(18)|(114)|(115)|(14)|(15)|(19));//关闭相关中断 TransferError SD_DATA_TIMEOUT; return(SD_DATA_TIMEOUT);
} if(SDIO-STA(15))//FIFO上溢错误
{
SDIO-ICR|15;//清除中断标记
SDIO-MASK~((11)|(13)|(18)|(114)|(115)|(14)|(15)|(19));//关闭相关中断 TransferError SD_RX_OVERRUN; return(SD_RX_OVERRUN);
} if(SDIO-STA(14))//FIFO下溢错误
{
SDIO-ICR|14;//清除中断标记
SDIO-MASK~((11)|(13)|(18)|(114)|(115)|(14)|(15)|(19));//关闭相关中断 TransferError SD_TX_UNDERRUN; return(SD_TX_UNDERRUN);
}
if(SDIO-STA(19))//起始位错误
{
SDIO-ICR|19;//清除中断标记
SDIO-MASK~((11)|(13)|(18)|(114)|(115)|(14)|(15)|(19));//关闭相关中断 TransferError SD_START_BIT_ERR; return(SD_START_BIT_ERR);
}
return(SD_OK);
} /*
函数功能: 检查CMD0的执行状态
返回值: sd卡错误码
*/
SDIO_SD_ERROR_INFO SDIO_CmdErrorCheck(void)
{ SDIO_SD_ERROR_INFO errorstatus SD_OK; u32 timeoutSDIO_CMD0TIMEOUT; while(timeout--) { if(SDIO-STA(17))break; //命令已发送(无需响应) } if(timeout0)return SD_CMD_RSP_TIMEOUT; SDIO-ICR0X5FF; //清除标记 return errorstatus;
} /*
函数功能: 检查R7响应的错误状态
函数参数: 返回值:sd卡错误码
*/
SDIO_SD_ERROR_INFO SDIO_CmdResp7Error(void)
{
SDIO_SD_ERROR_INFO errorstatusSD_OK;
u32 status;
u32 timeoutSDIO_CMD0TIMEOUT; while(timeout--)
{
statusSDIO-STA;
if(status((10)|(12)|(16)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)
} if((timeout0)||(status(12))) //响应超时
{
errorstatusSD_CMD_RSP_TIMEOUT; //当前卡不是2.0兼容卡,或者不支持设定的电压范围
SDIO-ICR|12; //清除命令响应超时标志
return errorstatus;
}
if(status16) //成功接收到响应
{
errorstatusSD_OK;
SDIO-ICR|16; //清除响应标志 }
return errorstatus;
} /*
函数功能:检查R1响应的错误状态
函数参数: cmd:当前命令
返回值:sd卡错误码
*/
SDIO_SD_ERROR_INFO SDIO_CmdResp1Error(u8 cmd)
{ u32 status; while(1) { statusSDIO-STA; if(status((10)|(12)|(16)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功) } if(status(12)) //响应超时 { SDIO-ICR12; //清除命令响应超时标志 return SD_CMD_RSP_TIMEOUT; } if(status(10)) //CRC错误 { SDIO-ICR10; //清除标志 return SD_CMD_CRC_FAIL; } if(SDIO-RESPCMD!cmd)return SD_ILLEGAL_CMD;//命令不匹配 SDIO-ICR0X5FF; //清除标记 return (SDIO_SD_ERROR_INFO)(SDIO-RESP1SD_OCR_ERRORBITS);//返回卡响应
} /*
函数功能: 检查R3响应的错误状态
返回值: 错误状态
*/
SDIO_SD_ERROR_INFO SDIO_CmdResp3Error(void)
{
u32 status; while(1)
{
statusSDIO-STA;
if(status((10)|(12)|(16)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)
} if(status(12)) //响应超时
{
SDIO-ICR|12; //清除命令响应超时标志
return SD_CMD_RSP_TIMEOUT;
} SDIO-ICR0X5FF; //清除标记 return SD_OK;
} /*
函数功能: 检查R2响应的错误状态
返回值:错误状态
*/
SDIO_SD_ERROR_INFO SDIO_CmdResp2Error(void)
{ SDIO_SD_ERROR_INFO errorstatusSD_OK; u32 status; u32 timeoutSDIO_CMD0TIMEOUT; while(timeout--) { statusSDIO-STA; if(status((10)|(12)|(16)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功) } if((timeout0)||(status(12))) //响应超时 { errorstatusSD_CMD_RSP_TIMEOUT; SDIO-ICR|12; //清除命令响应超时标志 return errorstatus; } if(status10) //CRC错误 { errorstatusSD_CMD_CRC_FAIL; SDIO-ICR|10; //清除响应标志 } SDIO-ICR0X5FF; //清除标记 return errorstatus;
} /*
函数功能: 检查R6响应的错误状态
函数参数: cmd:之前发送的命令 prca:卡返回的RCA地址
返回值:错误状态
*/
SDIO_SD_ERROR_INFO SDIO_CmdResp6Error(u8 cmd,u16*prca)
{
SDIO_SD_ERROR_INFO errorstatusSD_OK;
u32 status;
u32 rspr1; while(1)
{
statusSDIO-STA;
if(status((10)|(12)|(16)))break;//CRC错误/命令响应超时/已经收到响应(CRC校验成功)
}
if(status(12)) //响应超时
{ SDIO-ICR|12; //清除命令响应超时标志
return SD_CMD_RSP_TIMEOUT;
}
if(status10) //CRC错误
{
SDIO-ICR|10; //清除响应标志 return SD_CMD_CRC_FAIL;
}
if(SDIO-RESPCMD!cmd) //判断是否响应cmd命令
{ return SD_ILLEGAL_CMD;
}
SDIO-ICR0X5FF; //清除所有标记
rspr1SDIO-RESP1; //得到响应
if(SD_ALLZERO(rspr1(SD_R6_GENERAL_UNKNOWN_ERROR|SD_R6_ILLEGAL_CMD|SD_R6_COM_CRC_FAILED)))
{
*prca(u16)(rspr116); //右移16位得到,rca
return errorstatus;
} if(rspr1SD_R6_GENERAL_UNKNOWN_ERROR)return SD_GENERAL_UNKNOWN_ERROR; if(rspr1SD_R6_ILLEGAL_CMD)return SD_ILLEGAL_CMD; if(rspr1SD_R6_COM_CRC_FAILED)return SD_COM_CRC_FAILED;
return errorstatus;
} /*
函数功能:SDIO使能宽总线模式
函数参数: enx:0,不使能;1,使能;
返回值:错误状态
*/
SDIO_SD_ERROR_INFO SDIO_SdCardEnWideBus(u8 enx)
{
SDIO_SD_ERROR_INFO errorstatus SD_OK; u32 scr[2]{0,0};
u8 arg0X00;
if(enx)arg0X02;
else arg0X00; if(SDIO-RESP1SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//SD卡处于LOCKED状态 errorstatusSDIO_SdCardFindSCR(RCA,scr); //得到SCR寄存器数据 if(errorstatus!SD_OK)return errorstatus;
if((scr[1]SD_WIDE_BUS_SUPPORT)!SD_ALLZERO) //支持宽总线
{ SDIO_SendCmd(SD_CMD_APP_CMD,1,(u32)RCA16); //发送CMD55RCA,短响应 errorstatusSDIO_CmdResp1Error(SD_CMD_APP_CMD); if(errorstatus!SD_OK)return errorstatus; SDIO_SendCmd(SD_CMD_APP_SD_SET_BUSWIDTH,1,arg);//发送ACMD6,短响应,参数:10,4位;00,1位.
errorstatusSDIO_CmdResp1Error(SD_CMD_APP_SD_SET_BUSWIDTH);
return errorstatus;
}else return SD_REQUEST_NOT_APPLICABLE; //不支持宽总线设置
} /*
函数功能: 检查卡是否正在执行写操作
函数参数: pstatus:当前状态
返回值:错误代码
*/
SDIO_SD_ERROR_INFO SDIO_SdCardProgrammingState(u8 *pstatus)
{ vu32 respR1 0, status 0; SDIO_SendCmd(SD_CMD_SEND_STATUS,1,(u32)RCA16); //发送CMD13 statusSDIO-STA;
while(!(status((10)|(16)|(12))))statusSDIO-STA;//等待操作完成 if(status(10)) //CRC检测失败
{
SDIO-ICR|10; //清除错误标记
return SD_CMD_CRC_FAIL;
} if(status(12)) //命令超时
{
SDIO-ICR|12; //清除错误标记
return SD_CMD_RSP_TIMEOUT;
} if(SDIO-RESPCMD!SD_CMD_SEND_STATUS)return SD_ILLEGAL_CMD;
SDIO-ICR0X5FF; //清除所有标记
respR1SDIO-RESP1;
*pstatus(u8)((respR19)0x0000000F);
return SD_OK;
} /*
函数功能: 读取当前卡状态
函数参数: pcardstatus:卡状态
返回值 :错误代码
*/
SDIO_SD_ERROR_INFO SDIO_SdCardSendStatus(uint32_t *pcardstatus)
{
SDIO_SD_ERROR_INFO errorstatus SD_OK;
if(pcardstatusNULL)
{
errorstatusSD_INVALID_PARAMETER;
return errorstatus;
} SDIO_SendCmd(SD_CMD_SEND_STATUS,1,RCA16); //发送CMD13,短响应
errorstatusSDIO_CmdResp1Error(SD_CMD_SEND_STATUS); //查询响应状态
if(errorstatus!SD_OK)return errorstatus;
*pcardstatusSDIO-RESP1;//读取响应值
return errorstatus;
} /*
函数功能: 返回SD卡的状态
返回值 : SD卡状态
*/
SDCardState SDIO_SdCardGetState(void)
{
u32 resp10;
if(SDIO_SdCardSendStatus(resp1)!SD_OK)return SD_CARD_ERROR;
else return (SDCardState)((resp19) 0x0F);
} /*
函数功能:查找SD卡的SCR寄存器值
函数参数: rca:卡相对地址 pscr:数据缓存区(存储SCR内容)
返回值:错误状态
*/
SDIO_SD_ERROR_INFO SDIO_SdCardFindSCR(u16 rca,u32 *pscr)
{
u32 index 0;
SDIO_SD_ERROR_INFO errorstatus SD_OK;
u32 tempscr[2]{0,0}; SDIO_SendCmd(SD_CMD_SET_BLOCKLEN,1,8); //发送CMD16,短响应,设置Block Size为8字节 errorstatusSDIO_CmdResp1Error(SD_CMD_SET_BLOCKLEN); if(errorstatus!SD_OK)return errorstatus; SDIO_SendCmd(SD_CMD_APP_CMD,1,(u32)rca16); //发送CMD55,短响应 errorstatusSDIO_CmdResp1Error(SD_CMD_APP_CMD); if(errorstatus!SD_OK)return errorstatus;
SDIO_SendDataConfig(SD_DATATIMEOUT,8,3,1); //8个字节长度,block为8字节,SD卡到SDIO. SDIO_SendCmd(SD_CMD_SD_APP_SEND_SCR,1,0); //发送ACMD51,短响应,参数为0 errorstatusSDIO_CmdResp1Error(SD_CMD_SD_APP_SEND_SCR); if(errorstatus!SD_OK)return errorstatus; while(!(SDIO-STA(SDIO_FLAG_RXOVERR|SDIO_FLAG_DCRCFAIL|SDIO_FLAG_DTIMEOUT|SDIO_FLAG_DBCKEND|SDIO_FLAG_STBITERR)))
{
if(SDIO-STA(121))//接收FIFO数据可用
{
*(tempscrindex)SDIO-FIFO; //读取FIFO内容
index;
if(index2)break;
}
} if(SDIO-STA(13)) //接收数据超时
{ SDIO-ICR|13; //清除标记
return SD_DATA_TIMEOUT;
}
else if(SDIO-STA(11)) //已发送/接收的数据块CRC校验错误
{ SDIO-ICR|11; //清除标记
return SD_DATA_CRC_FAIL;
}
else if(SDIO-STA(15)) //接收FIFO溢出
{ SDIO-ICR|15; //清除标记
return SD_RX_OVERRUN;
}
else if(SDIO-STA(19)) //起始位检测错误
{ SDIO-ICR|19; //清除标记
return SD_START_BIT_ERR;
} SDIO-ICR0X5FF; //清除标记
//把数据顺序按8位为单位倒过来.
*(pscr1)((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;
} /*
函数功能: 得到NumberOfBytes以2为底的指数
函数参数: NumberOfBytes:字节数
返回值:以2为底的指数值
*/
u8 convert_from_bytes_to_power_of_two(u16 NumberOfBytes)
{
u8 count0;
while(NumberOfBytes!1)
{
NumberOfBytes1;
count;
}
return count;
} /*
函数功能: 配置SDIO DMA
函数参数: mbuf:存储器地址 bufsize:传输数据量 dir:方向;1,存储器--SDIO(写数据);0,SDIO--存储器(读数据);
*/
void SDIO_SdCard_DMAConfig(u32*mbuf,u32 bufsize,u8 dir)
{ DMA2-IFCR|(0XF12); //清除DMA2通道4的各种标记 DMA2_Channel4-CCR~(10); //关闭DMA 通道4 DMA2_Channel4-CCR~(0X7FF4); //清除之前的设置,DIR,CIRC,PINC,MINC,PSIZE,MSIZE,PL,MEM2MEM DMA2_Channel4-CCR|dir4; //从存储器读
DMA2_Channel4-CCR|05; //普通模式
DMA2_Channel4-CCR|06; //外设地址非增量模式
DMA2_Channel4-CCR|17; //存储器增量模式
DMA2_Channel4-CCR|28; //外设数据宽度为32位
DMA2_Channel4-CCR|210; //存储器数据宽度32位
DMA2_Channel4-CCR|212; //高优先级 DMA2_Channel4-CNDTRbufsize/4; //DMA2,传输数据量 DMA2_Channel4-CPAR(u32)SDIO-FIFO;//DMA2 外设地址
DMA2_Channel4-CMAR(u32)mbuf; //DMA2,存储器地址 DMA2_Channel4-CCR|10; //开启DMA通道
} /*
函数功能: 读SD卡
函数参数: buf:读数据缓存区 sector:扇区地址 cnt:扇区个数
返回值:错误状态;0,正常;其他,错误代码;
*/
u8 SDIO_SdCardReadDiskSector(u8*buf,u32 sector,u8 cnt)
{
u8 staSD_OK;
long long lsectorsector;
u8 n;
lsector9;
if((u32)buf%4!0)
{ for(n0;ncnt;n)
{ staSDIO_SdCardReadBlock(SDIO_DATA_BUFFER,lsector512*n,512);//单个sector的读操作
memcpy(buf,SDIO_DATA_BUFFER,512);
buf512;
}
}else
{
if(cnt1)staSDIO_SdCardReadBlock(buf,lsector,512); //单个sector的读操作
else staSDIO_SdCardReadMultiBlocks(buf,lsector,512,cnt);//多个sector
}
return sta;
} /*
函数功能:写SD卡
函数参数: buf:写数据缓存区 sector:扇区地址 cnt:扇区个数
返回值:错误状态;0,正常;其他,错误代码;
*/
u8 SDIO_SdCardWriteDiskSector(u8*buf,u32 sector,u8 cnt)
{
u8 staSD_OK;
u8 n;
long long lsectorsector;
lsector9;
if((u32)buf%4!0)
{ for(n0;ncnt;n)
{
memcpy(SDIO_DATA_BUFFER,buf,512); staSDIO_SdCardWriteBlock(SDIO_DATA_BUFFER,lsector512*n,512);//单个sector的写操作
buf512;
}
}else
{
if(cnt1)staSDIO_SdCardWriteBlock(buf,lsector,512); //单个sector的写操作
else staSDIO_SdCardWriteMultiBlocks(buf,lsector,512,cnt); //多个sector
}
return sta;
} 3sdio.h
#ifndef __SDIO_SDCARD_H
#define __SDIO_SDCARD_H
#include stm32f10x.h //SDIO相关标志位
#define SDIO_FLAG_CCRCFAIL ((uint32_t)0x00000001)
#define SDIO_FLAG_DCRCFAIL ((uint32_t)0x00000002)
#define SDIO_FLAG_CTIMEOUT ((uint32_t)0x00000004)
#define SDIO_FLAG_DTIMEOUT ((uint32_t)0x00000008)
#define SDIO_FLAG_TXUNDERR ((uint32_t)0x00000010)
#define SDIO_FLAG_RXOVERR ((uint32_t)0x00000020)
#define SDIO_FLAG_CMDREND ((uint32_t)0x00000040)
#define SDIO_FLAG_CMDSENT ((uint32_t)0x00000080)
#define SDIO_FLAG_DATAEND ((uint32_t)0x00000100)
#define SDIO_FLAG_STBITERR ((uint32_t)0x00000200)
#define SDIO_FLAG_DBCKEND ((uint32_t)0x00000400)
#define SDIO_FLAG_CMDACT ((uint32_t)0x00000800)
#define SDIO_FLAG_TXACT ((uint32_t)0x00001000)
#define SDIO_FLAG_RXACT ((uint32_t)0x00002000)
#define SDIO_FLAG_TXFIFOHE ((uint32_t)0x00004000)
#define SDIO_FLAG_RXFIFOHF ((uint32_t)0x00008000)
#define SDIO_FLAG_TXFIFOF ((uint32_t)0x00010000)
#define SDIO_FLAG_RXFIFOF ((uint32_t)0x00020000)
#define SDIO_FLAG_TXFIFOE ((uint32_t)0x00040000)
#define SDIO_FLAG_RXFIFOE ((uint32_t)0x00080000)
#define SDIO_FLAG_TXDAVL ((uint32_t)0x00100000)
#define SDIO_FLAG_RXDAVL ((uint32_t)0x00200000)
#define SDIO_FLAG_SDIOIT ((uint32_t)0x00400000)
#define SDIO_FLAG_CEATAEND ((uint32_t)0x00800000) //用户配置区
//SDIO时钟计算公式:SDIO_CK时钟SDIOCLK/[clkdiv2];其中,SDIOCLK一般为72Mhz
//使用DMA模式的时候,传输速率可以到24Mhz,不过如果你的卡不是高速卡,可能也会出错
//出错就请降低时钟,使用查询模式的话,推荐SDIO_TRANSFER_CLK_DIV设置为3或者更大
#define SDIO_INIT_CLK_DIV 0xB2 //SDIO初始化频率最大400Kh
#define SDIO_TRANSFER_CLK_DIV 0x04 //SDIO传输频率,该值太小可能会导致读写文件出错 //SDIO工作模式定义,通过SDIO_SdCardSetDeviceMode函数设置.
#define SD_POLLING_MODE 0 //查询模式,该模式下,如果读写有问题,建议增大SDIO_TRANSFER_CLK_DIV的设置.
#define SD_DMA_MODE 1 //DMA模式,该模式下,如果读写有问题,建议增大SDIO_TRANSFER_CLK_DIV的设置. //SDIO 各种错误枚举定义
typedef enum
{
//特殊错误定义
SD_CMD_CRC_FAIL (1), /*! Command response received (but CRC check failed) */
SD_DATA_CRC_FAIL (2), /*! Data bock sent/received (CRC check Failed) */
SD_CMD_RSP_TIMEOUT (3), /*! Command response timeout */
SD_DATA_TIMEOUT (4), /*! Data time out */
SD_TX_UNDERRUN (5), /*! Transmit FIFO under-run */
SD_RX_OVERRUN (6), /*! Receive FIFO over-run */
SD_START_BIT_ERR (7), /*! Start bit not detected on all data signals in widE bus mode */
SD_CMD_OUT_OF_RANGE (8), /*! CMDs argument was out of range.*/
SD_ADDR_MISALIGNED (9), /*! Misaligned address */
SD_BLOCK_LEN_ERR (10), /*! Transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */
SD_ERASE_SEQ_ERR (11), /*! An error in the sequence of erase command occurs.*/
SD_BAD_ERASE_PARAM (12), /*! An Invalid selection for erase groups */
SD_WRITE_PROT_VIOLATION (13), /*! Attempt to program a write protect block */
SD_LOCK_UNLOCK_FAILED (14), /*! Sequence or password error has been detected in unlock command or if there was an attempt to access a locked card */
SD_COM_CRC_FAILED (15), /*! CRC check of the previous command failed */
SD_ILLEGAL_CMD (16), /*! Command is not legal for the card state */
SD_CARD_ECC_FAILED (17), /*! Card internal ECC was applied but failed to correct the data */
SD_CC_ERROR (18), /*! Internal card controller error */
SD_GENERAL_UNKNOWN_ERROR (19), /*! General or Unknown error */
SD_STREAM_READ_UNDERRUN (20), /*! The card could not sustain data transfer in stream read operation. */
SD_STREAM_WRITE_OVERRUN (21), /*! The card could not sustain data programming in stream mode */
SD_CID_CSD_OVERWRITE (22), /*! CID/CSD overwrite error */
SD_WP_ERASE_SKIP (23), /*! only partial address space was erased */
SD_CARD_ECC_DISABLED (24), /*! Command has been executed without using internal ECC */
SD_ERASE_RESET (25), /*! Erase sequence was cleared before executing because an out of erase sequence command was received */
SD_AKE_SEQ_ERROR (26), /*! Error in sequence of authentication. */
SD_INVALID_VOLTRANGE (27),
SD_ADDR_OUT_OF_RANGE (28),
SD_SWITCH_ERROR (29),
SD_SDIO_DISABLED (30),
SD_SDIO_FUNCTION_BUSY (31),
SD_SDIO_FUNCTION_FAILED (32),
SD_SDIO_UNKNOWN_FUNCTION (33),
//标准错误定义
SD_INTERNAL_ERROR,
SD_NOT_CONFIGURED,
SD_REQUEST_PENDING,
SD_REQUEST_NOT_APPLICABLE,
SD_INVALID_PARAMETER,
SD_UNSUPPORTED_FEATURE,
SD_UNSUPPORTED_HW,
SD_ERROR,
SD_OK 0
} SDIO_SD_ERROR_INFO; //SD卡CSD寄存器数据
typedef struct
{
u8 CSDStruct; /*! CSD structure */
u8 SysSpecVersion; /*! System specification version */
u8 Reserved1; /*! Reserved */
u8 TAAC; /*! Data read access-time 1 */
u8 NSAC; /*! Data read access-time 2 in CLK cycles */
u8 MaxBusClkFrec; /*! Max. bus clock frequency */
u16 CardComdClasses; /*! Card command classes */
u8 RdBlockLen; /*! Max. read data block length */
u8 PartBlockRead; /*! Partial blocks for read allowed */
u8 WrBlockMisalign; /*! Write block misalignment */
u8 RdBlockMisalign; /*! Read block misalignment */
u8 DSRImpl; /*! DSR implemented */
u8 Reserved2; /*! Reserved */
u32 DeviceSize; /*! Device Size */
u8 MaxRdCurrentVDDMin; /*! Max. read current VDD min */
u8 MaxRdCurrentVDDMax; /*! Max. read current VDD max */
u8 MaxWrCurrentVDDMin; /*! Max. write current VDD min */
u8 MaxWrCurrentVDDMax; /*! Max. write current VDD max */
u8 DeviceSizeMul; /*! Device size multiplier */
u8 EraseGrSize; /*! Erase group size */
u8 EraseGrMul; /*! Erase group size multiplier */
u8 WrProtectGrSize; /*! Write protect group size */
u8 WrProtectGrEnable; /*! Write protect group enable */
u8 ManDeflECC; /*! Manufacturer default ECC */
u8 WrSpeedFact; /*! Write speed factor */
u8 MaxWrBlockLen; /*! Max. write data block length */
u8 WriteBlockPaPartial; /*! Partial blocks for write allowed */
u8 Reserved3; /*! Reserded */
u8 ContentProtectAppli; /*! Content protection application */
u8 FileFormatGrouop; /*! File format group */
u8 CopyFlag; /*! Copy flag (OTP) */
u8 PermWrProtect; /*! Permanent write protection */
u8 TempWrProtect; /*! Temporary write protection */
u8 FileFormat; /*! File Format */
u8 ECC; /*! ECC code */
u8 CSD_CRC; /*! CSD CRC */
u8 Reserved4; /*! always 1*/
} SD_CSD; //SD卡CID寄存器数据
typedef struct
{
u8 ManufacturerID; /*! ManufacturerID */
u16 OEM_AppliID; /*! OEM/Application ID */
u32 ProdName1; /*! Product Name part1 */
u8 ProdName2; /*! Product Name part2*/
u8 ProdRev; /*! Product Revision */
u32 ProdSN; /*! Product Serial Number */
u8 Reserved1; /*! Reserved1 */
u16 ManufactDate; /*! Manufacturing Date */
u8 CID_CRC; /*! CID CRC */
u8 Reserved2; /*! always 1 */
} SD_CID; //SD卡状态
typedef enum
{
SD_CARD_READY ((uint32_t)0x00000001),
SD_CARD_IDENTIFICATION ((uint32_t)0x00000002),
SD_CARD_STANDBY ((uint32_t)0x00000003),
SD_CARD_TRANSFER ((uint32_t)0x00000004),
SD_CARD_SENDING ((uint32_t)0x00000005),
SD_CARD_RECEIVING ((uint32_t)0x00000006),
SD_CARD_PROGRAMMING ((uint32_t)0x00000007),
SD_CARD_DISCONNECTED ((uint32_t)0x00000008),
SD_CARD_ERROR ((uint32_t)0x000000FF)
}SDCardState; //SD卡信息,包括CSD,CID等数据
typedef struct
{ SD_CSD SD_csd; SD_CID SD_cid; long long CardCapacity; //SD卡容量,单位:字节,最大支持2^64字节大小的卡. u32 CardBlockSize; //SD卡块大小 u16 RCA; //卡相对地址 u8 CardType; //卡类型
} SD_CardInfo;
extern SD_CardInfo SDCardInfo;//SD卡信息 //SDIO 指令集
#define SD_CMD_GO_IDLE_STATE ((u8)0)
#define SD_CMD_SEND_OP_COND ((u8)1)
#define SD_CMD_ALL_SEND_CID ((u8)2)
#define SD_CMD_SET_REL_ADDR ((u8)3) /*! SDIO_SEND_REL_ADDR for SD Card */
#define SD_CMD_SET_DSR ((u8)4)
#define SD_CMD_SDIO_SEN_OP_COND ((u8)5)
#define SD_CMD_HS_SWITCH ((u8)6)
#define SD_CMD_SEL_DESEL_CARD ((u8)7)
#define SD_CMD_HS_SEND_EXT_CSD ((u8)8)
#define SD_CMD_SEND_CSD ((u8)9)
#define SD_CMD_SEND_CID ((u8)10)
#define SD_CMD_READ_DAT_UNTIL_STOP ((u8)11) /*! SD Card doesnt support it */
#define SD_CMD_STOP_TRANSMISSION ((u8)12)
#define SD_CMD_SEND_STATUS ((u8)13)
#define SD_CMD_HS_BUSTEST_READ ((u8)14)
#define SD_CMD_GO_INACTIVE_STATE ((u8)15)
#define SD_CMD_SET_BLOCKLEN ((u8)16)
#define SD_CMD_READ_SINGLE_BLOCK ((u8)17)
#define SD_CMD_READ_MULT_BLOCK ((u8)18)
#define SD_CMD_HS_BUSTEST_WRITE ((u8)19)
#define SD_CMD_WRITE_DAT_UNTIL_STOP ((u8)20)
#define SD_CMD_SET_BLOCK_COUNT ((u8)23)
#define SD_CMD_WRITE_SINGLE_BLOCK ((u8)24)
#define SD_CMD_WRITE_MULT_BLOCK ((u8)25)
#define SD_CMD_PROG_CID ((u8)26)
#define SD_CMD_PROG_CSD ((u8)27)
#define SD_CMD_SET_WRITE_PROT ((u8)28)
#define SD_CMD_CLR_WRITE_PROT ((u8)29)
#define SD_CMD_SEND_WRITE_PROT ((u8)30)
#define SD_CMD_SD_ERASE_GRP_START ((u8)32) /*! To set the address of the first write block to be erased. (For SD card only) */
#define SD_CMD_SD_ERASE_GRP_END ((u8)33) /*! To set the address of the last write block of the continuous range to be erased. (For SD card only) */
#define SD_CMD_ERASE_GRP_START ((u8)35) /*! To set the address of the first write block to be erased. (For MMC card only spec 3.31) */ #define SD_CMD_ERASE_GRP_END ((u8)36) /*! To set the address of the last write block of the continuous range to be erased. (For MMC card only spec 3.31) */ #define SD_CMD_ERASE ((u8)38)
#define SD_CMD_FAST_IO ((u8)39) /*! SD Card doesnt support it */
#define SD_CMD_GO_IRQ_STATE ((u8)40) /*! SD Card doesnt support it */
#define SD_CMD_LOCK_UNLOCK ((u8)42)
#define SD_CMD_APP_CMD ((u8)55)
#define SD_CMD_GEN_CMD ((u8)56)
#define SD_CMD_NO_CMD ((u8)64) /** * brief Following commands are SD Card Specific commands. * SDIO_APP_CMD CMD55 should be sent before sending these commands. */
#define SD_CMD_APP_SD_SET_BUSWIDTH ((u8)6) /*! For SD Card only */
#define SD_CMD_SD_APP_STAUS ((u8)13) /*! For SD Card only */
#define SD_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((u8)22) /*! For SD Card only */
#define SD_CMD_SD_APP_OP_COND ((u8)41) /*! For SD Card only */
#define SD_CMD_SD_APP_SET_CLR_CARD_DETECT ((u8)42) /*! For SD Card only */
#define SD_CMD_SD_APP_SEND_SCR ((u8)51) /*! For SD Card only */
#define SD_CMD_SDIO_RW_DIRECT ((u8)52) /*! For SD I/O Card only */
#define SD_CMD_SDIO_RW_EXTENDED ((u8)53) /*! For SD I/O Card only */ /** * brief Following commands are SD Card Specific security commands. * SDIO_APP_CMD should be sent before sending these commands. */
#define SD_CMD_SD_APP_GET_MKB ((u8)43) /*! For SD Card only */
#define SD_CMD_SD_APP_GET_MID ((u8)44) /*! For SD Card only */
#define SD_CMD_SD_APP_SET_CER_RN1 ((u8)45) /*! For SD Card only */
#define SD_CMD_SD_APP_GET_CER_RN2 ((u8)46) /*! For SD Card only */
#define SD_CMD_SD_APP_SET_CER_RES2 ((u8)47) /*! For SD Card only */
#define SD_CMD_SD_APP_GET_CER_RES1 ((u8)48) /*! For SD Card only */
#define SD_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((u8)18) /*! For SD Card only */
#define SD_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((u8)25) /*! For SD Card only */
#define SD_CMD_SD_APP_SECURE_ERASE ((u8)38) /*! For SD Card only */
#define SD_CMD_SD_APP_CHANGE_SECURE_AREA ((u8)49) /*! For SD Card only */
#define SD_CMD_SD_APP_SECURE_WRITE_MKB ((u8)48) /*! For SD Card only */ //支持的SD卡定义
#define SDIO_STD_CAPACITY_SD_CARD_V1_1 ((u32)0x00000000)
#define SDIO_STD_CAPACITY_SD_CARD_V2_0 ((u32)0x00000001)
#define SDIO_HIGH_CAPACITY_SD_CARD ((u32)0x00000002)
#define SDIO_MULTIMEDIA_CARD ((u32)0x00000003)
#define SDIO_SECURE_DIGITAL_IO_CARD ((u32)0x00000004)
#define SDIO_HIGH_SPEED_MULTIMEDIA_CARD ((u32)0x00000005)
#define SDIO_SECURE_DIGITAL_IO_COMBO_CARD ((u32)0x00000006)
#define SDIO_HIGH_CAPACITY_MMC_CARD ((u32)0x00000007) //SDIO相关参数定义
#define NULL 0
#define SDIO_STATIC_FLAGS ((u32)0x000005FF)
#define SDIO_CMD0TIMEOUT ((u32)0x00010000)
#define SDIO_DATATIMEOUT ((u32)0xFFFFFFFF)
#define SDIO_FIFO_Address ((u32)0x40018080) //Mask for errors Card Status R1 (OCR Register)
#define SD_OCR_ADDR_OUT_OF_RANGE ((u32)0x80000000)
#define SD_OCR_ADDR_MISALIGNED ((u32)0x40000000)
#define SD_OCR_BLOCK_LEN_ERR ((u32)0x20000000)
#define SD_OCR_ERASE_SEQ_ERR ((u32)0x10000000)
#define SD_OCR_BAD_ERASE_PARAM ((u32)0x08000000)
#define SD_OCR_WRITE_PROT_VIOLATION ((u32)0x04000000)
#define SD_OCR_LOCK_UNLOCK_FAILED ((u32)0x01000000)
#define SD_OCR_COM_CRC_FAILED ((u32)0x00800000)
#define SD_OCR_ILLEGAL_CMD ((u32)0x00400000)
#define SD_OCR_CARD_ECC_FAILED ((u32)0x00200000)
#define SD_OCR_CC_ERROR ((u32)0x00100000)
#define SD_OCR_GENERAL_UNKNOWN_ERROR ((u32)0x00080000)
#define SD_OCR_STREAM_READ_UNDERRUN ((u32)0x00040000)
#define SD_OCR_STREAM_WRITE_OVERRUN ((u32)0x00020000)
#define SD_OCR_CID_CSD_OVERWRIETE ((u32)0x00010000)
#define SD_OCR_WP_ERASE_SKIP ((u32)0x00008000)
#define SD_OCR_CARD_ECC_DISABLED ((u32)0x00004000)
#define SD_OCR_ERASE_RESET ((u32)0x00002000)
#define SD_OCR_AKE_SEQ_ERROR ((u32)0x00000008)
#define SD_OCR_ERRORBITS ((u32)0xFDFFE008) //Masks for R6 Response
#define SD_R6_GENERAL_UNKNOWN_ERROR ((u32)0x00002000)
#define SD_R6_ILLEGAL_CMD ((u32)0x00004000)
#define SD_R6_COM_CRC_FAILED ((u32)0x00008000) #define SD_VOLTAGE_WINDOW_SD ((u32)0x80100000)
#define SD_HIGH_CAPACITY ((u32)0x40000000)
#define SD_STD_CAPACITY ((u32)0x00000000)
#define SD_CHECK_PATTERN ((u32)0x000001AA)
#define SD_VOLTAGE_WINDOW_MMC ((u32)0x80FF8000) #define SD_MAX_VOLT_TRIAL ((u32)0x0000FFFF)
#define SD_ALLZERO ((u32)0x00000000) #define SD_WIDE_BUS_SUPPORT ((u32)0x00040000)
#define SD_SINGLE_BUS_SUPPORT ((u32)0x00010000)
#define SD_CARD_LOCKED ((u32)0x02000000)
#define SD_CARD_PROGRAMMING ((u32)0x00000007)
#define SD_CARD_RECEIVING ((u32)0x00000006)
#define SD_DATATIMEOUT ((u32)0xFFFFFFFF)
#define SD_0TO7BITS ((u32)0x000000FF)
#define SD_8TO15BITS ((u32)0x0000FF00)
#define SD_16TO23BITS ((u32)0x00FF0000)
#define SD_24TO31BITS ((u32)0xFF000000)
#define SD_MAX_DATA_LENGTH ((u32)0x01FFFFFF) #define SD_HALFFIFO ((u32)0x00000008)
#define SD_HALFFIFOBYTES ((u32)0x00000020) //Command Class Supported
#define SD_CCCC_LOCK_UNLOCK ((u32)0x00000080)
#define SD_CCCC_WRITE_PROT ((u32)0x00000040)
#define SD_CCCC_ERASE ((u32)0x00000020) //CMD8指令
#define SDIO_SEND_IF_COND ((u32)0x00000008) //相关函数定义
SDIO_SD_ERROR_INFO SDIO_SdCardInit(void);
void SDIO_ClockSet(u8 clkdiv);
void SDIO_SendCmd(u8 cmdindex,u8 waitrsp,u32 arg);
void SDIO_SendDataConfig(u32 datatimeout,u32 datalen,u8 blksize,u8 dir);
SDIO_SD_ERROR_INFO SDIO_SdPowerON(void);
SDIO_SD_ERROR_INFO SD_PowerOFF(void);
SDIO_SD_ERROR_INFO SDIO_SdCardInitializeCards(void);
SDIO_SD_ERROR_INFO SDIO_SdCardGetInfo(SD_CardInfo *cardinfo);
SDIO_SD_ERROR_INFO SDIO_SdCardEnableWideBusOperation(u32 wmode);
SDIO_SD_ERROR_INFO SDIO_SdCardSetDeviceMode(u32 mode);
SDIO_SD_ERROR_INFO SDIO_SdCardSelectAddr(u32 addr);
SDIO_SD_ERROR_INFO SDIO_SdCardSendStatus(uint32_t *pcardstatus);
SDCardState SDIO_SdCardGetState(void);
SDIO_SD_ERROR_INFO SDIO_SdCardReadBlock(u8 *buf,long long addr,u16 blksize);
SDIO_SD_ERROR_INFO SDIO_SdCardReadMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks);
SDIO_SD_ERROR_INFO SDIO_SdCardWriteBlock(u8 *buf,long long addr, u16 blksize);
SDIO_SD_ERROR_INFO SDIO_SdCardWriteMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks);
SDIO_SD_ERROR_INFO SDIO_SdCardProcessIRQSrc(void);
SDIO_SD_ERROR_INFO SDIO_CmdErrorCheck(void);
SDIO_SD_ERROR_INFO SDIO_CmdResp7Error(void);
SDIO_SD_ERROR_INFO SDIO_CmdResp1Error(u8 cmd);
SDIO_SD_ERROR_INFO SDIO_CmdResp3Error(void);
SDIO_SD_ERROR_INFO SDIO_CmdResp2Error(void);
SDIO_SD_ERROR_INFO SDIO_CmdResp6Error(u8 cmd,u16*prca);
SDIO_SD_ERROR_INFO SDIO_SdCardEnWideBus(u8 enx);
SDIO_SD_ERROR_INFO SDIO_SdCardProgrammingState(u8 *pstatus);
SDIO_SD_ERROR_INFO SDIO_SdCardFindSCR(u16 rca,u32 *pscr);
u8 convert_from_bytes_to_power_of_two(u16 NumberOfBytes);
void SDIO_SdCard_DMAConfig(u32*mbuf,u32 bufsize,u8 dir);
u8 SDIO_SdCardReadDiskSector(u8*buf,u32 sector,u8 cnt); //读SD卡,fatfs/usb调用
u8 SDIO_SdCardWriteDiskSector(u8*buf,u32 sector,u8 cnt); //写SD卡,fatfs/usb调用
#endif