diff --git a/main.c b/main.c index da5c7a6..7633570 100644 --- a/main.c +++ b/main.c @@ -61,6 +61,18 @@ #define VERSION_HIGH '0' #define VERSION_LOW '7' +/* MCU frequency */ +#define F_CPU 7372800 + +/* UART Baudrate */ +#define BAUDRATE 115200 + +/* use "Double Speed Operation" */ +//#define UART_DOUBLESPEED + +/* use second UART on mega128 / can128 */ +//#define UART_USE_SECOND + #include #include #include @@ -68,23 +80,6 @@ #include #include -#ifndef XTAL -#warning "Set XTAL in Makefile" -#endif - -#ifdef START_BOOTICE -#warning "Using START_BOOTICE" -#if XTAL == 7372800 -#else -#warning "BOOTICE mode - External Crystal/Oszillator must be 7,3728 MHz" -#undef XTAL -#define XTAL 7372800 -#endif -#endif - -// UART handling - some definitions from P. Fleury's Library - thanks -#include "uart.h" - /* enable/disable readout of fuse and lock-bits (will not work for Mega169 since not supported by AVRPROG 1.37 */ #define ENABLEREADFUSELOCK @@ -109,6 +104,18 @@ unsigned char gBuffer[UART_RX_BUFFER_SIZE]; uint32_t address; unsigned char device; +void sendchar(char data) +{ + loop_until_bit_is_set(UART_STATUS, UART_TXREADY); + UART_DATA = data; +} + +char recvchar(void) +{ + loop_until_bit_is_set(UART_STATUS, UART_RXREADY); + return UART_DATA; +} + unsigned char BufferLoad(unsigned int size, unsigned char mem) { unsigned int data, cnt; @@ -116,7 +123,7 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem) for (cnt = 0; cnt < UART_RX_BUFFER_SIZE; cnt++) { if (cnt < size) - gBuffer[cnt] = recchar(); + gBuffer[cnt] = recvchar(); else gBuffer[cnt] = 0xFF; } @@ -259,8 +266,16 @@ int main(void) BLDDR &= ~(1<>8) & 0xFF; + UART_BAUD_LOW = (UART_CALC_BAUDRATE(BAUDRATE) & 0xFF); + +#ifdef UART_DOUBLESPEED + UART_STATUS = UART_DOUBLE; +#endif + + UART_CTRL = UART_CTRL_DATA; + UART_CTRL2 = UART_CTRL2_DATA; #ifdef START_POWERSAVE /* @@ -311,34 +326,31 @@ int main(void) // Timer-Setup for ATmega8 // - verify that the configuration is valid for the target AVR - #define F_OSC XTAL - #define UART0_STATUS UCSRA - #define UART0_DATA UDR #define MY_WAIT 900 // wait ca 1 sec (900ms) TCCR1A = 0; // timer setup // F_OSC / 8 / 1000 -> 1ms - #if (((F_OSC / 8 / 1000)*MY_WAIT) < 65535) + #if (((F_CPU / 8 / 1000)*MY_WAIT) < 65535) #warning Information: setting prescaler to 8 - #define WAIT_VALUE ((F_OSC / 8 / 1000)*MY_WAIT) + #define WAIT_VALUE ((F_CPU / 8 / 1000)*MY_WAIT) TCCR1B |= _BV(CS01); - #elif ((((F_OSC / 64 / 1000)*MY_WAIT) < 65535)) + #elif ((((F_CPU / 64 / 1000)*MY_WAIT) < 65535)) #warning Information: setting prescaler to 64 - #define WAIT_VALUE ((F_OSC / 64 / 1000)*MY_WAIT) + #define WAIT_VALUE ((F_CPU / 64 / 1000)*MY_WAIT) TCCR1B |= _BV(CS01)| _BV(CS00); - #elif ((((F_OSC / 256 / 1000)*MY_WAIT) < 65535)) + #elif ((((F_CPU / 256 / 1000)*MY_WAIT) < 65535)) #warning Information: setting prescaler to 256 - #define WAIT_VALUE ((F_OSC / 256 / 1000)*MY_WAIT) + #define WAIT_VALUE ((F_CPU / 256 / 1000)*MY_WAIT) TCCR1B |= _BV(CS02); - #else //((((F_OSC / 1024 / 1000)*MY_WAIT) < 65535)) + #else //((((F_CPU / 1024 / 1000)*MY_WAIT) < 65535)) #warning Information: setting prescaler to 1024 - #define WAIT_VALUE ((F_OSC / 1024 / 1000)*MY_WAIT) + #define WAIT_VALUE ((F_CPU / 1024 / 1000)*MY_WAIT) TCCR1B |= _BV(CS00) |_BV(CS02); //1024 prescaler #endif while (1) { - if (UART0_STATUS & (1<= WAIT_VALUE){ @@ -360,15 +372,15 @@ int main(void) #endif for(;;) { - val = recchar(); + val = recvchar(); // Autoincrement? if (val == 'a') { sendchar('Y'); // Autoincrement is quicker //write address } else if (val == 'A') { - address = recchar(); //read address 8 MSB - address = (address<<8) | recchar(); + address = recvchar(); //read address 8 MSB + address = (address<<8) | recvchar(); address = address<<1; // !! convert from word address to byte address sendchar('\r'); @@ -381,15 +393,15 @@ int main(void) // Start buffer load } else if (val == 'B') { - tempi = recchar() << 8; // Load high byte of buffersize - tempi |= recchar(); // Load low byte of buffersize - val = recchar(); // Load memory type ('E' or 'F') + tempi = recvchar() << 8; // Load high byte of buffersize + tempi |= recvchar(); // Load low byte of buffersize + val = recvchar(); // Load memory type ('E' or 'F') sendchar (BufferLoad(tempi, val)); // Start downloading of buffer // Block read } else if (val == 'g') { - tempi = (recchar() << 8) | recchar(); - val = recchar(); // Get memtype + tempi = (recvchar() << 8) | recvchar(); + val = recvchar(); // Get memtype BlockRead(tempi, val); // Perform the block read // Chip erase @@ -461,12 +473,12 @@ int main(void) // clear and set LED ignored } else if ((val == 'x') || (val == 'y')) { - recchar(); + recvchar(); sendchar('\r'); // set device } else if (val == 'T') { - device = recchar(); + device = recvchar(); sendchar('\r'); // Return software identifier diff --git a/makefile b/makefile index 82f278d..8a624cb 100644 --- a/makefile +++ b/makefile @@ -39,11 +39,6 @@ MCU = atmega8 ## MCU = atmega32 ## MCU = at90can128 -XTAL=16000000 -#XTAL=2000000UL -#BAUDRATE=115200 -BAUDRATE=9600UL - #Pin "STARTPIN" on port "STARTPORT" in this port has to grounded # (active low) to start the bootloader BLPORT = PORTB @@ -62,7 +57,7 @@ BLPNUM = PINB0 # * BOOTICE-Mode - to flash the JTAGICE upgrade.ebn file. # No startup-sequence in this mode. Jump directly to the # parser-loop on reset -# XTAL in BOOTICEMODE must be 7372800 Hz to be compatible +# F_CPU in BOOTICEMODE must be 7372800 Hz to be compatible # with the org. JTAGICE-Firmware */ # * WAIT-mode waits 1 sec for the S command if nothing is recived # then the user prog is started .. @@ -188,7 +183,7 @@ TARGET = main # List C source files here. (C dependencies are automatically generated.) -SRC = $(TARGET).c uart.c +SRC = $(TARGET).c # List Assembler source files here. @@ -226,7 +221,7 @@ CSTANDARD = -std=gnu99 # Place -D or -U options here CDEFS = -DBLPORT=$(BLPORT) -DBLDDR=$(BLDDR) -DBLPIN=$(BLPIN) -DBLPNUM=$(BLPNUM) -CDEFS += -D$(STARTMODE) -DBOOTSIZE=$(BOOTSIZE) -DBAUDRATE=$(BAUDRATE) +CDEFS += -D$(STARTMODE) -DBOOTSIZE=$(BOOTSIZE) ifdef XTAL CDEFS += -DXTAL=$(XTAL) endif diff --git a/mega128.h b/mega128.h index 293691c..9379969 100644 --- a/mega128.h +++ b/mega128.h @@ -7,4 +7,37 @@ #define SIG_BYTE2 0x97 #define SIG_BYTE1 0x02 + +#ifdef UART_DOUBLESPEED +#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate) *8) -1) +#else +#define UART_CALC_BAUDRATE(baudRate) ((uint32_t)(F_CPU) / ((uint32_t)(baudRate)*16) -1) +#endif + +#ifndef UART_USE_SECOND +#define UART_BAUD_HIGH UBRR0H +#define UART_BAUD_LOW UBRR0L +#define UART_STATUS UCSR0A +#define UART_TXREADY UDRE0 +#define UART_RXREADY RXC0 +#define UART_DOUBLE U2X0 +#define UART_CTRL UCSR0B +#define UART_CTRL_DATA ((1< - -/* most of the definitions borrowed from Peter Fleury's UART-Library - extende for control-register C and ATmega169 */ - -#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \ - || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \ - || defined(__AVR_ATmega323__) - /* ATMega with one USART */ - #define ATMEGA_USART - #define UART0_UBRR_HIGH UBRRH - #define UART0_UBRR_LOW UBRRL - #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV - #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA - #define UART0_STATUS UCSRA - #define UART0_CONTROL UCSRB - #define UART0_DATA UDR - #define UART0_UDRIE UDRIE -#elif defined(__AVR_ATmega162__) - /* ATMega with two USART */ - #define ATMEGA_USART0 - #define ATMEGA_USART1 - #define UART0_UBRR_HIGH UBRR0H - #define UART0_UBRR_LOW UBRR0L - #define UART1_UBRR_HIGH UBRR1H - #define UART1_UBRR_LOW UBRR1L - #define UART0_RECEIVE_INTERRUPT SIG_USART0_RECV - #define UART1_RECEIVE_INTERRUPT SIG_USART1_RECV - #define UART0_TRANSMIT_INTERRUPT SIG_USART0_DATA - #define UART1_TRANSMIT_INTERRUPT SIG_USART1_DATA - #define UART0_STATUS UCSR0A - #define UART0_CONTROL UCSR0B - #define UART0_CONTROL2 UCSR0C - #define UART0_DATA UDR0 - #define UART0_UDRIE UDRIE0 - #define UART1_STATUS UCSR1A - #define UART1_CONTROL UCSR1B - #define UART1_CONTROL2 UCSR1C - #define UART1_DATA UDR1 - #define UART1_UDRIE UDRIE1 -#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__) - /* ATMega with two USART */ - #define ATMEGA_USART0 - #define ATMEGA_USART1 - #define UART0_UBRR_HIGH UBRR0H - #define UART0_UBRR_LOW UBRR0L - #define UART1_UBRR_HIGH UBRR1H - #define UART1_UBRR_LOW UBRR1L - #define UART0_RECEIVE_INTERRUPT SIG_UART0_RECV - #define UART1_RECEIVE_INTERRUPT SIG_UART1_RECV - #define UART0_TRANSMIT_INTERRUPT SIG_UART0_DATA - #define UART1_TRANSMIT_INTERRUPT SIG_UART1_DATA - #define UART0_STATUS UCSR0A - #define UART0_CONTROL UCSR0B - #define UART0_CONTROL2 UCSR0C - #define UART0_DATA UDR0 - #define UART0_UDRIE UDRIE0 - #define UART1_STATUS UCSR1A - #define UART1_CONTROL UCSR1B - #define UART1_CONTROL2 UCSR1C - #define UART1_DATA UDR1 - #define UART1_UDRIE UDRIE1 -#elif defined(__AVR_ATmega169__) - #define ATMEGA_USART - #define UART0_UBRR_HIGH UBRR0H - #define UART0_UBRR_LOW UBRR0L - // TODO #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV - // TODO #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA - #define UART0_STATUS UCSR0A - #define UART0_CONTROL UCSR0B - #define UART0_CONTROL2 UCSR0C - #define UART0_DATA UDR0 - #define UART0_DOUBLEAVAIL - // TODO #define UART0_UDRIE UDRIE -#else - #error "Processor type not supported in uart.c !" -#endif - -void USART_Init(unsigned int baudrate, unsigned char doublespeed) -{ - // Set baud rate - UART0_UBRR_HIGH = (unsigned char)(baudrate>>8); - UART0_UBRR_LOW = (unsigned char)baudrate; - - // Enable 2x speed - TODO adopt to all uCs - #ifdef UART0_DOUBLEAVAIL - if (doublespeed) UCSR0A = (1<