e
Embed:
(wiki syntax)
Show/hide line numbers
SDCard.c
00001 #include "mbed.h" 00002 #include "mmc_sd.h" 00003 #include "spi.h" 00004 #include "Serial.h" 00005 00006 00007 uint8_t SD_Type=0;//SD Type 00008 00009 // 00010 //data:the data to write 00011 //return:the data read back 00012 uint8_t SD_SPI_ReadWriteByte(uint8_t data) 00013 { 00014 return SPI_ReadWriteByte(data); 00015 } 00016 00017 //SD Card should init in low speed 00018 void SD_SPI_SpeedLow(void) 00019 { 00020 SPI_SetSpeed(SPI_SPEED_256);//set in low speed 00021 } 00022 //SD Card work normally 00023 void SD_SPI_SpeedHigh(void) 00024 { 00025 SPI_SetSpeed(SPI_SPEED_2);//set in high speed 00026 } 00027 //SPI hardware Init 00028 void SD_SPI_Init(void) 00029 { 00030 SPI1_Init(); 00031 DigitalOut(SD_CS,1); 00032 } 00033 00034 /////////////////////////////////////////////////////////////////////////////////// 00035 //disable select ,release SPI BUS 00036 void SD_DisSelect(void) 00037 { 00038 SD_CS=1; 00039 SD_SPI_ReadWriteByte(0xff);//provide extra 8 clock 00040 } 00041 //select sd card,waiting card ready 00042 u8 SD_Select(void) 00043 { 00044 SD_CS=0; 00045 if(SD_WaitReady()==0)return 0;//waiting success 00046 SD_DisSelect(); 00047 return 1;/waiting failed 00048 } 00049 //waiting card ready 00050 //return:0,ready;other,error code 00051 u8 SD_WaitReady(void) 00052 { 00053 uint32_t t=0; 00054 do 00055 { 00056 if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK 00057 t++; 00058 }while(t<0XFFFFFF);//wait 00059 return 1; 00060 } 00061 //get SD card total sectors num 00062 //Response:0:get capacity error 00063 //other:SD card capacity(sectors num/512 bytes) 00064 //the num of byte of every sector must be 512,if ain't,the init can't pass 00065 uint8_t SD_GetResponse(uint8_t Response) 00066 { 00067 u16 Count=0xFFFF;//waiting num count 00068 while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//waiting for accurate respond 00069 if (Count==0)return MSD_RESPONSE_FAILURE;//response failure 00070 else return MSD_RESPONSE_NO_ERROR;//respond no error 00071 } 00072 //read a data package from SD card 00073 //buf:block buffer cache 00074 //len:length of data 00075 //return:0 success;other failed 00076 uint8_t SD_RecvData(uint8_t*buf,uint16_t len) 00077 { 00078 if(SD_GetResponse(0xFE))return 1;//waiting SD card return start sign 0xfe 00079 while(len--)//start recieve data 00080 { 00081 *buf=SPI_ReadWriteByte(0xFF); 00082 buf++; 00083 } 00084 //two dummy CRC 00085 SD_SPI_ReadWriteByte(0xFF); 00086 SD_SPI_ReadWriteByte(0xFF); 00087 return 0;//readding success 00088 } 00089 //write a data package to SD card 512 byte 00090 //buf:block buffer cache 00091 //cmd:order 00092 //retrun:0,success;1,failed 00093 uint8_t SD_SendBlock(uint8_t*buf,uint8_t cmd) 00094 { 00095 u16 t; 00096 if(SD_WaitReady())return 1;//waiting ready failed 00097 SD_SPI_ReadWriteByte(cmd); 00098 if(cmd!=0XFD)//not endding order 00099 { 00100 for(t=0;t<512;t++)SPI2_ReadWriteByte(buf[t]);//add speed 00101 SD_SPI_ReadWriteByte(0xFF);//ignore crc 00102 SD_SPI_ReadWriteByte(0xFF); 00103 t=SD_SPI_ReadWriteByte(0xFF);//receive respond 00104 if((t&0x1F)!=0x05)return 2;//respond failure 00105 } 00106 return 0;//writing success 00107 } 00108 00109 //write a order to sd card 00110 //input: u8 cmd order 00111 // u32 arg order param 00112 // u8 crc crc check Value 00113 //return:SD card respond 00114 uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg, uint8_t crc) 00115 { 00116 uint8_t r1; 00117 uint8_t Retry=0; 00118 SD_DisSelect();//disable last enable 00119 if(SD_Select())return 0XFF;//select failed 00120 //send 00121 SD_SPI_ReadWriteByte(cmd | 0x40);//write order 00122 SD_SPI_ReadWriteByte(arg >> 24); 00123 SD_SPI_ReadWriteByte(arg >> 16); 00124 SD_SPI_ReadWriteByte(arg >> 8); 00125 SD_SPI_ReadWriteByte(arg); 00126 SD_SPI_ReadWriteByte(crc); 00127 if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading 00128 //wait for respond or cvertime quit 00129 Retry=0X1F; 00130 do 00131 { 00132 r1=SD_SPI_ReadWriteByte(0xFF); 00133 }while((r1&0X80) && Retry--); 00134 //return state value 00135 return r1; 00136 } 00137 //��ȡSD����CID��Ϣ��������������Ϣ 00138 //����: u8 *cid_data(����CID���ڴ棬����16Byte�� 00139 //����ֵ:0��NO_ERR 00140 // 1������ 00141 uint8_t SD_GetCID(uint8_t *cid_data) 00142 { 00143 uint8_t r1; 00144 //��CMD10�����CID 00145 r1=SD_SendCmd(CMD10,0,0x01); 00146 if(r1==0x00) 00147 { 00148 r1=SD_RecvData(cid_data,16);//����16���ֽڵ����� 00149 } 00150 SD_DisSelect();//ȡ��Ƭѡ 00151 if(r1)return 1; 00152 else return 0; 00153 } 00154 //��ȡSD����CSD��Ϣ�������������ٶ���Ϣ 00155 //����:u8 *cid_data(����CID���ڴ棬����16Byte�� 00156 //����ֵ:0��NO_ERR 00157 // 1������ 00158 uint8_t SD_GetCSD(uint8_t *csd_data) 00159 { 00160 uint8_t r1; 00161 r1=SD_SendCmd(CMD9,0,0x01);//��CMD9�����CSD 00162 if(r1==0) 00163 { 00164 r1=SD_RecvData(csd_data, 16);//����16���ֽڵ����� 00165 } 00166 SD_DisSelect();//ȡ��Ƭѡ 00167 if(r1)return 1; 00168 else return 0; 00169 } 00170 //��ȡSD���������������������� 00171 //����ֵ:0�� ȡ�������� 00172 // ����:SD��������(������/512�ֽ�) 00173 //ÿ�������ֽ�����Ϊ512����Ϊ��������512������ʼ������ͨ��. 00174 uint32_t SD_GetSectorCount(void) 00175 { 00176 uint8_t csd[16]; 00177 uint32_t Capacity; 00178 uint8_t n; 00179 uint16_t csize; 00180 //ȡCSD��Ϣ�������ڼ�����������0 00181 if(SD_GetCSD(csd)!=0) return 0; 00182 //����ΪSDHC�����������淽ʽ���� 00183 if((csd[0]&0xC0)==0x40) //V2.00�Ŀ� 00184 { 00185 csize = csd[9] + ((uint16_t)csd[8] << 8) + 1; 00186 Capacity = (u32)csize << 10;//�õ������� 00187 }else//V1.XX�Ŀ� 00188 { 00189 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; 00190 csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1; 00191 Capacity= (uint32_t)csize << (n - 9);//�õ������� 00192 } 00193 return Capacity; 00194 } 00195 //��ʼ��SD�� 00196 uint8_t SD_Initialize(void) 00197 { 00198 uint8_t r1; // ����SD���ķ���ֵ 00199 uint16_t retry; // �������г�ʱ���� 00200 uint8_t buf[4]; 00201 uint16_t i; 00202 00203 SD_SPI_Init(); //��ʼ��IO 00204 SD_SPI_SpeedLow(); //���õ�����ģʽ 00205 for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//��������74������ 00206 retry=20; 00207 do 00208 { 00209 r1=SD_SendCmd(CMD0,0,0x95);//����IDLE״̬ 00210 }while((r1!=0X01) && retry--); 00211 SD_Type=0;//Ĭ���� 00212 if(r1==0X01) 00213 { 00214 if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0 00215 { 00216 for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF); //Get trailing return value of R7 resp 00217 if(buf[2]==0X01&&buf[3]==0XAA)//���Ƿ�֧��2.7~3.6V 00218 { 00219 retry=0XFFFE; 00220 do 00221 { 00222 SD_SendCmd(CMD55,0,0X01); //����CMD55 00223 r1=SD_SendCmd(CMD41,0x40000000,0X01);//����CMD41 00224 }while(r1&&retry--); 00225 if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//����SD2.0���汾��ʼ 00226 { 00227 for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//�õ�OCRֵ 00228 if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC; //����CCS 00229 else SD_Type=SD_TYPE_V2; 00230 } 00231 } 00232 }else//SD V1.x/ MMC V3 00233 { 00234 SD_SendCmd(CMD55,0,0X01); //����CMD55 00235 r1=SD_SendCmd(CMD41,0,0X01); //����CMD41 00236 if(r1<=1) 00237 { 00238 SD_Type=SD_TYPE_V1; 00239 retry=0XFFFE; 00240 do //�ȴ��˳�IDLEģʽ 00241 { 00242 SD_SendCmd(CMD55,0,0X01); //����CMD55 00243 r1=SD_SendCmd(CMD41,0,0X01);//����CMD41 00244 }while(r1&&retry--); 00245 }else//MMC����֧��CMD55+CMD41ʶ�� 00246 { 00247 SD_Type=SD_TYPE_MMC;//MMC V3 00248 retry=0XFFFE; 00249 do //�ȴ��˳�IDLEģʽ 00250 { 00251 r1=SD_SendCmd(CMD1,0,0X01);//����CMD1 00252 }while(r1&&retry--); 00253 } 00254 if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//�����Ŀ� 00255 } 00256 } 00257 SD_DisSelect();//ȡ��Ƭѡ 00258 SD_SPI_SpeedHigh();//���� 00259 if(SD_Type)return 0; 00260 else if(r1)return r1; 00261 return 0xaa;//�������� 00262 } 00263 //��SD�� 00264 //buf:���ݻ����� 00265 //sector:���� 00266 //cnt:������ 00267 //����ֵ:0,ok;����,ʧ��. 00268 uint8_t SD_ReadDisk(uint8_t*buf,uint32_t sector,u8 cnt) 00269 { 00270 uint8_t r1; 00271 if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//ת��Ϊ�ֽڵ�ַ 00272 if(cnt==1) 00273 { 00274 r1=SD_SendCmd(CMD17,sector,0X01);//������ 00275 if(r1==0)//ָ��ͳɹ� 00276 { 00277 r1=SD_RecvData(buf,512);//����512���ֽ� 00278 } 00279 }else 00280 { 00281 r1=SD_SendCmd(CMD18,sector,0X01);//���������� 00282 do 00283 { 00284 r1=SD_RecvData(buf,512);//����512���ֽ� 00285 buf+=512; 00286 }while(--cnt && r1==0); 00287 SD_SendCmd(CMD12,0,0X01); //����ֹͣ���� 00288 } 00289 SD_DisSelect();//ȡ��Ƭѡ 00290 return r1;// 00291 } 00292 //дSD�� 00293 //buf:���ݻ����� 00294 //sector:��ʼ���� 00295 //cnt:������ 00296 //����ֵ:0,ok;����,ʧ��. 00297 uint8_t SD_WriteDisk(uint8_t*buf,uint32_t sector,uint8_t cnt) 00298 { 00299 uint8_t r1; 00300 if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//ת��Ϊ�ֽڵ�ַ 00301 if(cnt==1) 00302 { 00303 r1=SD_SendCmd(CMD24,sector,0X01);//������ 00304 if(r1==0)//ָ��ͳɹ� 00305 { 00306 r1=SD_SendBlock(buf,0xFE);//д512���ֽ� 00307 } 00308 }else 00309 { 00310 if(SD_Type!=SD_TYPE_MMC) 00311 { 00312 SD_SendCmd(CMD55,0,0X01); 00313 SD_SendCmd(CMD23,cnt,0X01);//����ָ�� 00314 } 00315 r1=SD_SendCmd(CMD25,sector,0X01);//���������� 00316 if(r1==0) 00317 { 00318 do 00319 { 00320 r1=SD_SendBlock(buf,0xFC);//����512���ֽ� 00321 buf+=512; 00322 }while(--cnt && r1==0); 00323 r1=SD_SendBlock(0,0xFD);//����512���ֽ� 00324 } 00325 } 00326 SD_DisSelect();//ȡ��Ƭѡ 00327 return r1;// 00328 } 00329 00330 00331 00332 00333 00334 00335 00336 00337 00338 00339 00340 00341 00342 00343 00344 00345 00346 00347 00348 00349 00350 00351 00352 00353 00354 00355 00356 00357 00358 00359
Generated on Thu Jul 14 2022 08:13:32 by 1.7.2