Skip to content

Instantly share code, notes, and snippets.

@randrews
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save randrews/1d7f6bcdb63891b29fdb to your computer and use it in GitHub Desktop.
Save randrews/1d7f6bcdb63891b29fdb to your computer and use it in GitHub Desktop.
Nonworking SD card code for AVR
#include <avr/io.h>
#include <util/delay.h>
// Some serial comms stuff; just using for debugging
#include "uart.h"
typedef unsigned char byte;
byte spi(byte b); // Send / receive one byte over SPI
void sd_select(int high); // Set SD CS pin high or low
int sd_command(byte cmd, uint32_t arg); // Send one command / arg pair to the SD card
byte sd_wait(); // Wait a max of 3 sec for the card not to be busy
int main(){
initUSART();
DDRB |= (1 << 2); // SD CS pin
PORTB |= (1 << 2); /* start off not selected (high) */
DDRB |= (1 << 3); /* output on MOSI */
PORTB |= (1 << 4); /* pullup on MISO */
DDRB |= (1 << 5); /* output on SCK */
SPCR |= (1 << SPR0) | (1 << SPR1); /* div 128 */
SPCR |= (1 << MSTR); /* clockmaster */
SPCR |= (1 << SPE); /* enable */
while(1){
receiveByte();
// Throw a bunch of cycles with CS high at it
sd_select(1);
for(int k=0; k < 10; k++) spi(0xFF);
sd_select(0); // Start the command
printStringHex("Wait: ", sd_wait());
printStringHex("Enter idle state: ", sd_command(0x00, 0));
sd_select(1); // end command
}
return 0;
}
////////////////////////////////////////////////////////////
byte spi(byte b) {
SPDR = b;
loop_until_bit_is_set(SPSR, SPIF); /* wait until done */
return SPDR; /* SPDR now contains the received byte */
}
void sd_select(int high){
if(high) DDRB |= (1 << 2);
else DDRB &= ~(1 << 2);
}
int sd_command(byte cmd, uint32_t arg){
spi(cmd | 0x40);
spi(arg >> 24);
spi(arg >> 16);
spi(arg >> 8);
spi(arg);
byte crc = 0xFF;
if (cmd == 0x00) crc = 0x95;
if (cmd == 0x08) crc = 0x87;
spi(crc);
int count = 0;
while(1){
byte status = spi(0xff);
if(!(status & 0x80)) return status;
if(count++ > 300) return status;
}
}
byte sd_wait() {
int count = 0;
while(1) {
if(spi(0xFF) == 0xFF) return 1;
if(count++ > 300) return 0;
_delay_ms(10);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment