20260324
This commit is contained in:
360
IAPV1.1/Driver/spi/SPI_SD_driver.c
Normal file
360
IAPV1.1/Driver/spi/SPI_SD_driver.c
Normal file
@ -0,0 +1,360 @@
|
||||
/******************** (C) COPYRIGHT 2018 Designed by Captain *********************
|
||||
* <20>ļ<EFBFBD><C4BC><EFBFBD> <20><>main.c
|
||||
* <20><><EFBFBD><EFBFBD> : SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* ʵ<><CAB5>ƽ̨<C6BD><CCA8>STM32F105RBT6˫CAN<41><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>V2.0
|
||||
* <20><><EFBFBD>汾 <20><>ST3.5.0
|
||||
* ʱ<><CAB1> <20><>2018-9-23
|
||||
**********************************************************************************/
|
||||
|
||||
#include "SPI_SD_driver.h"
|
||||
#include "spi.h"
|
||||
|
||||
u8 SD_Type=0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SPIģ<49><C4A3><EFBFBD>ij<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>룬<EFBFBD><EBA3AC><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD>ģʽ<C4A3><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SD<53><44>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//<2F><>ֲʱ<D6B2><CAB1><EFBFBD>Ľӿ<C4BD>
|
||||
//data:Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
u8 SD_SPI_ReadWriteByte(u8 data)
|
||||
{
|
||||
return SPI2_ReadWriteByte(data);
|
||||
}
|
||||
//SD<53><44><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>,<2C><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
|
||||
void SD_SPI_SpeedLow(void)
|
||||
{
|
||||
SPI2_SetSpeed(SPI_BaudRatePrescaler_256);//<2F><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
||||
}
|
||||
//SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>,<2C><><EFBFBD>Ը<EFBFBD><D4B8><EFBFBD><EFBFBD><EFBFBD>
|
||||
void SD_SPI_SpeedHigh(void)
|
||||
{
|
||||
SPI2_SetSpeed(SPI_BaudRatePrescaler_2);//<2F><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
||||
}
|
||||
/**********************************************
|
||||
*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>void SPI_Configuration(void)
|
||||
*<2A><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*<2A><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*<2A><><EFBFBD><EFBFBD>ֵ <20><><EFBFBD><EFBFBD>
|
||||
*<2A><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>SPIģ<49><C4A3><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IO<49>ڵij<DAB5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
||||
**********************************************/
|
||||
|
||||
void SD_SPI_Init(void)
|
||||
{
|
||||
// GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//<2F><><EFBFBD><EFBFBD>
|
||||
// GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//<2F><><EFBFBD><EFBFBD>
|
||||
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;//ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
|
||||
// GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
//
|
||||
// GPIO_SetBits(GPIOC,GPIO_Pin_4);
|
||||
// GPIO_SetBits(GPIOA,GPIO_Pin_8);
|
||||
|
||||
SPI2_Init();
|
||||
//SPI1_Init();
|
||||
SPI2_SetSpeed(7);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//ȡ<><C8A1>ѡ<EFBFBD><D1A1>,<2C>ͷ<EFBFBD>SPI<50><49><EFBFBD><EFBFBD>
|
||||
void SD_DisSelect(void)
|
||||
{
|
||||
SD_CS_DISABLE() ;
|
||||
SD_SPI_ReadWriteByte(0xff);//<2F>ṩ<EFBFBD><E1B9A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8<EFBFBD><38>ʱ<EFBFBD><CAB1>
|
||||
}
|
||||
//ѡ<><D1A1>sd<73><64>,<2C><><EFBFBD>ҵȴ<D2B5><C8B4><EFBFBD><EFBFBD><D7BC>OK
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C>ɹ<EFBFBD>;1,ʧ<><CAA7>;
|
||||
u8 SD_Select(void)
|
||||
{
|
||||
SD_CS_ENABLE();
|
||||
if(SD_WaitReady()==0)return 0;//<2F>ȴ<EFBFBD><C8B4>ɹ<EFBFBD>
|
||||
SD_DisSelect();
|
||||
return 1;//<2F>ȴ<EFBFBD>ʧ<EFBFBD><CAA7>
|
||||
}
|
||||
//<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><D7BC><EFBFBD><EFBFBD>
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0,<><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;<3B><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
u8 SD_WaitReady(void)
|
||||
{
|
||||
u32 t=0;
|
||||
do
|
||||
{
|
||||
if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK
|
||||
t++;
|
||||
}while(t<0XFFFFFF);//<2F>ȴ<EFBFBD>
|
||||
return 1;
|
||||
}
|
||||
//<2F>ȴ<EFBFBD>SD<53><44><EFBFBD><EFBFBD>Ӧ
|
||||
//Response:Ҫ<>õ<EFBFBD><C3B5>Ļ<EFBFBD>Ӧֵ
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C>ɹ<EFBFBD><C9B9>õ<EFBFBD><C3B5>˸û<CBB8>Ӧֵ
|
||||
// <20><><EFBFBD><EFBFBD>,<2C>õ<EFBFBD><C3B5><EFBFBD>Ӧֵʧ<D6B5><CAA7>
|
||||
u8 SD_GetResponse(u8 Response)
|
||||
{
|
||||
u16 Count=0xFFFF;//<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>
|
||||
while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//<2F>ȴ<EFBFBD><C8B4>õ<EFBFBD>ȷ<D7BC>Ļ<EFBFBD>Ӧ
|
||||
if (Count==0)return MSD_RESPONSE_FAILURE;//<2F>õ<EFBFBD><C3B5><EFBFBD>Ӧʧ<D3A6><CAA7>
|
||||
else return MSD_RESPONSE_NO_ERROR;//<2F><>ȷ<EFBFBD><C8B7>Ӧ
|
||||
}
|
||||
//<2F><>sd<73><64><EFBFBD><EFBFBD>ȡһ<C8A1><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//buf:<3A><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
||||
//len:Ҫ<><D2AA>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>.
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C>ɹ<EFBFBD>;<3B><><EFBFBD><EFBFBD>,ʧ<><CAA7>;
|
||||
u8 SD_RecvData(u8*buf,u16 len)
|
||||
{
|
||||
if(SD_GetResponse(0xFE))return 1;//<2F>ȴ<EFBFBD>SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>0xFE
|
||||
while(len--)//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
*buf=SPI2_ReadWriteByte(0xFF);
|
||||
buf++;
|
||||
}
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>αCRC<52><43>dummy CRC<52><43>
|
||||
SD_SPI_ReadWriteByte(0xFF);
|
||||
SD_SPI_ReadWriteByte(0xFF);
|
||||
return 0;//<2F><>ȡ<EFBFBD>ɹ<EFBFBD>
|
||||
}
|
||||
//<2F><>sd<73><64>д<EFBFBD><D0B4>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD><DDB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 512<31>ֽ<EFBFBD>
|
||||
//buf:<3A><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
||||
//cmd:ָ<><D6B8>
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0,<2C>ɹ<EFBFBD>;<3B><><EFBFBD><EFBFBD>,ʧ<><CAA7>;
|
||||
u8 SD_SendBlock(u8*buf,u8 cmd)
|
||||
{
|
||||
u16 t;
|
||||
if(SD_WaitReady())return 1;//<2F>ȴ<EFBFBD><EFBFBD><D7BC>ʧЧ
|
||||
SD_SPI_ReadWriteByte(cmd);
|
||||
if(cmd!=0XFD)//<2F><><EFBFBD>ǽ<EFBFBD><C7BD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
{
|
||||
for(t=0;t<512;t++)SPI2_ReadWriteByte(buf[t]);//<2F><><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>,<2C><><EFBFBD>ٺ<EFBFBD><D9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||
SD_SPI_ReadWriteByte(0xFF);//<2F><><EFBFBD><EFBFBD>crc
|
||||
SD_SPI_ReadWriteByte(0xFF);
|
||||
t=SD_SPI_ReadWriteByte(0xFF);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ
|
||||
if((t&0x1F)!=0x05)return 2;//<2F><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
|
||||
}
|
||||
return 0;//д<><D0B4><EFBFBD>ɹ<EFBFBD>
|
||||
}
|
||||
|
||||
//<2F><>SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//<2F><><EFBFBD><EFBFBD>: u8 cmd <20><><EFBFBD><EFBFBD>
|
||||
// u32 arg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// u8 crc crcУ<63><D0A3>ֵ
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:SD<53><44><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD>Ӧ
|
||||
u8 SD_SendCmd(u8 cmd, u32 arg, u8 crc)
|
||||
{
|
||||
u8 r1;
|
||||
u8 Retry=0;
|
||||
SD_DisSelect();//ȡ<><C8A1><EFBFBD>ϴ<EFBFBD>Ƭѡ
|
||||
if(SD_Select())return 0XFF;//ƬѡʧЧ
|
||||
//<2F><><EFBFBD><EFBFBD>
|
||||
SD_SPI_ReadWriteByte(cmd | 0x40);//<2F>ֱ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
SD_SPI_ReadWriteByte(arg >> 24);
|
||||
SD_SPI_ReadWriteByte(arg >> 16);
|
||||
SD_SPI_ReadWriteByte(arg >> 8);
|
||||
SD_SPI_ReadWriteByte(arg);
|
||||
SD_SPI_ReadWriteByte(crc);
|
||||
if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
|
||||
//<2F>ȴ<EFBFBD><C8B4><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>˳<EFBFBD>
|
||||
Retry=0X1F;
|
||||
do
|
||||
{
|
||||
r1=SD_SPI_ReadWriteByte(0xFF);
|
||||
}while((r1&0X80) && Retry--);
|
||||
//<2F><><EFBFBD><EFBFBD>״ֵ̬
|
||||
return r1;
|
||||
}
|
||||
//<2F><>ȡSD<53><44><EFBFBD><EFBFBD>CID<49><44>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
//<2F><><EFBFBD><EFBFBD>: u8 *cid_data(<28><><EFBFBD><EFBFBD>CID<49><44><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD><EFBFBD>16Byte<74><65>
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0<><30>NO_ERR
|
||||
// 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
u8 SD_GetCID(u8 *cid_data)
|
||||
{
|
||||
u8 r1;
|
||||
//<2F><>CMD10<31><30><EFBFBD><EFBFBD><EEA3AC>CID
|
||||
r1=SD_SendCmd(CMD10,0,0x01);
|
||||
if(r1==0x00)
|
||||
{
|
||||
r1=SD_RecvData(cid_data,16);//<2F><><EFBFBD><EFBFBD>16<31><36><EFBFBD>ֽڵ<D6BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
|
||||
if(r1)return 1;
|
||||
else return 0;
|
||||
}
|
||||
//<2F><>ȡSD<53><44><EFBFBD><EFBFBD>CSD<53><44>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD><D9B6><EFBFBD>Ϣ
|
||||
//<2F><><EFBFBD><EFBFBD>:u8 *cid_data(<28><><EFBFBD><EFBFBD>CID<49><44><EFBFBD>ڴ棬<DAB4><E6A3AC><EFBFBD><EFBFBD>16Byte<74><65>
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0<><30>NO_ERR
|
||||
// 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
u8 SD_GetCSD(u8 *csd_data)
|
||||
{
|
||||
u8 r1;
|
||||
r1=SD_SendCmd(CMD9,0,0x01);//<2F><>CMD9<44><39><EFBFBD><EFBFBD><EEA3AC>CSD
|
||||
if(r1==0)
|
||||
{
|
||||
r1=SD_RecvData(csd_data, 16);//<2F><><EFBFBD><EFBFBD>16<31><36><EFBFBD>ֽڵ<D6BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
|
||||
if(r1)return 1;
|
||||
else return 0;
|
||||
}
|
||||
//<2F><>ȡSD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0<><30> ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD>:SD<53><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/512<31>ֽ<EFBFBD>)
|
||||
//ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>Ϊ512<31><32><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>512<31><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>.
|
||||
u32 SD_GetSectorCount(void)
|
||||
{
|
||||
u8 csd[16];
|
||||
u32 Capacity;
|
||||
u8 n;
|
||||
u16 csize;
|
||||
//ȡCSD<53><44>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><DABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0
|
||||
if(SD_GetCSD(csd)!=0) return 0;
|
||||
//<2F><><EFBFBD><EFBFBD>ΪSDHC<48><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>淽ʽ<E6B7BD><CABD><EFBFBD><EFBFBD>
|
||||
if((csd[0]&0xC0)==0x40) //V2.00<EFBFBD>Ŀ<EFBFBD>
|
||||
{
|
||||
csize = csd[9] + ((u16)csd[8] << 8) + 1;
|
||||
Capacity = (u32)csize << 10;//<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}else//V1.XX<58>Ŀ<EFBFBD>
|
||||
{
|
||||
n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
|
||||
csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1;
|
||||
Capacity= (u32)csize << (n - 9);//<2F>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
return Capacity;
|
||||
}
|
||||
//<2F><>ʼ<EFBFBD><CABC>SD<53><44>
|
||||
u8 SD_Initialize(void)
|
||||
{
|
||||
u8 r1; // <20><><EFBFBD><EFBFBD>SD<53><44><EFBFBD>ķ<EFBFBD><C4B7><EFBFBD>ֵ
|
||||
u16 retry; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||
u8 buf[4];
|
||||
u16 i;
|
||||
|
||||
SD_SPI_Init(); //<2F><>ʼ<EFBFBD><CABC>IO
|
||||
SD_SPI_SpeedLow(); //<2F><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
||||
for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>74<37><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
retry=20;
|
||||
do
|
||||
{
|
||||
r1=SD_SendCmd(CMD0,0,0x95);//<2F><><EFBFBD><EFBFBD>IDLE״̬
|
||||
}while((r1!=0X01) && retry--);
|
||||
SD_Type=0;//Ĭ<><C4AC><EFBFBD><EFBFBD>
|
||||
if(r1==0X01)
|
||||
{
|
||||
if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0
|
||||
{
|
||||
for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF); //Get trailing return value of R7 resp
|
||||
if(buf[2]==0X01&&buf[3]==0XAA)//<2F><><EFBFBD>Ƿ<EFBFBD>֧<EFBFBD><D6A7>2.7~3.6V
|
||||
{
|
||||
retry=0XFFFE;
|
||||
do
|
||||
{
|
||||
SD_SendCmd(CMD55,0,0X01); //<2F><><EFBFBD><EFBFBD>CMD55
|
||||
r1=SD_SendCmd(CMD41,0x40000000,0X01);//<2F><><EFBFBD><EFBFBD>CMD41
|
||||
}while(r1&&retry--);
|
||||
if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//<2F><><EFBFBD><EFBFBD>SD2.0<EFBFBD><EFBFBD><EFBFBD>汾<EFBFBD><EFBFBD>ʼ
|
||||
{
|
||||
for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//<2F>õ<EFBFBD>OCRֵ
|
||||
if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC; //<2F><><EFBFBD><EFBFBD>CCS
|
||||
else SD_Type=SD_TYPE_V2;
|
||||
}
|
||||
}
|
||||
}else//SD V1.x/ MMC V3
|
||||
{
|
||||
SD_SendCmd(CMD55,0,0X01); //<2F><><EFBFBD><EFBFBD>CMD55
|
||||
r1=SD_SendCmd(CMD41,0,0X01); //<2F><><EFBFBD><EFBFBD>CMD41
|
||||
if(r1<=1)
|
||||
{
|
||||
SD_Type=SD_TYPE_V1;
|
||||
retry=0XFFFE;
|
||||
do //<2F>ȴ<EFBFBD><C8B4>˳<EFBFBD>IDLEģʽ
|
||||
{
|
||||
SD_SendCmd(CMD55,0,0X01); //<2F><><EFBFBD><EFBFBD>CMD55
|
||||
r1=SD_SendCmd(CMD41,0,0X01);//<2F><><EFBFBD><EFBFBD>CMD41
|
||||
}while(r1&&retry--);
|
||||
}else
|
||||
{
|
||||
SD_Type=SD_TYPE_MMC;//MMC V3
|
||||
retry=0XFFFE;
|
||||
do //<2F>ȴ<EFBFBD><C8B4>˳<EFBFBD>IDLEģʽ
|
||||
{
|
||||
r1=SD_SendCmd(CMD1,0,0X01);//<2F><><EFBFBD><EFBFBD>CMD1
|
||||
}while(r1&&retry--);
|
||||
}
|
||||
if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//<2F><><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>
|
||||
}
|
||||
}
|
||||
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
|
||||
SD_SPI_SpeedHigh();//<2F><><EFBFBD><EFBFBD>
|
||||
if(SD_Type)return 0;
|
||||
else if(r1)return r1;
|
||||
return 0xaa;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
//<2F><>SD<53><44>
|
||||
//buf:<3A><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
||||
//sector:<3A><><EFBFBD><EFBFBD>
|
||||
//cnt:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0,ok;<3B><><EFBFBD><EFBFBD>,ʧ<><CAA7>.
|
||||
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
|
||||
{
|
||||
u8 r1;
|
||||
if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//ת<><D7AA>Ϊ<EFBFBD>ֽڵ<D6BD>ַ
|
||||
if(cnt==1)
|
||||
{
|
||||
r1=SD_SendCmd(CMD17,sector,0X01);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if(r1==0)//ָ<><EFBFBD>ͳɹ<CDB3>
|
||||
{
|
||||
r1=SD_RecvData(buf,512);//<2F><><EFBFBD><EFBFBD>512<31><32><EFBFBD>ֽ<EFBFBD>
|
||||
}
|
||||
}else
|
||||
{
|
||||
r1=SD_SendCmd(CMD18,sector,0X01);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
do
|
||||
{
|
||||
r1=SD_RecvData(buf,512);//<2F><><EFBFBD><EFBFBD>512<31><32><EFBFBD>ֽ<EFBFBD>
|
||||
buf+=512;
|
||||
}while(--cnt && r1==0);
|
||||
SD_SendCmd(CMD12,0,0X01); //<2F><><EFBFBD><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
|
||||
}
|
||||
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
|
||||
return r1;//
|
||||
}
|
||||
//дSD<53><44>
|
||||
//buf:<3A><><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD>
|
||||
//sector:<3A><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
||||
//cnt:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//<2F><><EFBFBD><EFBFBD>ֵ:0,ok;<3B><><EFBFBD><EFBFBD>,ʧ<><CAA7>.
|
||||
u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt)
|
||||
{
|
||||
u8 r1;
|
||||
if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//ת<><D7AA>Ϊ<EFBFBD>ֽڵ<D6BD>ַ
|
||||
if(cnt==1)
|
||||
{
|
||||
r1=SD_SendCmd(CMD24,sector,0X01);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if(r1==0)//ָ<><EFBFBD>ͳɹ<CDB3>
|
||||
{
|
||||
r1=SD_SendBlock(buf,0xFE);//д512<31><32><EFBFBD>ֽ<EFBFBD>
|
||||
}
|
||||
}else
|
||||
{
|
||||
if(SD_Type!=SD_TYPE_MMC)
|
||||
{
|
||||
SD_SendCmd(CMD55,0,0X01);
|
||||
SD_SendCmd(CMD23,cnt,0X01);//<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
||||
}
|
||||
r1=SD_SendCmd(CMD25,sector,0X01);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
if(r1==0)
|
||||
{
|
||||
do
|
||||
{
|
||||
r1=SD_SendBlock(buf,0xFC);//<2F><><EFBFBD><EFBFBD>512<31><32><EFBFBD>ֽ<EFBFBD>
|
||||
buf+=512;
|
||||
}while(--cnt && r1==0);
|
||||
r1=SD_SendBlock(0,0xFD);//<2F><><EFBFBD><EFBFBD>512<31><32><EFBFBD>ֽ<EFBFBD>
|
||||
}
|
||||
}
|
||||
SD_DisSelect();//ȡ<><C8A1>Ƭѡ
|
||||
return r1;//
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user