samp Srinivasan / Mbed 2 deprecated CDMS_CODE_FROM13JAN2017

Dependencies:   FreescaleIAP SimpleDMA mbed-rtos mbed

Fork of CDMS_CODE by shubham c

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cdms_sd.h Source File

cdms_sd.h

00001 //SPI spi(PTE1, PTE3, PTE2);      // MOSI,MISO, CLOCK microcontroller(in order)     
00002 //DigitalOut cs_sd(PTE22);
00003 
00004 //Serial sd1(USBTX,USBRX);
00005 
00006 
00007 #define SD_COMMAND_TIMEOUT 325
00008 
00009 #define SD_DBG             0
00010 
00011 #define R1_IDLE_STATE           (1 << 0)
00012 #define R1_ERASE_RESET          (1 << 1)
00013 #define R1_ILLEGAL_COMMAND      (1 << 2)
00014 #define R1_COM_CRC_ERROR        (1 << 3)
00015 #define R1_ERASE_SEQUENCE_ERROR (1 << 4)
00016 #define R1_ADDRESS_ERROR        (1 << 5)
00017 #define R1_PARAMETER_ERROR      (1 << 6)
00018 
00019 
00020 
00021 #define SD_MAX_CYCLES 10000
00022 
00023 uint32_t SD_SCP_FIRST=1001;
00024 uint32_t SD_SCP_LAST=2000;
00025 uint32_t SD_SFF_AT_FIRST=2001;
00026 uint32_t SD_SFF_AT_LAST = 3000;
00027 uint32_t SD_SFF_BT_FIRST =3001;
00028 uint32_t SD_SFF_BT_LAST=4000;
00029 uint32_t SD_HK_ARCH_FIRST=4001;
00030 uint32_t SD_HK_ARCH_LAST= 5000;
00031 uint32_t LOG_FIRST =5001;
00032 uint32_t LOG_LAST=6000;
00033 uint32_t SD_MNG_SECT = 8000;
00034 
00035 extern uint8_t SD_INIT_FLAGS;
00036 
00037 int initialise_card();
00038 int initialise_card_v1();
00039 int initialise_card_v2();
00040 int disk_write(const uint8_t *, uint64_t);
00041 int disk_read(uint8_t *, uint64_t);
00042 int disk_erase(int,int);
00043 int disk_read_statusbits(uint8_t *);
00044 
00045 void FCTN_SD_MNGR();
00046 int INCREMENT_SD_LIB(uint8_t);
00047 
00048 
00049 int cmd(int, int);
00050 int cmd58();
00051 int cmdx(int, int);
00052 int cmd8();
00053 int read(uint8_t*, uint32_t );
00054 int write(const uint8_t*, uint32_t );
00055 static uint32_t ext_bits(unsigned char *, int , int );
00056 int SD_WRITE(uint8_t*,uint32_t,uint8_t);
00057 int FCTN_CDMS_SD_INIT();
00058 uint8_t SD_READ(uint8_t*,uint32_t,uint8_t);
00059 #define SDCARD_FAIL 4
00060 #define SDCARD_V1   1
00061 #define SDCARD_V2   2
00062 #define SDCARD_V2HC 3
00063 
00064 int cdv;
00065 uint64_t sd_sectors();
00066 uint64_t sectors;
00067 
00068 int FCTN_CDMS_SD_INIT()
00069 {   
00070     int i = initialise_card();
00071     if( i == 4)
00072     return 4;
00073     debug_if(SD_DBG, "init card = %d\n", i);
00074     sectors = sd_sectors();
00075 
00076     // Set block length to 512 (CMD16)
00077     if (cmd(16, 512) != 0) {
00078         debug("\rSet 512-byte block timed out\r\n");
00079         return 1;
00080     } else {
00081     //printf("\rDisk initialization successfull\r\n");
00082     }
00083     SD_STATUS = DEVICE_POWERED;
00084     spi.frequency(1000000); // Set to 1MHz for data transfer
00085     return 0;
00086 }
00087 
00088 void  FCTN_SD_MNGR()
00089 {
00090     uint32_t fsc;
00091     uint32_t start_fsc;
00092     uint8_t buffer[512];
00093     int b;
00094     if(SD_STATUS == DEVICE_POWERED){
00095     b=disk_read(buffer, SD_MNG_SECT);
00096     
00097     fsc=(uint32_t)(buffer[0]<<24)+(uint32_t)(buffer[1]<<16)+(uint32_t)(buffer[2]<<8)+(uint32_t)buffer[3];
00098     start_fsc=(uint32_t)(buffer[4]<<24)+(uint32_t)(buffer[5]<<16)+(uint32_t)(buffer[6]<<8)+(uint32_t)buffer[7];
00099     FSC_CURRENT[1] = fsc;
00100     FSC_OLD[1] = start_fsc;
00101 
00102     fsc=(uint32_t)(buffer[8]<<24)+(uint32_t)(buffer[9]<<16)+(uint32_t)(buffer[10]<<8)+(uint32_t)buffer[11];
00103     start_fsc=(uint32_t)(buffer[12]<<24)+(uint32_t)(buffer[13]<<16)+(uint32_t)(buffer[14]<<8)+(uint32_t)buffer[15];
00104     FSC_CURRENT[2] = fsc;
00105     FSC_OLD[2] = start_fsc;
00106 
00107     fsc=(uint32_t)(buffer[16]<<24)+(uint32_t)(buffer[17]<<16)+(uint32_t)(buffer[18]<<8)+(uint32_t)buffer[19];
00108     start_fsc=(uint32_t)(buffer[20]<<24)+(uint32_t)(buffer[21]<<16)+(uint32_t)(buffer[22]<<8)+(uint32_t)buffer[23];
00109     FSC_CURRENT[3] = fsc;
00110     FSC_OLD[3] = start_fsc;
00111 
00112     fsc=(uint32_t)(buffer[24]<<24)+(uint32_t)(buffer[25]<<16)+(uint32_t)(buffer[26]<<8)+(uint32_t)buffer[27];
00113     start_fsc=(uint32_t)(buffer[28]<<24)+(uint32_t)(buffer[29]<<16)+(uint32_t)(buffer[30]<<8)+(uint32_t)buffer[31];
00114     FSC_CURRENT[4] = fsc;
00115     FSC_OLD[4] = start_fsc;
00116 
00117     fsc=(uint32_t)(buffer[32]<<24)+(uint32_t)(buffer[33]<<16)+(uint32_t)(buffer[34]<<8)+(uint32_t)buffer[35];
00118     start_fsc=(uint32_t)(buffer[36]<<24)+(uint32_t)(buffer[37]<<16)+(uint32_t)(buffer[38]<<8)+(uint32_t)buffer[39];
00119     FSC_CURRENT[5] = fsc;
00120     FSC_OLD[5] = start_fsc;
00121     }
00122 }
00123 
00124 int INCREMENT_SD_LIB(uint8_t sid)
00125 {
00126     uint32_t fsc;
00127     uint32_t start_fsc;
00128     int i;
00129     uint8_t buffer[512];
00130     
00131     disk_read(buffer,SD_MNG_SECT);
00132     SD_MNG_SECT += SD_LIB_WRITES/(int)0xFFFF;
00133     if(SD_MNG_SECT != SD_LIB_BLK_CURRENT)
00134     {
00135         SD_LIB_BLK_CURRENT = SD_MNG_SECT;
00136         FCTN_CDMS_WR_FLASH(16,SD_LIB_BLK_CURRENT);    
00137     }
00138     SD_LIB_WRITES = SD_LIB_WRITES%(int)0xFFFF;
00139     disk_write(buffer,SD_MNG_SECT);
00140  //   gPC.printf("in increment_SD_LIB = %d, %d,%d\n\r", FSC_CURRENT[1],FSC_CURRENT[2],FSC_CURRENT[3]);
00141   //  SD_MNG_SECT += SD_LIB_WRITES/(int)0xFFFF;
00142   //  SD_LIB_WRITES = SD_LIB_WRITES%(int)0xFFFF;
00143  
00144     disk_read(buffer,SD_MNG_SECT);
00145     if(sid==0x01)
00146     {
00147         fsc=(uint32_t)(buffer[0]<<24)+(uint32_t)(buffer[1]<<16)+(uint32_t)(buffer[2]<<8)+(uint32_t)buffer[3];
00148         start_fsc=(uint32_t)(buffer[4]<<24)+(uint32_t)(buffer[5]<<16)+(uint32_t)(buffer[6]<<8)+(uint32_t)buffer[7];
00149         fsc++;
00150         buffer[0]=(uint8_t) (fsc>>24 & 0xFF);
00151         buffer[1]=(uint8_t) (fsc>>16 & 0xFF);
00152         buffer[2]=(uint8_t) (fsc>>8 & 0xFF);
00153         buffer[3]=(uint8_t) (fsc & 0xFF);
00154         if(fsc > SD_SCP_LAST-SD_SCP_FIRST+1)
00155         {
00156             start_fsc = start_fsc+1;
00157             buffer[4]=(uint8_t) (start_fsc>>24 & 0xFF);
00158             buffer[5]=(uint8_t) (start_fsc>>16 & 0xFF);
00159             buffer[6]=(uint8_t) (start_fsc>>8 & 0xFF);
00160             buffer[7]=(uint8_t) (start_fsc & 0xFF);
00161         }
00162         
00163         i = disk_write(buffer,SD_MNG_SECT);
00164         if(i == 0)
00165         {
00166             FSC_CURRENT[1] = fsc;
00167             FSC_OLD[1] = start_fsc;
00168             return i;
00169         } 
00170     }
00171     if(sid==0x02)
00172     {
00173         fsc=(uint32_t)(buffer[8]<<24)+(uint32_t)(buffer[9]<<16)+(uint32_t)(buffer[10]<<8)+(uint32_t)buffer[11];
00174         start_fsc=(uint32_t)(buffer[12]<<24)+(uint32_t)(buffer[13]<<16)+(uint32_t)(buffer[14]<<8)+(uint32_t)buffer[15];
00175         fsc++;
00176         buffer[8]=(uint8_t) (fsc>>24 & 0xFF);
00177         buffer[9]=(uint8_t) (fsc>>16 & 0xFF);
00178         buffer[10]=(uint8_t) (fsc>>8 & 0xFF);
00179         buffer[11]=(uint8_t) (fsc & 0xFF);
00180         if(fsc > SD_SFF_AT_LAST-SD_SFF_AT_FIRST+1)
00181         {
00182             start_fsc = start_fsc+1;
00183             buffer[12]=(uint8_t) (start_fsc>>24 & 0xFF);
00184             buffer[13]=(uint8_t) (start_fsc>>16 & 0xFF);
00185             buffer[14]=(uint8_t) (start_fsc>>8 & 0xFF);
00186             buffer[15]=(uint8_t) (start_fsc & 0xFF);
00187         }
00188         i = disk_write(buffer,SD_MNG_SECT);
00189         if(i == 0)
00190         {
00191             FSC_CURRENT[2] = fsc;
00192             FSC_OLD[2] = start_fsc;
00193             return i;
00194         }
00195     }
00196     if(sid==0x03)
00197     {
00198         fsc=(uint32_t)(buffer[16]<<24)+(uint32_t)(buffer[17]<<16)+(uint32_t)(buffer[18]<<8)+(uint32_t)buffer[19];
00199         start_fsc=(uint32_t)(buffer[20]<<24)+(uint32_t)(buffer[21]<<16)+(uint32_t)(buffer[22]<<8)+(uint32_t)buffer[23];
00200         fsc++;
00201         buffer[16]=(uint8_t) (fsc>>24 & 0xFF);
00202         buffer[17]=(uint8_t) (fsc>>16 & 0xFF);
00203         buffer[18]=(uint8_t) (fsc>>8 & 0xFF);
00204         buffer[19]=(uint8_t) (fsc & 0xFF);
00205         if(fsc > SD_SFF_BT_LAST-SD_SFF_BT_FIRST+1)
00206         {
00207             start_fsc = start_fsc+1;
00208             buffer[20]=(uint8_t) (start_fsc>>24 & 0xFF);
00209             buffer[21]=(uint8_t) (start_fsc>>16 & 0xFF);
00210             buffer[22]=(uint8_t) (start_fsc>>8 & 0xFF);
00211             buffer[23]=(uint8_t) (start_fsc & 0xFF);
00212         }
00213         i = disk_write(buffer,SD_MNG_SECT);
00214         if(i == 0)
00215         {
00216             FSC_CURRENT[3] = fsc;
00217             FSC_OLD[3] = start_fsc;
00218             return i;
00219         }
00220     }
00221      if(sid==0x04)
00222     {
00223         fsc=(uint32_t)(buffer[24]<<24)+(uint32_t)(buffer[25]<<16)+(uint32_t)(buffer[26]<<8)+(uint32_t)buffer[27];
00224         start_fsc=(uint32_t)(buffer[28]<<24)+(uint32_t)(buffer[29]<<16)+(uint32_t)(buffer[30]<<8)+(uint32_t)buffer[31];
00225         fsc++;
00226         buffer[24]=(uint8_t) (fsc>>24 & 0xFF);
00227         buffer[25]=(uint8_t) (fsc>>16 & 0xFF);
00228         buffer[26]=(uint8_t) (fsc>>8 & 0xFF);
00229         buffer[27]=(uint8_t) (fsc & 0xFF);
00230         if(fsc > SD_HK_ARCH_LAST-SD_HK_ARCH_FIRST+1)
00231         {
00232             start_fsc = start_fsc+1;
00233             buffer[28]=(uint8_t) (start_fsc>>24 & 0xFF);
00234             buffer[29]=(uint8_t) (start_fsc>>16 & 0xFF);
00235             buffer[30]=(uint8_t) (start_fsc>>8 & 0xFF);
00236             buffer[31]=(uint8_t) (start_fsc & 0xFF);
00237         }
00238         i = disk_write(buffer,SD_MNG_SECT);
00239         if(i == 0)
00240         {
00241             FSC_CURRENT[4] = fsc;
00242             FSC_OLD[4] = start_fsc;
00243             return i;
00244         }
00245     }
00246      if(sid==0x05)
00247     {
00248         fsc=(uint32_t)(buffer[32]<<24)+(uint32_t)(buffer[33]<<16)+(uint32_t)(buffer[34]<<8)+(uint32_t)buffer[35];
00249         start_fsc=(uint32_t)(buffer[36]<<24)+(uint32_t)(buffer[37]<<16)+(uint32_t)(buffer[38]<<8)+(uint32_t)buffer[39];
00250         fsc++;
00251         buffer[32]=(uint8_t) (fsc>>24 & 0xFF);
00252         buffer[33]=(uint8_t) (fsc>>16 & 0xFF);
00253         buffer[34]=(uint8_t) (fsc>>8 & 0xFF);
00254         buffer[35]=(uint8_t) (fsc & 0xFF);
00255         if(fsc > LOG_LAST-LOG_FIRST+1)
00256         {
00257             start_fsc = start_fsc+1;
00258             buffer[36]=(uint8_t) (start_fsc>>24 & 0xFF);
00259             buffer[37]=(uint8_t) (start_fsc>>16 & 0xFF);
00260             buffer[38]=(uint8_t) (start_fsc>>8 & 0xFF);
00261             buffer[39]=(uint8_t) (start_fsc & 0xFF);
00262         }
00263         i = disk_write(buffer,SD_MNG_SECT);
00264         if(i == 0)
00265         {
00266             FSC_CURRENT[5] = fsc;
00267             FSC_OLD[5] = start_fsc;
00268             return i;
00269         }
00270     }
00271     return -1;
00272 }
00273 
00274 
00275 int SD_WRITE(uint8_t* buffer,uint32_t fsc,uint8_t sid)
00276 {
00277     uint32_t block_number;
00278     int result = 10;
00279     if(SD_STATUS == DEVICE_POWERED){
00280     if(sid==0x01)
00281     {
00282         block_number=SD_SCP_FIRST+(fsc%(SD_SCP_LAST-SD_SCP_FIRST+1))-1;
00283         //block_number=SD_SCP_FIRST+fsc;
00284         result= disk_write(buffer,block_number);
00285         if(result == 0)
00286         {
00287             if(INCREMENT_SD_LIB(sid) == 0)
00288                 SD_LIB_WRITES++;
00289         }
00290         return result;
00291     }
00292    if(sid==0x02)
00293     {
00294         block_number= SD_SFF_AT_FIRST+(fsc%(SD_SFF_AT_LAST - SD_SFF_AT_FIRST+1))-1;
00295         //block_number= SD_SFF_AT_FIRST+fsc;
00296         result= disk_write(buffer,block_number);
00297         if(result == 0)
00298          {
00299             if(INCREMENT_SD_LIB(sid) == 0)
00300                 SD_LIB_WRITES++;
00301         }
00302         return result;
00303     }
00304      if(sid==0x03)
00305     {
00306         block_number= SD_SFF_BT_FIRST +(fsc%(SD_SFF_BT_LAST - SD_SFF_BT_FIRST +1))-1;
00307         //block_number= SD_SFF_BT_FIRST +fsc;
00308         result= disk_write(buffer,block_number);
00309         if(result == 0)
00310         {
00311             if(INCREMENT_SD_LIB(sid) == 0)
00312                 SD_LIB_WRITES++;
00313         }
00314         return result;
00315     }
00316      if(sid==0x04)
00317     {
00318         block_number=SD_HK_ARCH_FIRST +(fsc%(SD_HK_ARCH_LAST - SD_HK_ARCH_FIRST +1))-1;
00319         //block_number=SD_HK_ARCH_FIRST +fsc;
00320         result= disk_write(buffer,block_number);
00321         if(result == 0)
00322         {
00323             if(INCREMENT_SD_LIB(sid) == 0)
00324                 SD_LIB_WRITES++;
00325         }
00326         return result;
00327     }
00328      if(sid==0x05)
00329     {
00330         block_number= LOG_FIRST +(fsc%(LOG_FIRST - LOG_FIRST +1))-1;
00331         //block_number= LOG_FIRST +fsc;
00332         result= disk_write(buffer,block_number);
00333         if(result == 0)
00334         {
00335             if(INCREMENT_SD_LIB(sid) == 0)
00336                 SD_LIB_WRITES++;
00337         }
00338         return result;
00339     }
00340     }
00341    // return 1;
00342 }
00343 
00344 uint8_t SD_READ(uint8_t* buffer,uint32_t fsc,uint8_t sid)
00345 {
00346     FCTN_SD_MNGR();
00347     uint32_t block_number;
00348     int result;
00349     //if(SD_SW_EN_DS == 1)
00350     //    return 0x89;
00351     if(sid==0x01)
00352     {
00353         if(!(FSC_OLD[1]<=fsc && fsc<=FSC_CURRENT[1])){
00354             return 0x86;
00355         }
00356         block_number=SD_SCP_FIRST+(fsc%(SD_SCP_LAST-SD_SCP_FIRST+1))-1;
00357         result= disk_read(buffer,block_number);
00358     }
00359    else if(sid==0x02)
00360     {
00361         if(!(FSC_OLD[2]<=fsc && fsc<=FSC_CURRENT[2])){
00362             return 0x86;
00363         }
00364         block_number= SD_SFF_AT_FIRST+(fsc%(SD_SFF_AT_LAST - SD_SFF_AT_FIRST+1))-1;
00365         result= disk_read(buffer,block_number);
00366     }
00367     else if(sid==0x03)
00368     {
00369         if(!(FSC_OLD[3]<=fsc && fsc<=FSC_CURRENT[3])){
00370             return 0x86;
00371         }
00372         block_number= SD_SFF_BT_FIRST +(fsc%(SD_SFF_BT_LAST - SD_SFF_BT_FIRST +1))-1;
00373         result= disk_read(buffer,block_number);
00374     }
00375     else if(sid==0x04)
00376     {
00377         if(!(FSC_OLD[4]<=fsc && fsc<=FSC_CURRENT[4])){
00378             return 0x86;
00379         }
00380         block_number=SD_HK_ARCH_FIRST +(fsc%(SD_HK_ARCH_LAST - SD_HK_ARCH_FIRST +1))-1;
00381         result= disk_read(buffer,block_number);
00382     }
00383     else if(sid==0x05)
00384     {
00385         if(!(FSC_OLD[5]<=fsc && fsc<=FSC_CURRENT[5])){
00386             return 0x86;
00387         }
00388         block_number= LOG_FIRST +(fsc%(LOG_FIRST - LOG_FIRST +1))-1;
00389         result= disk_read(buffer,block_number);
00390     }
00391     else
00392     {
00393         return 0x02;
00394     }
00395     if(result == 0)
00396         return 0xA0;
00397     else
00398         return 0x88;
00399     return 0xA0;
00400 }
00401 
00402 
00403 int initialise_card()
00404 {
00405     // Set to 100kHz for initialisation, and clock card with cs_sd = 1
00406     spi.frequency(100000);           // changed on 31 12 2015 to 1 MHz 
00407     cs_sd = 1;
00408     for (int i = 0; i < 16; i++) {
00409         spi.write(0xFF);
00410     }
00411     uint8_t R1_response = cmd(0,0);
00412     gPC.printf("0x%02X",R1_response);
00413     // send CMD0, should return with all zeros except IDLE STATE set (bit 0)
00414     if (R1_response != R1_IDLE_STATE) {
00415         debug("No disk, or could not put SD card in to spi idle state\r\n");
00416         return SDCARD_FAIL;
00417     }
00418     else
00419         gPC.puts("SD Card is in IDLE state\n\r");    
00420 
00421     // send CMD8 to determine whther it is ver 2.x
00422     int r = cmd8();
00423     if (r == R1_IDLE_STATE) {
00424         gPC.puts("Entering V2\r");
00425         int q =  initialise_card_v2();
00426         return q;
00427 
00428     } else if (r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND)) {
00429         gPC.puts("Entering V1");
00430         return initialise_card_v1();
00431 
00432     } else {
00433         debug("\rNot in idle state after sending CMD8 (not an SD card?)\r\n");
00434         return SDCARD_FAIL;
00435     }
00436 }
00437 
00438 int initialise_card_v1()
00439 {
00440     for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
00441         cmd(55, 0);
00442         if (cmd(41, 0) == 0) {
00443             gPC.puts("\rv1 initialization successfull\r\n");
00444             cdv = 512;
00445             debug_if(SD_DBG, "\n\rInit: SEDCARD_V1\n\r");
00446             return SDCARD_V1;
00447         }
00448     }
00449 
00450     debug("\rTimeout waiting for v1.x card\r\n");
00451     return SDCARD_FAIL;
00452 }
00453 
00454 
00455 int initialise_card_v2()
00456 {
00457     for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
00458         wait_ms(50);
00459         cmd58();
00460         cmd(55, 0);
00461         if (cmd(41, 0x40000000) == 0) {
00462             if (DEBUG)
00463                 gPC.puts("\rv2 initialization successfull\r\n");
00464             cmd58();
00465             debug_if(SD_DBG, "\n\rInit: SDCARD_V2\n\r");
00466             cdv = 1;
00467             FCTN_SD_MNGR();
00468             return SDCARD_V2;
00469         }
00470     }
00471 
00472     debug("\rTimeout waiting for v2.x card\r\n");
00473     return SDCARD_FAIL;
00474 }
00475 
00476 int cmd(int cmd, int arg)
00477 {
00478     cs_sd = 0;
00479 
00480     // send a command
00481     spi.write(0x40 | cmd);
00482     spi.write(arg >> 24);
00483     spi.write(arg >> 16);
00484     spi.write(arg >> 8);
00485     spi.write(arg >> 0);
00486     spi.write(0x95);
00487 
00488     // wait for the repsonse (response[7] == 0)
00489     for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
00490         int response = spi.write(0xFF);
00491         if (!(response & 0x80)) {
00492             cs_sd = 1;
00493             spi.write(0xFF);
00494             return response;
00495         }
00496     }
00497     cs_sd = 1;
00498     spi.write(0xFF);
00499     return -1; // timeout
00500 }
00501 
00502 
00503 int cmd58()
00504 {
00505     cs_sd = 0;
00506     int arg = 0;
00507 
00508     // send a command
00509     spi.write(0x40 | 58);
00510     spi.write(arg >> 24);
00511     spi.write(arg >> 16);
00512     spi.write(arg >> 8);
00513     spi.write(arg >> 0);
00514     spi.write(0x95);
00515 
00516     // wait for the repsonse (response[7] == 0)
00517     for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
00518         int response = spi.write(0xFF);
00519         if (!(response & 0x80)) {
00520             int ocr = spi.write(0xFF) << 24;
00521             ocr |= spi.write(0xFF) << 16;
00522             ocr |= spi.write(0xFF) << 8;
00523             ocr |= spi.write(0xFF) << 0;
00524             cs_sd = 1;
00525             spi.write(0xFF);
00526             return response;
00527         }
00528     }
00529     cs_sd = 1;
00530     spi.write(0xFF);
00531     return -1; // timeout
00532 }
00533 
00534 
00535 int cmd8()
00536 {
00537     cs_sd = 0;
00538 
00539     // send a command
00540     spi.write(0x40 | 8); // CMD8
00541     spi.write(0x00);     // reserved
00542     spi.write(0x00);     // reserved
00543     spi.write(0x01);     // 3.3v
00544     spi.write(0xAA);     // check pattern
00545     spi.write(0x87);     // crc
00546 
00547     // wait for the repsonse (response[7] == 0)
00548     for (int i = 0; i < SD_COMMAND_TIMEOUT * 1000; i++) {
00549         char response[5];
00550         response[0] = spi.write(0xFF);
00551         if (!(response[0] & 0x80)) {
00552             for (int j = 1; j < 5; j++) {
00553                 response[i] = spi.write(0xFF);
00554             }
00555             cs_sd = 1;
00556             spi.write(0xFF);
00557             return response[0];
00558         }
00559     }
00560     cs_sd = 1;
00561     spi.write(0xFF);
00562     return -1; // timeout
00563 }
00564 
00565 uint64_t sd_sectors()
00566 {
00567     uint32_t c_size, c_size_mult, read_bl_len;
00568     uint32_t block_len, mult, blocknr, capacity;
00569     uint32_t hc_c_size;
00570     uint64_t blocks;
00571 
00572     // CMD9, Response R2 (R1 byte + 16-byte block read)
00573     if (cmdx(9, 0) != 0) {
00574         debug("\rDidn't get a response from the disk\n");
00575         return 0;
00576     }
00577 
00578     uint8_t cs_sdd[16];
00579     if (read(cs_sdd, 16) != 0) {
00580         debug("\rCouldn't read cs_sdd response from disk\n");
00581         return 0;
00582     }
00583 
00584     // cs_sdd_structure : cs_sdd[127:126]
00585     // c_size        : cs_sdd[73:62]
00586     // c_size_mult   : cs_sdd[49:47]
00587     // read_bl_len   : cs_sdd[83:80] - the *maximum* read block length
00588 
00589     int cs_sdd_structure = ext_bits(cs_sdd, 127, 126);
00590 
00591     switch (cs_sdd_structure) {
00592         case 0:
00593             cdv = 512;
00594             c_size = ext_bits(cs_sdd, 73, 62);
00595             c_size_mult = ext_bits(cs_sdd, 49, 47);
00596             read_bl_len = ext_bits(cs_sdd, 83, 80);
00597 
00598             block_len = 1 << read_bl_len;
00599             mult = 1 << (c_size_mult + 2);
00600             blocknr = (c_size + 1) * mult;
00601             capacity = blocknr * block_len;
00602             blocks = capacity / 512;
00603             debug_if(SD_DBG, "\n\rSDCard\n\rc_size: %d \n\rcapacity: %ld \n\rsectors: %lld\n\r", c_size, capacity, blocks);
00604             break;
00605 
00606         case 1:
00607             cdv = 1;
00608             hc_c_size = ext_bits(cs_sdd, 63, 48);
00609             blocks = (hc_c_size+1)*1024;
00610             debug_if(SD_DBG, "\n\rSDHC Card \n\rhc_c_size: %d\n\rcapacity: %lld \n\rsectors: %lld\n\r", hc_c_size, blocks*512, blocks);
00611             break;
00612 
00613         default:
00614             debug("cs_sdD struct unsupported\r\n");
00615             return 0;
00616     };
00617     return blocks;
00618 }
00619 
00620 int cmdx(int cmd, int arg)
00621 {
00622     cs_sd = 0;
00623 
00624     // send a command
00625     spi.write(0x40 | cmd);
00626     spi.write(arg >> 24);
00627     spi.write(arg >> 16);
00628     spi.write(arg >> 8);
00629     spi.write(arg >> 0);
00630     spi.write(0x95);
00631 
00632     // wait for the repsonse (response[7] == 0)
00633     for (int i = 0; i < SD_COMMAND_TIMEOUT; i++) {
00634         int response = spi.write(0xFF);
00635         if (!(response & 0x80)) {
00636             return response;
00637         }
00638     }
00639     cs_sd = 1;
00640     spi.write(0xFF);
00641     return 1; // timeout
00642 }
00643 
00644 static uint32_t ext_bits(unsigned char *data, int msb, int lsb)
00645 {
00646     uint32_t bits = 0;
00647     uint32_t size = 1 + msb - lsb;
00648     for (int i = 0; i < size; i++) {
00649         uint32_t position = lsb + i;
00650         uint32_t byte = 15 - (position >> 3);
00651         uint32_t bit = position & 0x7;
00652         uint32_t value = (data[byte] >> bit) & 1;
00653         bits |= value << i;
00654     }
00655     return bits;
00656 }
00657 
00658 int disk_write(const uint8_t *buffer, uint64_t block_number)
00659 
00660 {
00661     // set write address for single block (CMD24)
00662     if (cmd(24, block_number * cdv) != 0) {
00663         CDMS_WR_SD_FAULT_COUNTER++;
00664         return 1;
00665     }
00666     
00667     uint64_t temp;
00668     int r = write(buffer, 512);
00669     if(r == 0 ){
00670         temp = FCTN_CDMS_RD_RTC();
00671         TIME_LATEST_SD_WR = temp >> 7; //corrected by samp:TIME_LATEST_SD_WRD = temp >> 7;
00672     }
00673     return  r;
00674 }
00675 
00676 int write(const uint8_t*buffer, uint32_t length)
00677 {
00678     cs_sd = 0;
00679 
00680     // indicate start of block
00681     spi.write(0xFE);
00682 
00683     // write the data
00684     for (int i = 0; i < length; i++) {
00685         spi.write(buffer[i]);
00686     }
00687 
00688     // write the checksum
00689     spi.write(0xFF);
00690     spi.write(0xFF);
00691 
00692     // check the response token
00693     if ((spi.write(0xFF) & 0x1F) != 0x05) {
00694         cs_sd = 1;
00695         spi.write(0xFF);
00696         CDMS_WR_SD_FAULT_COUNTER++;
00697         return 1;
00698     }
00699 
00700     // wait for write to finish
00701     while (spi.write(0xFF) == 0);
00702 
00703     cs_sd = 1;
00704     spi.write(0xFF);
00705     return 0;
00706 }
00707 
00708 int disk_read(uint8_t *buffer, uint64_t block_number)
00709 {
00710     // set read address for single block (CMD17)
00711     if (cmd(17, block_number * cdv) != 0) {
00712         SD_RD_ERROR = 1;
00713         return 1;
00714     }
00715 
00716     // receive the data
00717     read(buffer, 512);
00718     uint64_t temp = FCTN_CDMS_RD_RTC();
00719     TIME_LATEST_SD_RD = temp >> 7;
00720     return 0;
00721 }
00722 
00723 int read(uint8_t *buffer, uint32_t length)
00724 {
00725     cs_sd = 0;
00726 
00727     // read until start byte (0xFF)
00728     while (spi.write(0xFF) != 0xFE);
00729 
00730     // read data
00731     for (int i = 0; i < length; i++) {
00732         buffer[i] = spi.write(0xFF);
00733     }
00734     spi.write(0xFF); // checksum
00735     spi.write(0xFF);
00736 
00737     cs_sd = 1;
00738     spi.write(0xFF);
00739     return 0;
00740 }
00741 
00742 int disk_erase(int startBlock, int totalBlocks)
00743 {
00744     if(cmd(32, startBlock * cdv) != 0) {
00745         return 1;
00746     }
00747     if (cmd(33, (startBlock+totalBlocks-1) * cdv) != 0) {
00748         return 1;
00749     }
00750     if (cmd(38,0) != 0) {
00751         return 1;
00752     }
00753     
00754     return 0; //normal return
00755 }
00756 
00757 int disk_read_statusbits(uint8_t *buffer)
00758 {
00759     if (cmd(17, 0) != 0) {
00760           SD_RD_ERROR = 1;
00761         return -1;
00762     }
00763 
00764     // receive the data
00765     return read(buffer,64);
00766 }