// a LBA of sector requested // p pointer to sector buffer // returns TRUE if successful int writeSECTOR(LBA a, char *p) { unsigned r, i; // 0. check Write Protect if (getWP()) return FAIL; // 1. send WRITE command r = sendSDCmd(WRITE_SINGLE, (a << 9)); if (r == 0) // check if command was accepted { // 2. send data writeSPI(DATA_START); // send 512 bytes of data for(i=0; i<512; i++) writeSPI(*p++); // 3. send dummy CRC clockSPI(); clockSPI(); // 4. check if data accepted r = readSPI(); if ((r & 0xf) == DATA_ACCEPT) { #ifdef WRITE_LED digitalwrite(WRITE_LED, 0); #endif // 5. wait for write completion for(i=0; i<W_TIMEOUT; i++) { r = readSPI(); if (r != 0 ) break; } #ifdef WRITE_LED digitalwrite(WRITE_LED, 1); #endif } // accepted else { r = FAIL; } } // command accepted // 6. disable the card disableSD(); return (r); // return TRUE if successful } // writeSECTOR
int initMedia( void) //returns 0 if succesful // E_COMMAND_ACK failed to acknowledge reset command // E_INIT_TIMEOUT failed to initialize { int i, r; ; // 1. with the card NOT selected disableSD(); // 2. send 80 clock cycles start up for(i=0;i<80;i++) clockSPI(); // 3. now select the card enableSD(); // 4. send a single RESET commmand r = sendSDCmd( RESET, 0); disableSD(); if ( r != 1) // must return Idle return E_COMMAND_ACK; // 5. send repeatedly INIT until Idle terminates for (i=0; i<I_TIMEOUT; i++) { r = sendSDCmd( INIT, 0); disableSD(); if ( !r) break; } if ( i == I_TIMEOUT) return E_INIT_TIMEOUT; // init timed out // 6. increase speed SPI3ACON = 0; // disable the SPI2 module SPI3ABRG = 0; // Fpb/(2*(0+1)) = 20/2 = 10MHz SPI3ACON = 0x8120; // re-enable the SPI2 module return 0; } //init media
// a LBA of sector requested // p pointer to sector buffer // returns TRUE if successful int readSECTOR(LBA a, char *p) { int r, i; #ifdef READ_LED digitalwrite(READ_LED, 0); #endif // 1. send READ command r = sendSDCmd(READ_SINGLE, (a << 9)); if (r == 0) // check if command was accepted { // 2. wait for a response for(i=0; i<R_TIMEOUT; i++) { r = readSPI(); if (r == DATA_START) break; } // 3. if it did not timeout, read 512 byte of data if (i != R_TIMEOUT) { i = 512; do{ *p++ = readSPI(); } while (--i>0); // 4. ignore CRC readSPI(); readSPI(); } // data arrived } // command accepted // 5. remember to disable the card disableSD(); #ifdef READLED digital(READ_LED, 1); #endif return (r == DATA_START); // return TRUE if successful } // readSECTOR
// returns 0 if successful // E_COMMAND_ACK failed to acknowledge reset command // E_INIT_TIMEOUT failed to initialize int initMedia(void) { int i, r; // 1. with the card NOT selected // Set DI and CS high disableSD(); // 2. send 74 or more clock cycles to start up // apply 74 or more clock pulses to SCLK. // The card will enter its native operating mode and go ready to accept native commands. for (i=0; i<10; i++) clockSPI(); // 3. now select the card enableSD(); //card detection is now in disk_initialize() return 0; } // init media