diff --git a/chipdef.h b/chipdef.h index 40f1e94..4c86cc9 100644 --- a/chipdef.h +++ b/chipdef.h @@ -1,190 +1,190 @@ - -#ifndef CHIPDEF_H -#define CHIPDEF_H - -#include - -// TODO: make use of RAMEND in the avr-libc io-files and -// avoid a lot of by-device definitions here - -#if defined(__AVR_ATmega169__) - #define sig_byte3 0x1E - #define sig_byte2 0x94 - #define sig_byte1 0x05 - - #define devtype 0x79 // Mega 169 device code - -// #define PAGESIZE 128 // 2*64 Words = Size in Bytes - - #ifdef _B128 - #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B256 - #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B512 - #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B1024 - #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B2048 - #error "_B2048 not suppoted on this device" - #endif - -#elif defined(__AVR_ATmega16__) - - #define sig_byte3 0x1E - #define sig_byte2 0x94 - #define sig_byte1 0x03 - - #define devtype 0x75 // Mega16 device code - -// #define PAGESIZE 128 // Size in Bytes - - #ifdef _B128 - #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B256 - #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B512 - #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B1024 - #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B2048 - #error "_B2048 not suppoted on this device" - #endif - -#elif defined(__AVR_ATmega8__) - - #define sig_byte3 0x1E - #define sig_byte2 0x93 - #define sig_byte1 0x07 - + +#ifndef CHIPDEF_H +#define CHIPDEF_H + +#include + +// TODO: make use of RAMEND in the avr-libc io-files and +// avoid a lot of by-device definitions here + +#if defined(__AVR_ATmega169__) + #define sig_byte3 0x1E + #define sig_byte2 0x94 + #define sig_byte1 0x05 + + #define devtype 0x79 // Mega 169 device code + +// #define PAGESIZE 128 // 2*64 Words = Size in Bytes + + #ifdef _B128 + #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B256 + #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B512 + #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B1024 + #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B2048 + #error "_B2048 not suppoted on this device" + #endif + +#elif defined(__AVR_ATmega16__) + + #define sig_byte3 0x1E + #define sig_byte2 0x94 + #define sig_byte1 0x03 + + #define devtype 0x75 // Mega16 device code + +// #define PAGESIZE 128 // Size in Bytes + + #ifdef _B128 + #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B256 + #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B512 + #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B1024 + #define APP_PAGES ((2*8192 / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B2048 + #error "_B2048 not suppoted on this device" + #endif + +#elif defined(__AVR_ATmega8__) + + #define sig_byte3 0x1E + #define sig_byte2 0x93 + #define sig_byte1 0x07 + //#define devtype 0x77 // Mega8 boot device code - #define devtype 0x76 // Mega8 boot device code - -// #define PAGESIZE 64 // Size in Bytes - - #ifdef _B128 - #define APP_PAGES ((2*4096 / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B256 - #define APP_PAGES ((2*4096 / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B512 - #define APP_PAGES ((2*4096 / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B1024 - #define APP_PAGES ((2*4096 / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B2048 - #error "_B2048 not suppoted on this device" - #endif - -#elif defined(__AVR_ATmega32__) - - #define sig_byte3 0x1E - #define sig_byte2 0x95 - #define sig_byte1 0x02 - - #define devtype 0x73 // Mega32 device code - -// #define PAGESIZE 128 // Size in Bytes - - #ifdef _B128 - #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B256 - #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B512 - #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B1024 - #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B2048 - #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - -#elif defined(__AVR_ATmega128__) - - #define sig_byte3 0x1E - #define sig_byte2 0x97 - #define sig_byte1 0x02 - - #define devtype 0x44 // - -// #define PAGESIZE 128 // Size in Bytes - - #ifdef _B512 - #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B1024 - #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B2048 - #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B4096 - #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*4096 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - -#elif defined(__AVR_AT90CAN128__) - - #define sig_byte3 0x1E - #define sig_byte2 0x97 - #define sig_byte1 0x81 - - #define devtype 0x43 /* Dummy device code for now, must be same as - used in avrdude.conf */ - -// #define PAGESIZE 128 // Size in Bytes - - #ifdef _B512 - #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B1024 - #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B2048 - #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - #ifdef _B4096 - #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*4096 / SPM_PAGESIZE )) - #define APP_END APP_PAGES * SPM_PAGESIZE - #endif - -#else - #error "no definition for MCU available in chipdef.h" -#endif - -#endif + #define devtype 0x76 // Mega8 boot device code + +// #define PAGESIZE 64 // Size in Bytes + + #ifdef _B128 + #define APP_PAGES ((2*4096 / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B256 + #define APP_PAGES ((2*4096 / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B512 + #define APP_PAGES ((2*4096 / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B1024 + #define APP_PAGES ((2*4096 / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B2048 + #error "_B2048 not suppoted on this device" + #endif + +#elif defined(__AVR_ATmega32__) + + #define sig_byte3 0x1E + #define sig_byte2 0x95 + #define sig_byte1 0x02 + + #define devtype 0x73 // Mega32 device code + +// #define PAGESIZE 128 // Size in Bytes + + #ifdef _B128 + #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B256 + #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B512 + #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B1024 + #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B2048 + #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + +#elif defined(__AVR_ATmega128__) + + #define sig_byte3 0x1E + #define sig_byte2 0x97 + #define sig_byte1 0x02 + + #define devtype 0x44 // + +// #define PAGESIZE 128 // Size in Bytes + + #ifdef _B512 + #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B1024 + #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B2048 + #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B4096 + #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*4096 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + +#elif defined(__AVR_AT90CAN128__) + + #define sig_byte3 0x1E + #define sig_byte2 0x97 + #define sig_byte1 0x81 + + #define devtype 0x43 /* Dummy device code for now, must be same as + used in avrdude.conf */ + +// #define PAGESIZE 128 // Size in Bytes + + #ifdef _B512 + #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B1024 + #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B2048 + #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + #ifdef _B4096 + #define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*4096 / SPM_PAGESIZE )) + #define APP_END APP_PAGES * SPM_PAGESIZE + #endif + +#else + #error "no definition for MCU available in chipdef.h" +#endif + +#endif diff --git a/lowlevel.c b/lowlevel.c index f508bd0..ce715a9 100644 --- a/lowlevel.c +++ b/lowlevel.c @@ -1,27 +1,27 @@ -// -// Low-level routines to read lock and fuse-bytes -// -// Copyright (C) 2/2005 Martin Thomas, Kaiserslautern, Germany -// - -#include "lowlevel.h" - -unsigned char read_fuse_lock(unsigned short addr, unsigned char mode) -{ - unsigned char retval; - - asm volatile - ( - "movw r30, %3\n\t" /* Z to addr */ \ - "sts %0, %2\n\t" /* set mode in SPM_REG */ \ - "lpm\n\t" /* load fuse/lock value into r0 */ \ - "mov %1,r0\n\t" /* save return value */ \ - : "=m" (SPM_REG), - "=r" (retval) - : "r" (mode), - "r" (addr) - : "r30", "r31", "r0" - ); - return retval; -} - +// +// Low-level routines to read lock and fuse-bytes +// +// Copyright (C) 2/2005 Martin Thomas, Kaiserslautern, Germany +// + +#include "lowlevel.h" + +unsigned char read_fuse_lock(unsigned short addr, unsigned char mode) +{ + unsigned char retval; + + asm volatile + ( + "movw r30, %3\n\t" /* Z to addr */ \ + "sts %0, %2\n\t" /* set mode in SPM_REG */ \ + "lpm\n\t" /* load fuse/lock value into r0 */ \ + "mov %1,r0\n\t" /* save return value */ \ + : "=m" (SPM_REG), + "=r" (retval) + : "r" (mode), + "r" (addr) + : "r30", "r31", "r0" + ); + return retval; +} + diff --git a/lowlevel.h b/lowlevel.h index 2c8ed21..f268a56 100644 --- a/lowlevel.h +++ b/lowlevel.h @@ -1,18 +1,18 @@ -#ifndef LOWLEVEL_H -#define LOWLEVEL_H - -#include - -/* Check for SPM Control Register in processor. */ -#if defined (SPMCSR) -# define SPM_REG SPMCSR -#elif defined (SPMCR) -# define SPM_REG SPMCR -#else -# error AVR processor does not provide bootloader support! -#endif - -unsigned char read_fuse_lock(unsigned short addr, unsigned char mode); - - -#endif +#ifndef LOWLEVEL_H +#define LOWLEVEL_H + +#include + +/* Check for SPM Control Register in processor. */ +#if defined (SPMCSR) +# define SPM_REG SPMCSR +#elif defined (SPMCR) +# define SPM_REG SPMCR +#else +# error AVR processor does not provide bootloader support! +#endif + +unsigned char read_fuse_lock(unsigned short addr, unsigned char mode); + + +#endif diff --git a/main.c b/main.c index 788fd92..4f2e65f 100644 --- a/main.c +++ b/main.c @@ -2,14 +2,14 @@ * * AVRPROG compatible boot-loader * Version : 0.75 (Feb. 2006) -* Compiler : avr-gcc 3.4.1 / avr-libc 1.0.2 +* Compiler : avr-gcc 3.4.1 / avr-libc 1.0.2 * size : depends on features and startup ( minmal features < 512 words) * by : Martin Thomas, Kaiserslautern, Germany * eversmith@heizung-thomas.de * * License : Copyright (c) 2005 Martin Thomas -* Free to use. You have to mention the copyright -* owners in source-code and documentation of derived +* Free to use. You have to mention the copyright +* owners in source-code and documentation of derived * work. No warranty. * * Additional code and improvements contributed by: @@ -22,11 +22,11 @@ * - based on the Butterfly Bootloader-Code * Copyright (C) 1996-1998 Atmel Corporation * Author(s) : BBrandal, PKastnes, ARodland, LHM -* The orignal code has been made available by ATMEL together with the -* Butterfly application code. Since ATMEL.NO had no problem with +* The orignal code has been made available by ATMEL together with the +* Butterfly application code. Since ATMEL.NO had no problem with * the application gcc-port they hopefully will not have any concerns about * publishing this port. A lot of things have been change but the ATMEL -* "skeleton" is still in this code. Make sure to keep the copyright notice +* "skeleton" is still in this code. Make sure to keep the copyright notice * in derived work to avoid trouble. * * - based on boot.h from the avr-libc (c) Eric Weddington @@ -36,19 +36,19 @@ * The boot interrupt vector is included (this bootloader is completly in * ".text" section). If you need this space for further functions you have to * add a separate section for the bootloader-functions and add an attribute -* for this section to _all_ function prototypes of functions in the loader. -* With this the interrupt vector will be placed at .0000 and the bootloader +* for this section to _all_ function prototypes of functions in the loader. +* With this the interrupt vector will be placed at .0000 and the bootloader * code (without interrupt vector) at the adress you define in the linker * options for the newly created section. See the avr-libc FAQ, the avr- * libc's avr/boot.h documentation and the makefile for further details. * -* See the makefile for information how to adopt the linker-settings to +* See the makefile for information how to adopt the linker-settings to * the selected Boot Size (_Bxxx below) * * With BOOT_SIMPLE this bootloader has 0x3DE bytes size and should fit * into a 512word bootloader-section. * -* Set AVR clock-frequency and the baudrate below, set MCU-type in +* Set AVR clock-frequency and the baudrate below, set MCU-type in * makefile. * ****************************************************************************/ @@ -87,11 +87,11 @@ // UART handling - some definitions from P. Fleury's Library - thanks #include "uart.h" -/* enable/disable readout of fuse and lock-bits +/* enable/disable readout of fuse and lock-bits (will not work for Mega169 since not supported by AVRPROG 1.37 */ -#define ENABLEREADFUSELOCK +#define ENABLEREADFUSELOCK -/* enable/disable write of lock-bits +/* enable/disable write of lock-bits WARNING: lock-bits can not be reseted by bootloader (as far as I know) Only protection no unprotection, "chip erase" from bootloader only clears the flash but does no real "chip erase" (this is not possible @@ -131,33 +131,33 @@ int main(void) { unsigned tempi; char val; - + #ifdef START_POWERSAVE - char OK = 1; + char OK = 1; #endif - + cli(); - - MCUCR = (1<= WAIT_VALUE){ BLPORT &= ~(1< address ) { boot_page_erase(address); // Perform page erase @@ -305,7 +305,7 @@ int main(void) } } boot_rww_enable(); - sendchar('\r'); + sendchar('\r'); } else if(val=='E') //Exit upgrade @@ -313,11 +313,11 @@ int main(void) wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset sendchar('\r'); } - + #ifdef WRITELOCKBITS #warning "Extension 'WriteLockBits' enabled" // TODO: does not work reliably - else if(val=='l') // write lockbits + else if(val=='l') // write lockbits { if (device == devtype) { @@ -328,22 +328,22 @@ int main(void) sendchar('\r'); } #endif - - else if(val=='P') // Enter programming mode + + else if(val=='P') // Enter programming mode { sendchar('\r'); } - + else if(val=='L') // Leave programming mode - { + { sendchar('\r'); } - + else if (val=='p') // return programmer type { sendchar('S'); // always serial programmer - } - + } + #ifdef ENABLEREADFUSELOCK #warning "Extension 'ReadFuseLock' enabled" else if(val=='F') // read "low" fuse bits @@ -352,23 +352,23 @@ int main(void) } else if(val=='r') // read lock bits - { + { sendchar( read_fuse_lock(0x0001, _BV(BLBSET)|_BV(SPMEN)) ); - } + } else if(val=='N') // read high fuse bits { sendchar( read_fuse_lock(0x0003,_BV(BLBSET)|_BV(SPMEN)) ); - } + } else if(val=='Q') // read extended fuse bits { sendchar( read_fuse_lock(0x0002,_BV(BLBSET)|_BV(SPMEN)) ); } -#endif +#endif // end of ENABLEREADFUSELOCK section - else if(val=='t') // Return device type + else if(val=='t') // Return device type { sendchar(devtype); sendchar(0); @@ -379,37 +379,37 @@ int main(void) recchar(); sendchar('\r'); } - + else if (val=='T') // set device { device = recchar(); sendchar('\r'); } - - else if (val=='S') // Return software identifier + + else if (val=='S') // Return software identifier { send_boot(); - } - + } + else if (val=='V') // Return Software Version { sendchar(VERSION_HIGH); sendchar(VERSION_LOW); - } + } else if (val=='s') // Return Signature Byte { sendchar(sig_byte1); sendchar(sig_byte2); sendchar(sig_byte3); - } + } else if(val != 0x1b) /* ESC */ { sendchar('?'); } } // end of "parser" for-loop - + return 0; } @@ -418,7 +418,7 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem) { unsigned int data, cnt; uint32_t tempaddress; - + for (cnt=0; cnt>=1; @@ -468,10 +468,10 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem) EEARH = (address >> 8); address++; // Select next byte EEDR=gBuffer[cnt++]; - + EECR |= (1<>=1; // not needed here - hmm, somehow inconsistant TODO @@ -512,7 +512,7 @@ void BlockRead(unsigned int size, unsigned char mem) data = pgm_read_word_near((uint16_t)address); #endif sendchar((unsigned char)data); //send LSB - sendchar((unsigned char)(data >> 8)); //send MSB + sendchar((unsigned char)(data >> 8)); //send MSB address += 2; // Select next word in memory size -= 2; // Subtract two bytes from number of bytes to read } while (size); // Repeat until all block has been read diff --git a/makefile b/makefile index 8853d87..6636253 100644 --- a/makefile +++ b/makefile @@ -44,7 +44,7 @@ XTAL=16000000 #BAUDRATE=115200 BAUDRATE=9600UL -#Pin "STARTPIN" on port "STARTPORT" in this port has to grounded +#Pin "STARTPIN" on port "STARTPORT" in this port has to grounded # (active low) to start the bootloader BLPORT = PORTB BLDDR = DDRB @@ -52,8 +52,8 @@ BLPIN = PINB BLPNUM = PINB0 # Select startup-mode -# * SIMPLE-Mode - Jump to bootloader main BL-loop if key is -# pressed (Pin grounded) "during" reset or jump to the +# * SIMPLE-Mode - Jump to bootloader main BL-loop if key is +# pressed (Pin grounded) "during" reset or jump to the # application if the pin is not grounded (=pulled up by # internal pull-up-resistor) # * POWERSAVE-Mode - Startup is separated in two loops @@ -61,7 +61,7 @@ BLPNUM = PINB0 # is on the chip. Needs more memory # * BOOTICE-Mode - to flash the JTAGICE upgrade.ebn file. # No startup-sequence in this mode. Jump directly to the -# parser-loop on reset +# parser-loop on reset # XTAL 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 @@ -74,43 +74,43 @@ STARTMODE=START_WAIT #/* Select Boot Size in Words (select one, comment out the others) */ ## NO! BOOTSIZE=_B128 -## NO! BOOTSIZE=_B256 -## MAYBE: BOOTSIZE=_B512 -#BOOTSIZE=_B512 -BOOTSIZE=_B1024 +## NO! BOOTSIZE=_B256 +## MAYBE: BOOTSIZE=_B512 +#BOOTSIZE=_B512 +BOOTSIZE=_B1024 ##BOOTSIZE=_B2048 ################## BOOTLOADER ###################### # mt: Boot loader support. So far not done with a separate section -# to get the interrupt vector into the bootloader area. +# to get the interrupt vector into the bootloader area. # Bootloader address in datasheet and stk500 is given as -# "word", gcc toolchain needs "byte"-address +# "word", gcc toolchain needs "byte"-address # (see LDFLAGS further down) # 0x1C00*2=0x3800 for ATmega16 1024 words Boot Size ifeq ($(MCU), atmega16) - MT_BOOTLOADER_ADDRESS = 3800 + MT_BOOTLOADER_ADDRESS = 3800 endif # 0x0C00*2=0x1800 for ATmega8 1024 words Boot Size ifeq ($(MCU), atmega8) - MT_BOOTLOADER_ADDRESS = 1800 + MT_BOOTLOADER_ADDRESS = 1800 endif # 0x3C00*2=0x7800 for ATmega32 1024 words Boot Size ifeq ($(MCU), atmega32) - MT_BOOTLOADER_ADDRESS = 7800 + MT_BOOTLOADER_ADDRESS = 7800 endif # 0xFC00*2=0x1F800 for ATmega128 1024 words Boot Size ifeq ($(MCU), atmega128) - MT_BOOTLOADER_ADDRESS = 1F800 + MT_BOOTLOADER_ADDRESS = 1F800 endif # 0xFC00*2=0x1F800 for AT90Can128 1024 words Boot Size ifeq ($(MCU), at90can128) - MT_BOOTLOADER_ADDRESS = 1f800 + MT_BOOTLOADER_ADDRESS = 1f800 endif @@ -133,11 +133,11 @@ SRC = $(TARGET).c uart.c lowlevel.c # Even though the DOS/Win* filesystem matches both .s and .S the same, # it will preserve the spelling of the filenames, and gcc itself does # care about how the name is spelled on its command-line. -ASRC = +ASRC = -# Optimization level, can be [0, 1, 2, 3, s]. +# Optimization level, can be [0, 1, 2, 3, s]. # 0 = turn off optimization. s = optimize for size. # (Note: 3 is not always the best optimization level. See avr-libc FAQ.) OPT = s @@ -149,7 +149,7 @@ DEBUG = stabs # List any extra directories to look for include files here. # Each directory must be seperated by a space. -EXTRAINCDIRS = +EXTRAINCDIRS = # Compiler flag to set the C Standard level. @@ -194,7 +194,7 @@ CFLAGS += $(CSTANDARD) # for use in COFF files, additional information about filenames # and function names needs to be present in the assembler source # files -- see avr-libc docs [FIXME: not yet described there] -ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs +ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs @@ -206,7 +206,7 @@ PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min # Floating point printf version (requires MATH_LIB = -lm below) PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt -PRINTF_LIB = +PRINTF_LIB = # Minimalistic scanf version SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min @@ -214,7 +214,7 @@ SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min # Floating point + %[ scanf version (requires MATH_LIB = -lm below) SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt -SCANF_LIB = +SCANF_LIB = MATH_LIB = -lm @@ -247,7 +247,7 @@ LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS) # Programming support using avrdude. Settings and variables. -# Programming hardware: alf avr910 avrisp bascom bsd +# Programming hardware: alf avr910 avrisp bascom bsd # dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 # # Type: avrdude -c ? @@ -273,7 +273,7 @@ AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex #AVRDUDE_NO_VERIFY = -V # Increase verbosity level. Please use this when submitting bug -# reports about avrdude. See +# reports about avrdude. See # to submit bug reports. #AVRDUDE_VERBOSE = -v -v @@ -296,7 +296,7 @@ AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) # Define programs and commands. #SHELL = $(DIRAVRUTILS)/sh -#NM = $(DIRAVRBIN)/avr-nm +#NM = $(DIRAVRBIN)/avr-nm #CC = $(DIRAVRBIN)/avr-gcc #OBJCOPY = $(DIRAVRBIN)/avr-objcopy #OBJDUMP= $(DIRAVRBIN)/avr-objdump @@ -323,7 +323,7 @@ WINSHELL = cmd MSG_ERRORS_NONE = Errors: none MSG_BEGIN = -------- begin -------- MSG_END = -------- end -------- -MSG_SIZE_BEFORE = Size before: +MSG_SIZE_BEFORE = Size before: MSG_SIZE_AFTER = Size after: MSG_COFF = Converting to AVR COFF: MSG_EXTENDED_COFF = Converting to AVR Extended COFF: @@ -340,7 +340,7 @@ MSG_CLEANING = Cleaning project: # Define all object files. -OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) +OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) # Define all listing files. LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) @@ -367,7 +367,7 @@ build: elf hex eep lss sym elf: $(TARGET).elf hex: $(TARGET).hex eep: $(TARGET).eep -lss: $(TARGET).lss +lss: $(TARGET).lss sym: $(TARGET).sym @@ -399,12 +399,12 @@ sizeafter: # Display compiler version information. -gccversion : +gccversion : @$(CC) --version -# Program the device. +# Program the device. program: $(TARGET).hex $(TARGET).eep $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) @@ -416,7 +416,7 @@ COFFCONVERT=$(OBJCOPY) --debugging \ --change-section-address .data-0x800000 \ --change-section-address .bss-0x800000 \ --change-section-address .noinit-0x800000 \ ---change-section-address .eeprom-0x810000 +--change-section-address .eeprom-0x810000 coff: $(TARGET).elf @@ -471,7 +471,7 @@ extcoff: $(TARGET).elf %.o : %.c @echo @echo $(MSG_COMPILING) $< - $(CC) -c $(ALL_CFLAGS) $< -o $@ + $(CC) -c $(ALL_CFLAGS) $< -o $@ # Compile: create assembler files from C source files. diff --git a/readme.txt b/readme.txt index 5cdb4a0..eab4030 100644 --- a/readme.txt +++ b/readme.txt @@ -1,179 +1,179 @@ - -====================================================== - - ATMEL AVR UART Bootloader for AVR-GCC/avr-libc - based on the AVR Butterfly bootloader code - - by Martin Thomas, Kaiserslautern, Germany - mthomas@rhrk.uni-kl.de - eversmith@heizung-thomas.de - - http://www.siwawi.arubi.uni-kl.de/avr_projects - - Addtional code and improvements provided by - Uwe Bonnes and Bjoern Riemer. - - -====================================================== - - -Programming-Software (on the "PC-Side"): - -* AVRProg (included in AVRStudio) available at www.atmel.com. - MS-Windows only. AVRProg can be used as stand-alone application. - (avrprog.exe) - -* avrdude available at http://savannah.nongnu.org/projects/avrdude/ - "Multiplattform" - - - -09. Feb. 2006 - Version 0.75 - -* additional STARTUP_WAIT support contributed by Bjoern Riemer - -18. Aug. 2005 - Version 0.74 - -* AT90CAN128 support contributed by Uwe Bonnes -* Makefile modifications contributed by Uwe Bonnes - -23. Feb. 2005 - Version 0.7 - -* (Version 0.6 has never been available on the web-page) -* ATmega128 support -* code cleanup -* Tested with ATmega8, ATmega32 and ATmega128 - -7. Apr. 2004 - Version 0.5 - -* added different startup-methods -* compatible with ATmega8 now -* included makefile adopted to ATmega8 now - (ATmega16 options still available) -* fixed jump to application which did not work - reliably before -* tested with ATmega8 -* minimal options and startup-code result in - bootloader-size < 512 words - -6. Apr. 2004 - Version 0.4 - -* Buffered read of chars from UART during programming -since eeprom-write is too slow for unbuffered -operation. So EEPROM-upload does work now. -* Added BOOTICE-mode to flash JTAGICE-compatible -hardware (ATmega16@7,3Mhz) (if you know about BOOTICE, -you may unterstand why this has been added, if not -just keep the option disabled) -* small changes in (my)boot.h (lock-bit-mask) found -out during the development of the STK-500-compatible -bootloader. But setting lock-bits still does not -work with this bootloader. -* read of the low-fuse byte works (high byte still TODO) -* read of the lock-byte works (write still TODO) - -27. Mar 2004 - Version 0.3 - -Felt that as much functions from avr-libc's boot.h -as possible should be used without modifications. -Latest CVS-version of boot.h is included. -Only the read-routine is still "self-made" based -on ATMELs assembler-code. -EEPROM write on Mega16 does not work (and did not -work with V0.2 too). May be caused by my old Mega16 -chip. Needs testing. Flash read/write and EEPROM -read works. Still only tested with ATmega16. -This version may not work with the ATmega169 any -more. - -24. Mar 2004 - Version 0.2 - -During the development of a data-logger application -with the AVR-Butterfly there was a need to make -some changes in the bootloader. The same problem -again: no IAR compiler. The same way to solve the -problem: a port of the code to avr-gcc/avr-libc. -So this code is based on the ATMEL Butterfly -bootloader source code Rev 0.2 for IAR. - -The bootloader-port for the Butterfly which mimics -the complete functionality of the original -BF-bootloader is availabe at: -www.siwawi.arubi.uni-kl.de/avr_projects - -Atmel used a separate "lib" written in "pure" -assembly to access the low-level functions -for flash read/write. Well, so far I -don't know how to use "mixed language sources" -with the avr-gcc toolchain, so the low-level -routines have been implemented as inline assembler. -The avr-libc boot.h module written by Eric -Weddington served as a template Three of the four -low-level routines found in lowlevel.c come from -boot.h with minimal changes. The read routine has -been developed based on the ATMEL assembler code. - -Ignore the fuse and lock-bit readout. Read and Set is -not enabled (TODO). - - ---------------- Installation ----------------- - -- Change the MCU type in the makefile (so far - ATmega16 has been tested, ATmega169, ATmega8 - and ATmega32 should be o.k. too. - -- Change the boot(loader)-size in Makefile, this - bootloader is larger than 512 words (1024 bytes), - so select at least _B1024! - -- Change the XTAL in Makefile to the clock-frequency - of your board (keep BAUDRATE at 19200). See - the datasheet for frequencies with minimum - error at 19200bps and select Crystal/Oscillator - to get minimum errors. - -- Change the start-condition in Makefile. Default - is: enter bootloader if Pin A7 is connected to - GND during reset/startup - -- Please use at least avr-gcc 3.3.1/avr-libc 1.0 - or WINAVR Sept. 2003 or later to compile and link - the bootloader. - -- upload the hex-File to the AVR (STK500, STK200, SP12 - etc.) - -- program the "Boot Flash section size" (BOOTSZ fuses) - according to the boot-size selected in main.c - i.e. BOOTSZ=00 for boot-size 1024 words on ATmega16 - -- enable the BOOT Reset Vector (BOOTTRST=0) - -- Set the lock bits to protect the bootloader from - SPM-writes (Boot Loader Protection Mode 2 in STK500- - plugin) - -- Connect the AVR UART Pins via level-shifter/inverter - (i.e. MAX232) to you PCs Com-Port. - -- Reset the AVR while fullfilling the bootloader start- - condition. Which means connect PA7 to GND in the default - config during reste/power-cycle. Keep the connection - or hold the key down until you see the AVRPROG dialog! - -- Start AVRPROG (AVRStuido/Tools or stand-alone) - - keep PA7 grounded! (avrdude is supported too, check - the avrdude manual for command-line options). - -- AVRPROG will detect the bootloader, you may release - PA7 now - -- see AVRStuido online-help for more information how - to use AVRPROG - -- make sure to EXIT from AVRPROG (button) to start - your main-application (or toogle power/reset) - -good luck, feedback welcome. -Martin + +====================================================== + + ATMEL AVR UART Bootloader for AVR-GCC/avr-libc + based on the AVR Butterfly bootloader code + + by Martin Thomas, Kaiserslautern, Germany + mthomas@rhrk.uni-kl.de + eversmith@heizung-thomas.de + + http://www.siwawi.arubi.uni-kl.de/avr_projects + + Addtional code and improvements provided by + Uwe Bonnes and Bjoern Riemer. + + +====================================================== + + +Programming-Software (on the "PC-Side"): + +* AVRProg (included in AVRStudio) available at www.atmel.com. + MS-Windows only. AVRProg can be used as stand-alone application. + (avrprog.exe) + +* avrdude available at http://savannah.nongnu.org/projects/avrdude/ + "Multiplattform" + + + +09. Feb. 2006 - Version 0.75 + +* additional STARTUP_WAIT support contributed by Bjoern Riemer + +18. Aug. 2005 - Version 0.74 + +* AT90CAN128 support contributed by Uwe Bonnes +* Makefile modifications contributed by Uwe Bonnes + +23. Feb. 2005 - Version 0.7 + +* (Version 0.6 has never been available on the web-page) +* ATmega128 support +* code cleanup +* Tested with ATmega8, ATmega32 and ATmega128 + +7. Apr. 2004 - Version 0.5 + +* added different startup-methods +* compatible with ATmega8 now +* included makefile adopted to ATmega8 now + (ATmega16 options still available) +* fixed jump to application which did not work + reliably before +* tested with ATmega8 +* minimal options and startup-code result in + bootloader-size < 512 words + +6. Apr. 2004 - Version 0.4 + +* Buffered read of chars from UART during programming +since eeprom-write is too slow for unbuffered +operation. So EEPROM-upload does work now. +* Added BOOTICE-mode to flash JTAGICE-compatible +hardware (ATmega16@7,3Mhz) (if you know about BOOTICE, +you may unterstand why this has been added, if not +just keep the option disabled) +* small changes in (my)boot.h (lock-bit-mask) found +out during the development of the STK-500-compatible +bootloader. But setting lock-bits still does not +work with this bootloader. +* read of the low-fuse byte works (high byte still TODO) +* read of the lock-byte works (write still TODO) + +27. Mar 2004 - Version 0.3 + +Felt that as much functions from avr-libc's boot.h +as possible should be used without modifications. +Latest CVS-version of boot.h is included. +Only the read-routine is still "self-made" based +on ATMELs assembler-code. +EEPROM write on Mega16 does not work (and did not +work with V0.2 too). May be caused by my old Mega16 +chip. Needs testing. Flash read/write and EEPROM +read works. Still only tested with ATmega16. +This version may not work with the ATmega169 any +more. + +24. Mar 2004 - Version 0.2 + +During the development of a data-logger application +with the AVR-Butterfly there was a need to make +some changes in the bootloader. The same problem +again: no IAR compiler. The same way to solve the +problem: a port of the code to avr-gcc/avr-libc. +So this code is based on the ATMEL Butterfly +bootloader source code Rev 0.2 for IAR. + +The bootloader-port for the Butterfly which mimics +the complete functionality of the original +BF-bootloader is availabe at: +www.siwawi.arubi.uni-kl.de/avr_projects + +Atmel used a separate "lib" written in "pure" +assembly to access the low-level functions +for flash read/write. Well, so far I +don't know how to use "mixed language sources" +with the avr-gcc toolchain, so the low-level +routines have been implemented as inline assembler. +The avr-libc boot.h module written by Eric +Weddington served as a template Three of the four +low-level routines found in lowlevel.c come from +boot.h with minimal changes. The read routine has +been developed based on the ATMEL assembler code. + +Ignore the fuse and lock-bit readout. Read and Set is +not enabled (TODO). + + +--------------- Installation ----------------- + +- Change the MCU type in the makefile (so far + ATmega16 has been tested, ATmega169, ATmega8 + and ATmega32 should be o.k. too. + +- Change the boot(loader)-size in Makefile, this + bootloader is larger than 512 words (1024 bytes), + so select at least _B1024! + +- Change the XTAL in Makefile to the clock-frequency + of your board (keep BAUDRATE at 19200). See + the datasheet for frequencies with minimum + error at 19200bps and select Crystal/Oscillator + to get minimum errors. + +- Change the start-condition in Makefile. Default + is: enter bootloader if Pin A7 is connected to + GND during reset/startup + +- Please use at least avr-gcc 3.3.1/avr-libc 1.0 + or WINAVR Sept. 2003 or later to compile and link + the bootloader. + +- upload the hex-File to the AVR (STK500, STK200, SP12 + etc.) + +- program the "Boot Flash section size" (BOOTSZ fuses) + according to the boot-size selected in main.c + i.e. BOOTSZ=00 for boot-size 1024 words on ATmega16 + +- enable the BOOT Reset Vector (BOOTTRST=0) + +- Set the lock bits to protect the bootloader from + SPM-writes (Boot Loader Protection Mode 2 in STK500- + plugin) + +- Connect the AVR UART Pins via level-shifter/inverter + (i.e. MAX232) to you PCs Com-Port. + +- Reset the AVR while fullfilling the bootloader start- + condition. Which means connect PA7 to GND in the default + config during reste/power-cycle. Keep the connection + or hold the key down until you see the AVRPROG dialog! + +- Start AVRPROG (AVRStuido/Tools or stand-alone) - + keep PA7 grounded! (avrdude is supported too, check + the avrdude manual for command-line options). + +- AVRPROG will detect the bootloader, you may release + PA7 now + +- see AVRStuido online-help for more information how + to use AVRPROG + +- make sure to EXIT from AVRPROG (button) to start + your main-application (or toogle power/reset) + +good luck, feedback welcome. +Martin diff --git a/uart.c b/uart.c index 7aad949..eb337ee 100644 --- a/uart.c +++ b/uart.c @@ -1,151 +1,151 @@ - -#include - -/* 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< + +/* 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<