o ported the code to stk 500 using a mega16

This commit is contained in:
optixx 2009-03-15 22:10:22 +01:00
parent 9a40d078dd
commit 04c6c64e12
7 changed files with 275 additions and 307 deletions

View File

@ -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 <http://savannah.nongnu.org/projects/avrdude>
# 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

28
poc/avr_sdcard/fifo.c Normal file
View File

@ -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);
}

69
poc/avr_sdcard/fifo.h Normal file
View File

@ -0,0 +1,69 @@
#ifndef _FIFO_H_
#define _FIFO_H_
#include <avr/io.h>
#include <avr/interrupt.h>
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_ */

View File

@ -1,4 +1,3 @@
#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>
@ -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<<S_MOSI) | (1<<S_SCK) | (1<<S_LATCH));
DDRB &= ~(1<<S_MISO);
PORTB |= (1<<S_MISO);
SPI_DIR |= ((1<<S_MOSI) | (1<<S_SCK) | (1<<S_LATCH));
SPI_DIR &= ~(1<<S_MISO);
SPI_PORT |= (1<<S_MISO);
/* Enable SPI, Master*/
SPCR = ((1<<SPE) | (1<<MSTR));
}
@ -90,64 +100,70 @@ uint8_t sram_read(uint32_t addr)
{
uint8_t byte;
DDRD=0x00;
PORTD=0xff;
RAM_DIR = 0x00;
RAM_PORT = 0xff;
PORTB |= (1<<R_RD);
PORTB |= (1<<R_WR);
CTRL_PORT |= (1<<R_RD);
CTRL_PORT |= (1<<R_WR);
spi_master_transmit((uint8_t)(addr>>16));
spi_master_transmit((uint8_t)(addr>>8));
spi_master_transmit((uint8_t)(addr>>0));
PORTB |= (1<<S_LATCH);
PORTB &= ~(1<<S_LATCH);
PORTB &= ~(1<<R_RD);
LATCH_PORT |= (1<<S_LATCH);
LATCH_PORT &= ~(1<<S_LATCH);
CTRL_PORT &= ~(1<<R_RD);
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
byte = PIND;
PORTB |= (1<<R_RD);
DDRD=0x00;
PORTD=0x00;
byte = RAM_REG;
CTRL_PORT |= (1<<R_RD);
RAM_DIR =0x00;
RAM_PORT =0x00;
return byte;
}
void sram_write(uint32_t addr, uint8_t data)
{
DDRD=0xff;
RAM_DIR = 0xff;
PORTB |= (1<<R_RD);
PORTB |= (1<<R_WR);
CTRL_PORT |= (1<<R_RD);
CTRL_PORT |= (1<<R_WR);
spi_master_transmit((uint8_t)(addr>>16));
spi_master_transmit((uint8_t)(addr>>8));
spi_master_transmit((uint8_t)(addr>>0));
PORTB |= (1<<S_LATCH);
PORTB &= ~(1<<S_LATCH);
LATCH_PORT |= (1<<S_LATCH);
LATCH_PORT &= ~(1<<S_LATCH);
PORTB &= ~(1<<R_WR);
PORTD=data;
CTRL_PORT &= ~(1<<R_WR);
PORTB |= (1<<R_WR);
RAM_PORT = data;
CTRL_PORT |= (1<<R_WR);
DDRD=0x00;
PORTD=0x00;
RAM_DIR = 0x00;
RAM_PORT = 0x00;
}
void sram_init(void){
DDRD=0x00;
PORTD=0x00;
DDRB |= ((1<<R_WR) | (1<<R_RD));
PORTB |= (1<<R_RD);
PORTB |= (1<<R_WR);
RAM_DIR = 0x00;
RAM_PORT = 0x00;
DDRC |= (1<<D_LED0);
CTR_DIR |= ((1<<R_WR) | (1<<R_RD));
CTRL_PORT |= (1<<R_RD);
CTRL_PORT |= (1<<R_WR);
LED_PORT |= (1<<D_LED0);
}
@ -163,7 +179,7 @@ void sram_copy(uint32_t addr,uint8_t *src, uint32_t len){
uint32_t i;
uint8_t *ptr = src;
for (i=addr; i<(addr + len);i++ )
sram_write(addr, *ptr++);
sram_write(i, *ptr++);
}
void sram_read_buffer(uint32_t addr,uint8_t *dst, uint32_t len){
@ -171,7 +187,7 @@ void sram_read_buffer(uint32_t addr,uint8_t *dst, uint32_t len){
uint32_t i;
uint8_t *ptr = dst;
for (i=addr; i<(addr + len);i++ ){
*ptr = sram_read(addr);
*ptr = sram_read(i);
ptr++;
}
}
@ -187,27 +203,35 @@ int main(void)
uart_init();
stdout = &uart_stdout;
sram_init();
dprintf("sram_init\n");
printf("sram_init\n");
spi_init();
dprintf("spi_init\n");
printf("spi_init\n");
/*
sram_clear(0x000000, 0x400000);
dprintf("sram_clear\n");
printf("sram_clear\n");
*/
//printf("read 0x0f0f\n");
//sram_read(0x0f0f);
//printf("write 0x0f0f\n");
//sram_write(0x0f0f,0xaa);
//while(1);
while ( mmc_init() !=0) {
dprintf("no sdcard..\n\r");
printf("no sdcard..\n");
}
dprintf("mmc_init\n\r");
printf("mmc_init\n");
fat_init(read_buffer);
dprintf("fat_init\n\r");
printf("fat_init\n");
rom_addr = 0x000000;
dprintf("look for sprite.smc\n\r");
printf("look for sprite.smc\n");
if (fat_search_file((uint8_t*)"sprite.smc",
&fat_cluster,
@ -215,17 +239,19 @@ int main(void)
&fat_attrib,
read_buffer) == 1) {
for (uint16_t block_cnt=0; block_cnt<512; block_cnt++) {
for (uint16_t block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
fat_read_file (fat_cluster,read_buffer,block_cnt);
dprintf("Read Block %i addr 0x%06\n",block_cnt,rom_addr);
printf("Read Block %i addr 0x%06lx\n",block_cnt,rom_addr);
//dump_packet(rom_addr,512,read_buffer);
sram_copy(rom_addr,read_buffer,512);
rom_addr += 512;
}
}
rom_addr = 0x000000;
for (uint16_t block_cnt=0; block_cnt<512; block_cnt++) {
for (uint16_t block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
sram_read_buffer(rom_addr,read_buffer,512);
printf("Block %i\n",block_cnt);
dump_packet(rom_addr,512,read_buffer);
rom_addr += 512;
}

View File

@ -14,15 +14,13 @@ Copyright (C) 2004 Ulrich Radig
#define MMC_Write PORTC //Port an der die MMC/SD-Karte angeschlossen ist also des SPI
#define MMC_Read PINC
#define MMC_Direction_REG DDRC
#define MMC_Direction_REG DDRC
#if defined (__AVR_ATmega8__)
#define MMC_CS PC0
#define MMC_DO PC1
#define MMC_DI PC2
#define MMC_CS PC7
#define MMC_DO PC5
#define MMC_DI PC6
#define MMC_CLK PC3
#define SPI_SS 4 //Nicht Benutz muß aber definiert werden
#endif
#define SPI_SS PC4 //Nicht Benutz muß aber definiert werden
//Prototypes

View File

@ -1,223 +1,79 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#ifndef SIGNAL
#include <avr/signal.h>
#endif // SIGNAL
#include <avr/pgmspace.h>
#include <stdio.h>
#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()
void uart_puts(const char *s)
{
return fifo_get_nowait (&infifo);
}
#else // _FIFO_H_
uint8_t uart_getc_wait()
{
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;
}

View File

@ -1,23 +1,18 @@
#ifndef _UART_H_
#define _UART_H_
#define SUART_TXD
#define SUART_RXD
#define CR "\r\n"
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdio.h>
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_ */