// 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
// 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
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
void disableSD(void) { digitalwrite(SDCS, HIGH); // Deselected = SDCS high clockSPI(); }