e

Dependents:   MusicShield

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SDCard.c Source File

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