diff --git a/poc/avr_sdcard/Makefile b/poc/avr_sdcard/Makefile index 6f5a58a..035b198 100644 --- a/poc/avr_sdcard/Makefile +++ b/poc/avr_sdcard/Makefile @@ -38,11 +38,11 @@ # MCU name -MCU = atmega8 +MCU = atmega16 # Main Oscillator Frequency # This is only used to define F_OSC in all assembler and c-sources. -F_OSC = 8000000 +F_OSC = 16000000 # Output format. (can be srec, ihex, binary) FORMAT = ihex @@ -112,7 +112,7 @@ CFLAGS += -Wa,-adhlns=$(<:.c=.lst) CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) CFLAGS += $(CSTANDARD) CFLAGS += -DF_OSC=$(F_OSC) -CFLAGS += -DF_CPU=8000000UL +CFLAGS += -DF_CPU=16000000UL #CFLAGS += -DF_CPU=3686400UL @@ -181,7 +181,7 @@ LDFLAGS += $(PRINTF_LIB_MIN) $(SCANF_LIB) $(MATH_LIB) AVRDUDE_PROGRAMMER = stk500v2 # com1 = serial port. Use lpt1 to connect to parallel port. -AVRDUDE_PORT = /dev/ttyUSB0 # programmer connected to serial device +AVRDUDE_PORT = /dev/tty.PL2303-00002006 # programmer connected to serial device AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep @@ -194,27 +194,23 @@ AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex # Uncomment the following if you do /not/ wish a verification to be # performed after programming the device. -#AVRDUDE_NO_VERIFY = -V +AVRDUDE_NO_VERIFY = -V # Increase verbosity level. Please use this when submitting bug # reports about avrdude. See # to submit bug reports. -#AVRDUDE_VERBOSE = -v -v +AVRDUDE_VERBOSE = -v -v AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) -# -# Mega8 set to internal 4mhz -# avrdude -p atmega8 -P /dev/ttyUSB0 -c stk500v2 -U lfuse:w:0xe3:m -# +#flash_fuse: +# avrdude -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -U lfuse:w:0xfe:m +# avrdude -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) -U hfuse:w:0xd9:m -#flashmac: -# uisp -dprog=avr910 -dpart=ATmega8 -dserial=/dev/cu.PL2303-00002326 --erase -v --upload if=$(TARGET).hex - diff --git a/poc/avr_sdcard/fifo.c b/poc/avr_sdcard/fifo.c new file mode 100644 index 0000000..c06e7b4 --- /dev/null +++ b/poc/avr_sdcard/fifo.c @@ -0,0 +1,28 @@ +#include "fifo.h" + +void fifo_init(fifo_t * f, uint8_t * buffer, const uint8_t size) +{ + f->count = 0; + f->pread = f->pwrite = buffer; + f->read2end = f->write2end = f->size = size; +} + +uint8_t fifo_put(fifo_t * f, const uint8_t data) +{ + return _inline_fifo_put(f, data); +} + +uint8_t fifo_get_wait(fifo_t * f) +{ + while (!f->count); + + return _inline_fifo_get(f); +} + +int fifo_get_nowait(fifo_t * f) +{ + if (!f->count) + return -1; + + return (int) _inline_fifo_get(f); +} diff --git a/poc/avr_sdcard/fifo.h b/poc/avr_sdcard/fifo.h new file mode 100644 index 0000000..bcf9aad --- /dev/null +++ b/poc/avr_sdcard/fifo.h @@ -0,0 +1,69 @@ +#ifndef _FIFO_H_ +#define _FIFO_H_ + +#include +#include + +typedef struct { + uint8_t volatile count; // # Zeichen im Puffer + uint8_t size; // Puffer-Größe + uint8_t *pread; // Lesezeiger + uint8_t *pwrite; // Schreibzeiger + uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger +} fifo_t; + +extern void fifo_init(fifo_t *, uint8_t * buf, const uint8_t size); +extern uint8_t fifo_put(fifo_t *, const uint8_t data); +extern uint8_t fifo_get_wait(fifo_t *); +extern int fifo_get_nowait(fifo_t *); + +static inline uint8_t _inline_fifo_put(fifo_t * f, const uint8_t data) +{ + if (f->count >= f->size) + return 0; + + uint8_t *pwrite = f->pwrite; + + *(pwrite++) = data; + + uint8_t write2end = f->write2end; + + if (--write2end == 0) { + write2end = f->size; + pwrite -= write2end; + } + + f->write2end = write2end; + f->pwrite = pwrite; + + uint8_t sreg = SREG; + cli(); + f->count++; + SREG = sreg; + + return 1; +} + +static inline uint8_t _inline_fifo_get(fifo_t * f) +{ + uint8_t *pread = f->pread; + uint8_t data = *(pread++); + uint8_t read2end = f->read2end; + + if (--read2end == 0) { + read2end = f->size; + pread -= read2end; + } + + f->pread = pread; + f->read2end = read2end; + + uint8_t sreg = SREG; + cli(); + f->count--; + SREG = sreg; + + return data; +} + +#endif /* _FIFO_H_ */ diff --git a/poc/avr_sdcard/main.c b/poc/avr_sdcard/main.c index c3b5284..3a043e8 100644 --- a/poc/avr_sdcard/main.c +++ b/poc/avr_sdcard/main.c @@ -1,4 +1,3 @@ -#define F_CPU 8000000 #include #include @@ -9,37 +8,47 @@ #include "fat.h" //SREG defines -#define S_MOSI PB3 -#define S_MISO PB4 -#define S_SCK PB5 -#define S_LATCH PB2 +#define S_MOSI PB5 +#define S_MISO PB6 +#define S_SCK PB7 +#define S_LATCH PB4 //DEBUG defines -#define D_LED0 PC5 +#define D_LED0 PD6 //SRAM defines -#define R_WR PB6 -#define R_RD PB7 -#define R_DATA PORTD -#define R_DIR DDRD +#define R_WR PB1 +#define R_RD PB0 + +#define RAM_PORT PORTA +#define RAM_DIR DDRA +#define RAM_REG PINA + + +#define CTRL_PORT PORTB +#define CTR_DIR DDRB + + +#define LATCH_PORT PORTB +#define LATCH_DIR DDRB + +#define SPI_PORT PORTB +#define SPI_DIR DDRB + + +#define LED_PORT PORTD +#define LED_DIR DDRD -#define DEBUG_BUFFER_SIZE 128 #define READ_BUFFER_SIZE 512 +#define BLOCKS 512 + +#define debug(x, fmt) printf("%s:%u: %s=" fmt, __FILE__, __LINE__, #x, x) + +extern FILE uart_stdout; -uint8_t debug_buffer[DEBUG_BUFFER_SIZE]; uint8_t read_buffer[READ_BUFFER_SIZE]; -void dprintf(const uint8_t * fmt, ...) { - - va_list args; - va_start(args, fmt); - vsprintf(debug_buffer, fmt, args); - va_end(args); - uart_puts(debug_buffer); -} - - void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet){ uint16_t i,j; uint16_t sum =0; @@ -48,21 +57,22 @@ void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet){ for (j=0;j<16;j++) { sum +=packet[i+j]; } - if (!sum) + if (!sum){ + //printf("."); continue; - - dprintf("%08x:", addr + i); - for (j=0;j<16;j++) { - dprintf(" %02x", packet[i+j]); } - dprintf(" |"); + printf("%08lx:", addr + i); + for (j=0;j<16;j++) { + printf(" %02x", packet[i+j]); + } + printf(" |"); for (j=0;j<16;j++) { if (packet[i+j]>=33 && packet[i+j]<=126 ) - dprintf("%c", packet[i+j]); + printf("%c", packet[i+j]); else - dprintf("."); + printf("."); } - dprintf("|\n"); + printf("|\n"); } } @@ -70,9 +80,9 @@ void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet){ void spi_init(void) { /* Set MOSI and SCK output, all others input */ - DDRB |= ((1<>16)); spi_master_transmit((uint8_t)(addr>>8)); spi_master_transmit((uint8_t)(addr>>0)); - PORTB |= (1<>16)); spi_master_transmit((uint8_t)(addr>>8)); spi_master_transmit((uint8_t)(addr>>0)); - PORTB |= (1< #include - -#ifndef SIGNAL -#include -#endif // SIGNAL - +#include +#include #include "uart.h" +#include "fifo.h" -// Folgende Zeile einkommentieren, falls FIFO verwendet werden soll -// #include "fifo.h" - -#define BAUDRATE 38400 -#define F_CPU 8000000 - -#define nop() __asm volatile ("nop") - -#ifdef SUART_TXD - #define SUART_TXD_PORT PORTB - #define SUART_TXD_DDR DDRB - #define SUART_TXD_BIT PB1 - static volatile uint16_t outframe; -#endif // SUART_TXD - -#ifdef SUART_RXD - #define SUART_RXD_PORT PORTB - #define SUART_RXD_PIN PINB - #define SUART_RXD_DDR DDRB - #define SUART_RXD_BIT PB0 - static volatile uint16_t inframe; - static volatile uint8_t inbits, received; - - #ifdef _FIFO_H_ - #define INBUF_SIZE 4 - static uint8_t inbuf[INBUF_SIZE]; - fifo_t infifo; - #else // _FIFO_H_ - static volatile uint8_t indata; - #endif // _FIFO_H_ -#endif // SUART_RXD - - -// Initialisierung für einen ATmega8 -// Für andere AVR-Derivate sieht dies vermutlich anders aus: -// Registernamen ändern sich (zB TIMSK0 anstatt TIMSK, etc). -void uart_init() +volatile struct { - uint8_t tifr = 0; - uint8_t sreg = SREG; - cli(); + uint8_t tmr_int: 1; + uint8_t adc_int: 1; + uint8_t rx_int: 1; +} +intflags; - // Mode #4 für Timer1 - // und volle MCU clock - // IC Noise Cancel - // IC on Falling Edge - TCCR1A = 0; - TCCR1B = (1 << WGM12) | (1 << CS10) | (0 << ICES1) | (1 << ICNC1); +/* + * * Last character read from the UART. + * + */ +volatile char rxbuff; - // OutputCompare für gewünschte Timer1 Frequenz - OCR1A = (uint16_t) ((uint32_t) F_CPU/BAUDRATE); -#ifdef SUART_RXD - SUART_RXD_DDR &= ~(1 << SUART_RXD_BIT); - SUART_RXD_PORT |= (1 << SUART_RXD_BIT); - TIMSK |= (1 << TICIE1); - tifr |= (1 << ICF1) | (1 << OCF1B); -#else - TIMSK &= ~(1 << TICIE1); -#endif // SUART_RXD +FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE); -#ifdef SUART_TXD - tifr |= (1 << OCF1A); - SUART_TXD_PORT |= (1 << SUART_TXD_BIT); - SUART_TXD_DDR |= (1 << SUART_TXD_BIT); - outframe = 0; -#endif // SUART_TXD +void uart_init(void) +{ + UCSRA = _BV(U2X); /* improves baud rate error @ F_CPU = 1 MHz */ + UCSRB = _BV(TXEN)|_BV(RXEN)|_BV(RXCIE); /* tx/rx enable, rx complete intr */ + UBRRL = (F_CPU / (8 * 115200UL)) - 1; /* 9600 Bd */ - TIFR = tifr; - - SREG = sreg; } -#ifdef SUART_TXD -void uart_putc (uint8_t c) +ISR(USART_RXC_vect) { - do - { - sei(); nop(); cli(); // yield(); - } while (outframe); - - // frame = *.P.7.6.5.4.3.2.1.0.S S=Start(0), P=Stop(1), *=Endemarke(1) - outframe = (3 << 9) | (((uint8_t) c) << 1); - - TIMSK |= (1 << OCIE1A); - TIFR = (1 << OCF1A); - - sei(); -} - -void uart_puts (uint8_t *buf) -{ - while( *buf ) - uart_putc ( *buf++ ); - -} -#endif // SUART_TXD - - -#ifdef SUART_TXD -SIGNAL (SIG_OUTPUT_COMPARE1A) -{ - uint16_t data = outframe; - - if (data & 1) SUART_TXD_PORT |= (1 << SUART_TXD_BIT); - else SUART_TXD_PORT &= ~(1 << SUART_TXD_BIT); - - if (1 == data) - { - TIMSK &= ~(1 << OCIE1A); - } - - outframe = data >> 1; -} -#endif // SUART_TXD - - - -#ifdef SUART_RXD -SIGNAL (SIG_INPUT_CAPTURE1) -{ - uint16_t icr1 = ICR1; - uint16_t ocr1a = OCR1A; - - // Eine halbe Bitzeit zu ICR1 addieren (modulo OCR1A) und nach OCR1B - uint16_t ocr1b = icr1 + ocr1a/2; - if (ocr1b >= ocr1a) - ocr1b -= ocr1a; - OCR1B = ocr1b; - - TIFR = (1 << OCF1B); - TIMSK = (TIMSK & ~(1 << TICIE1)) | (1 << OCIE1B); - inframe = 0; - inbits = 0; -} -#endif // SUART_RXD - - - - -#ifdef SUART_RXD -SIGNAL (SIG_OUTPUT_COMPARE1B) -{ - uint16_t data = inframe >> 1; - - if (SUART_RXD_PIN & (1 << SUART_RXD_BIT)) - data |= (1 << 9); - - uint8_t bits = inbits+1; - - if (10 == bits) - { - if ((data & 1) == 0) - if (data >= (1 << 9)) - { -#ifdef _FIFO_H_ - _inline_fifo_put (&infifo, data >> 1); -#else - indata = data >> 1; -#endif // _FIFO_H_ - received = 1; - } - - TIMSK = (TIMSK & ~(1 << OCIE1B)) | (1 << TICIE1); - TIFR = (1 << ICF1); - } - else - { - inbits = bits; - inframe = data; + uint8_t c; + c = UDR; + if (bit_is_clear(UCSRA, FE)){ + rxbuff = c; + intflags.rx_int = 1; } } -#endif // SUART_RXD - -#ifdef SUART_RXD -#ifdef _FIFO_H_ - -uint8_t uart_getc_wait() +void uart_putc(uint8_t c) { - return (int) fifo_get_wait (&infifo); + loop_until_bit_is_set(UCSRA, UDRE); + UDR = c; } -int uart_getc_nowait() -{ - return fifo_get_nowait (&infifo); -} -#else // _FIFO_H_ - -uint8_t uart_getc_wait() +void uart_puts(const char *s) { - while (!received) {} - received = 0; - - return (uint8_t) indata; -} - -uint8_t uart_getc_nowait() -{ - if (received) - { - received = 0; - return (uint8_t) indata; + do { + uart_putc(*s); } - - return -1; + while (*s++); } -#endif // _FIFO_H_ -#endif // SUART_RXD +void uart_puts_P(PGM_P s) +{ + while (1) { + unsigned char c = pgm_read_byte(s); + s++; + if ('\0' == c) + break; + uart_putc(c); + } +} + +static int uart_stream(char c, FILE *stream) +{ + if (c == '\n') + uart_putc('\r'); + loop_until_bit_is_set(UCSRA, UDRE); + UDR = c; + return 0; +} diff --git a/poc/avr_sdcard/uart.h b/poc/avr_sdcard/uart.h index 8fa2209..7af251f 100644 --- a/poc/avr_sdcard/uart.h +++ b/poc/avr_sdcard/uart.h @@ -1,23 +1,18 @@ #ifndef _UART_H_ #define _UART_H_ -#define SUART_TXD -#define SUART_RXD +#define CR "\r\n" + #include +#include #include -void uart_init(); +void uart_init(void); +void uart_putc(const uint8_t); +void uart_puts(const char *s); +void uart_puts_P(PGM_P s); +static int uart_stream(char c, FILE *stream); -#ifdef SUART_TXD - void uart_putc(uint8_t byte); - void uart_puts(uint8_t *buf); -#endif // SUART_RXD - -#ifdef SUART_RXD - uint8_t uart_getc_wait(); - uint8_t uart_getc_nowait(); -#endif // SUART_RXD - -#endif /* _UART_H_ */ +#endif /* _UART_H_ */