Hi,
I’m trying to interface a atmega8 with a SD card, but it’s not really working. I’m using a stripped version (only raw) of Roland Riegel’s library which can be found here: http://www.roland-riegel.de/sd-reader/doc/index.html
How it works: the atmega8 sends a little menu via UART, with three options: init SD, write byte and read byte. Init nicely returns success when the card is inserted, and fails without the card. Writing and reading always return success, even when the card is not inserted. I suspect that writing doesn’t work because I can still read the card’s old contents using my laptop, and reading always returns 0.
An additional “problem” is that I cannot program the atmega while the SD card is inserted, but that’s not really my priority so let’s keep that for later.
The code:
main.c
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#include <string.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include "sd_raw.h"
#include "sd_raw_config.h"
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdlib.h>
void usart_init(){
UCSRB |= (1 << RXEN) | (1 << TXEN);
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1) ;
UBRRL = BAUD_PRESCALE;
UBRRH = (BAUD_PRESCALE >> 8);
UCSRB |= (1 << RXCIE);
sei();
}
void usart_putch(char send){
while ((UCSRA & (1 << UDRE)) == 0) {};
UDR = send;
}
void usart_puts(char *stringptr){
while (*stringptr != 0x00){
usart_putch(*stringptr);
stringptr++;
}
}
void menu(){
usart_puts("\n1. init SD card\n");
usart_puts("2. write byte\n");
usart_puts("3. read byte\n");
}
ISR(USART_RXC_vect){
char rec;
uint8_t rbyte = 0x00;
uint8_t wbyte = 0x00;
rec = UDR;
if (rec == 0x31){
if(!sd_raw_init()) {
usart_puts("SD init failed...\n");
} else {
usart_puts("SD init successful...\n");
}
} else if (rec == 0x32){
wbyte = 0x61;
if(sd_raw_write(0, (uint8_t*) wbyte, 1)){
usart_puts("byte written...\n");
sd_raw_sync();
} else {
usart_puts("error writing byte...\n");
}
} else if (rec == 0x33){
if(sd_raw_read(0, (uint8_t*) rbyte, 1)){
usart_puts("byte read: ");
usart_putch((char)rbyte);
} else {
usart_puts("error reading byte...\n");
}
} else {
menu();
}
}
int main() {
usart_init();
menu();
while(1){
}
return 0;
}
changes to sd-raw_config.h
#define configure_pin_available()// DDRC &= ~(1 << DDC4)
#define configure_pin_locked() //DDRC &= ~(1 << DDC5)
#define get_pin_available() 0//(PINC & (1 << PINC4))
#define get_pin_locked() 1 //(PINC & (1 << PINC5))
Makefile
NAME := sd-reader
HEX := $(NAME).hex
OUT := $(NAME).out
MAP := $(NAME).map
SOURCES := $(wildcard *.c)
HEADERS := $(wildcard *.h)
OBJECTS := $(patsubst %.c,%.o,$(SOURCES))
MCU := atmega8
MCU_AVRDUDE := m8
MCU_FREQ := 12000000UL
CC := avr-gcc
OBJCOPY := avr-objcopy
SIZE := avr-size -A
DOXYGEN := doxygen
CFLAGS := -Wall -pedantic -mmcu=$(MCU) -std=c99 -g -Os -DF_CPU=$(MCU_FREQ)
all: $(HEX)
clean:
rm -f $(HEX) $(OUT) $(MAP) $(OBJECTS)
rm -rf doc/html
flash: $(HEX)
avrdude -y -c usbasp -p $(MCU_AVRDUDE) -U flash:w:$(HEX)
$(HEX): $(OUT)
$(OBJCOPY) -R .eeprom -O ihex $< $@
$(OUT): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ -Wl,-Map,$(MAP) $^
@echo
@$(SIZE) $@
@echo
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c -o $@ $<
%.pp: %.c
$(CC) $(CFLAGS) -E -o $@ $<
%.ppo: %.c
$(CC) $(CFLAGS) -E $<
doc: $(HEADERS) $(SOURCES) Doxyfile
$(DOXYGEN) Doxyfile
.PHONY: all clean flash doc
The SD board looks like this:
http://www.pieterprovoost.nl/sdcard.jpg
Thanks!