/***************************************************************************** * * AVRPROG compatible boot-loader * Version : 0.2 (24. March 2004) * Compiler : avr-gcc 3.3.1 / avr-libc 1.0 * size : ca. 610 word ( larger than 512 words :-( ) * by : Martin Thomas, Kaiserslautern, Germany * eversmith@heizung-thomas.de * * 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 application gcc-port they hopefully will not have any concerns about * publishing this port. Make sure to keep the copyright notice in derived * work to avoid trouble. **************************************************************************** * * Many functions used by "AVRPROG" (fuses) have been disabled by ATMEL in * the original source code of the Butterfly Boot-loader not by me. * Please 'diff' against the original source to see everything that has been * changed for the gcc port. * * 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 * code (without interrupt vector) at the adress you define in the linker * options for the newly created section. See the avr-libc FAQ and the avr- * libc's avr/boot.h documentation for further details. * * For this bootloader a Boot-Size of at least 0x4C4 (1220) bytes = * 610 words is needed. Sorry, so far efforts to shrink to 512 words failed. * See the makefile for information how to adopt the linker-settings to * the selected Boot Size (_Bxxx below) * ****************************************************************************/ #include #include #include #include /* READFUSELOCK is untested, will not work for Mega169 since not supported by AVRPROG 1.37 */ // #define ENABLEREADFUSELOCK #define BAUDRATE 19200 #define XTAL 3686400 /* Select Boot Size (select one, comment out the others) select at least _B1024 */ // NO! #define _B128 // NO! #define _B256 // NO! #define _B512 #define _B1024 //#define _B2048 #include "chipdef.h" #define UART_RX_BUFFER_SIZE PAGESIZE #include "lowlevel.h" #include "uart.h" unsigned char BufferLoad(unsigned int , unsigned char ) ; void BlockRead(unsigned int , unsigned char ) ; unsigned int address; unsigned char device; void send_boot(void) { sendchar('A'); sendchar('V'); sendchar('R'); sendchar('B'); sendchar('O'); sendchar('O'); sendchar('T'); } int main(void) { void (*funcptr)( void ) = 0x0000; // Set up function pointer unsigned int tempi; char val; char OK = 1; PORTA = 0xFF; // Enable pullups on Port A USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); MCUCR = (1<> 8) & 0xFF); // Report buffer size in bytes sendchar(UART_RX_BUFFER_SIZE & 0xFF); } else if(val=='B') // Start buffer load { tempi = recchar() << 8; // Load high byte of buffersize tempi |= recchar(); // Load low byte of buffersize val = recchar(); // Load memory type ('E' or 'F') sendchar (BufferLoad(tempi,val)); // Start downloading of buffer } else if(val == 'g') // Block read { tempi = (recchar() << 8) | recchar(); val = recchar(); // Get memtype BlockRead(tempi,val); // Perform the block read } /* else if(val=='c') //Write program memory, low byte { ldata=recchar(); sendchar('\r'); } else if(val== 'C') //Write program memory, high byte { data=ldata|(recchar()<<8); if (device == devtype) { fill_temp_buffer(data,(address)); //call asm routine. } address=address+2; sendchar('\r'); } */ else if(val=='e') //Chip erase { if (device == devtype) { for(address=0;address < APP_END;address += PAGESIZE) //Application section = 60 pages { write_page(address,(1<>8)); //send MSB sendchar((char)intval); //send LSB address=address+2; } else if (val == 'D') // write EEPROM { if (device == devtype) { EEARL = address; EEARH = (address >> 8); address++; EEDR = recchar(); EECR |= (1<> 8); address++; EECR |= (1<> 8); address++; // Select next byte EEDR = recchar(); // Load data to write EECR |= (1<> 8); address++; // Select next EEPROM byte EECR |= (1<> 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 } }