int sendSDCmd ( unsigned char c, unsigned a) // c command code // a bte address of data block { int i, r; //enable SD card enableSD(); // send a command packet (6 bytes) writeSPI( c | 0x40); //send command writeSPI( a>>24); //msb of the address writeSPI( a>>16); writeSPI( a>>8); writeSPI( a); //lsb writeSPI(0x95); //send CMD0 CRC // now wait for a response, allow to 8 bytes delay for( i=0; i<8; i++) { r=readSPI(); if ( r != 0xFF) break; } return ( r); // NOTE SDCS is still low! } // sendSDCmd
// c command code // a byte address of data block int sendSDCmd(unsigned char c, unsigned a) { int i, r; // enable SD card // CS low enableSD(); // send a comand packet (6 bytes) writeSPI(c | 0x40); // send command writeSPI(a>>24); // msb of the address writeSPI(a>>16); writeSPI(a>>8); writeSPI(a); // lsb writeSPI(0x95); // send CMD0 CRC // now wait for a response, allow for up to 8 bytes delay for(i=0; i<8; i++) { r = readSPI(); if (r != 0xFF) break; } return (r); /* return response FF - timeout 00 - command accepted 01 - command received, card in idle state after RESET other codes: bit 0 = Idle state bit 1 = Erase Reset bit 2 = Illegal command bit 3 = Communication CRC error bit 4 = Erase sequence error bit 5 = Address error bit 6 = Parameter error bit 7 = Always 0 */ // NOTE CSCD is still low! } // sendSDCmd
// 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