SparkFun Forums 

Where electronics enthusiasts find answers.

Your source for all things Atmel.
By tombaugh
#93669
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
Code: Select all
#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
Code: Select all
#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
Code: Select all
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:

Image

Thanks!
By Liencouer
#93834
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.
if the SD card is spi (and i think it is), you might have some bus conflicts with the ISP. im not familiar with SD card interfacing, does the SD card have a CSN line that may not be properly pulled up when the M8 is in reset (being programmed)?
By tombaugh
#93903
Liencouer wrote:if the SD card is spi (and i think it is), you might have some bus conflicts with the ISP. im not familiar with SD card interfacing, does the SD card have a CSN line that may not be properly pulled up when the M8 is in reset (being programmed)?
That's the problem indeed, the circuit on Ronald's page has such a line but mine doesn't. Have to keep that in mind for the next version.

The writing problem has been solved by fixing the pointers...