diff options
Diffstat (limited to 'bootloaders/bt')
| -rw-r--r-- | bootloaders/bt/ATmegaBOOT_168.c | 1038 | ||||
| -rw-r--r-- | bootloaders/bt/ATmegaBOOT_168.hex | 121 | ||||
| -rw-r--r-- | bootloaders/bt/ATmegaBOOT_168_atmega328_bt.hex | 162 | ||||
| -rwxr-xr-x | bootloaders/bt/Makefile | 109 | 
4 files changed, 1430 insertions, 0 deletions
| diff --git a/bootloaders/bt/ATmegaBOOT_168.c b/bootloaders/bt/ATmegaBOOT_168.c new file mode 100644 index 0000000..c73eefa --- /dev/null +++ b/bootloaders/bt/ATmegaBOOT_168.c @@ -0,0 +1,1038 @@ +/**********************************************************/ +/* Serial Bootloader for Atmel megaAVR Controllers        */ +/*                                                        */ +/* tested with ATmega8, ATmega128 and ATmega168           */ +/* should work with other mega's, see code for details    */ +/*                                                        */ +/* ATmegaBOOT.c                                           */ +/*                                                        */ +/* build: 050815                                          */ +/* date : 15.08.2005                                      */ +/*                                                        */ +/* 20060802: hacked for Arduino by D. Cuartielles         */ +/*           based on a previous hack by D. Mellis        */ +/*           and D. Cuartielles                           */ +/*                                                        */ +/* Monitor and debug functions were added to the original */ +/* code by Dr. Erik Lins, chip45.com. (See below)         */ +/*                                                        */ +/* Thanks to Karl Pitrich for fixing a bootloader pin     */ +/* problem and more informative LED blinking!             */ +/*                                                        */ +/* For the latest version see:                            */ +/* http://www.chip45.com/                                 */ +/*                                                        */ +/* ------------------------------------------------------ */ +/*                                                        */ +/* based on stk500boot.c                                  */ +/* Copyright (c) 2003, Jason P. Kyle                      */ +/* All rights reserved.                                   */ +/* see avr1.org for original file and information         */ +/*                                                        */ +/* This program is free software; you can redistribute it */ +/* and/or modify it under the terms of the GNU General    */ +/* Public License as published by the Free Software       */ +/* Foundation; either version 2 of the License, or        */ +/* (at your option) any later version.                    */ +/*                                                        */ +/* This program is distributed in the hope that it will   */ +/* be useful, but WITHOUT ANY WARRANTY; without even the  */ +/* implied warranty of MERCHANTABILITY or FITNESS FOR A   */ +/* PARTICULAR PURPOSE.  See the GNU General Public        */ +/* License for more details.                              */ +/*                                                        */ +/* You should have received a copy of the GNU General     */ +/* Public License along with this program; if not, write  */ +/* to the Free Software Foundation, Inc.,                 */ +/* 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */ +/*                                                        */ +/* Licence can be viewed at                               */ +/* http://www.fsf.org/licenses/gpl.txt                    */ +/*                                                        */ +/* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */ +/* m8515,m8535. ATmega161 has a very small boot block so  */ +/* isn't supported.                                       */ +/*                                                        */ +/* Tested with m128,m8,m163 - feel free to let me know    */ +/* how/if it works for you.                               */ +/*                                                        */ +/**********************************************************/ + + +/* some includes */ +#include <inttypes.h> +#include <avr/io.h> +#include <avr/pgmspace.h> +#include <avr/interrupt.h> +#include <avr/wdt.h>                + + +#define set_output(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#define set_input(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) + + +#define high(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#define low(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) + + + + +/* the current avr-libc eeprom functions do not support the ATmega168 */ +/* own eeprom write/read functions are used instead */ +#if !defined(__AVR_ATmega168__) || !defined(__AVR_ATmega328P__) +#include <avr/eeprom.h> +#endif + +/* define F_CPU according to AVR_FREQ set in Makefile */ +/* Is there a better way to pass such a parameter from Makefile to source code ? */ + +#define F_CPU     16000000L + +#include <util/delay.h>  + + +/* 20060803: hacked by DojoCorp */ +/* set the waiting time for the bootloader */ +#define MAX_TIME_COUNT (F_CPU>>1) + +/* set the UART baud rate */ +/* 20060803: hacked by DojoCorp */ +#define BAUD_RATE   115200 + + +/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */ +/* never allow AVR Studio to do an update !!!! */ +#define HW_VER	 0x02 +#define SW_MAJOR 0x01 +#define SW_MINOR 0x0f + + +/* Adjust to suit whatever pin your hardware uses to enter the bootloader */ +/* ATmega128 has two UARTS so two pins are used to enter bootloader and select UART */ +/* BL0... means UART0, BL1... means UART1 */ +#ifdef __AVR_ATmega128__ +#define BL_DDR  DDRF +#define BL_PORT PORTF +#define BL_PIN  PINF +#define BL0     PINF7 +#define BL1     PINF6 +#else +/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */ +#define BL_DDR  DDRD +#define BL_PORT PORTD +#define BL_PIN  PIND +#define BL      PIND6 +#endif + + +/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */ +/* if monitor functions are included, LED goes on after monitor was entered */ +#ifdef __AVR_ATmega128__ +/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128) */ +#define LED_DDR  DDRB +#define LED_PORT PORTB +#define LED_PIN  PINB +#define LED      PINB7 +#else +/* Onboard LED is connected to pin PB2 (e.g. Crumb8, Crumb168) */ +#define LED_DDR  DDRB +#define LED_PORT PORTB +#define LED_PIN  PINB +/* 20060803: hacked by DojoCorp, LED pin is B5 in Arduino */ +/* #define LED      PINB2 */ +#define LED      PINB5 +#endif + + +/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */ +#ifdef __AVR_ATmega128__ +#define MONITOR +#endif + + +/* define various device id's */ +/* manufacturer byte is always the same */ +#define SIG1	0x1E	// Yep, Atmel is the only manufacturer of AVR micros.  Single source :( + +#if defined __AVR_ATmega128__ +#define SIG2	0x97 +#define SIG3	0x02 +#define PAGE_SIZE	0x80U	//128 words + +#elif defined __AVR_ATmega64__ +#define SIG2	0x96 +#define SIG3	0x02 +#define PAGE_SIZE	0x80U	//128 words + +#elif defined __AVR_ATmega32__ +#define SIG2	0x95 +#define SIG3	0x02 +#define PAGE_SIZE	0x40U	//64 words + +#elif defined __AVR_ATmega16__ +#define SIG2	0x94 +#define SIG3	0x03 +#define PAGE_SIZE	0x40U	//64 words + +#elif defined __AVR_ATmega8__ +#define SIG2	0x93 +#define SIG3	0x07 +#define PAGE_SIZE	0x20U	//32 words + +#elif defined __AVR_ATmega88__ +#define SIG2	0x93 +#define SIG3	0x0a +#define PAGE_SIZE	0x20U	//32 words + +#elif defined __AVR_ATmega168__ +#define SIG2	0x94 +#define SIG3	0x06 +#define PAGE_SIZE	0x40U	//64 words + +#elif defined __AVR_ATmega328P__ +#define SIG2	0x95 +#define SIG3	0x0F +#define PAGE_SIZE	0x40U	//64 words + +#elif defined __AVR_ATmega162__ +#define SIG2	0x94 +#define SIG3	0x04 +#define PAGE_SIZE	0x40U	//64 words + +#elif defined __AVR_ATmega163__ +#define SIG2	0x94 +#define SIG3	0x02 +#define PAGE_SIZE	0x40U	//64 words + +#elif defined __AVR_ATmega169__ +#define SIG2	0x94 +#define SIG3	0x05 +#define PAGE_SIZE	0x40U	//64 words + +#elif defined __AVR_ATmega8515__ +#define SIG2	0x93 +#define SIG3	0x06 +#define PAGE_SIZE	0x20U	//32 words + +#elif defined __AVR_ATmega8535__ +#define SIG2	0x93 +#define SIG3	0x08 +#define PAGE_SIZE	0x20U	//32 words +#endif + + +/* function prototypes */ +void putch(char); +char getch(void); +void getNch(uint8_t); +void byte_response(uint8_t); +void nothing_response(void); +char gethex(void); +void puthex(char); +void flash_led(uint8_t); + +/* some variables */ +union address_union { +    uint16_t word; +    uint8_t  byte[2]; +} address; + +union length_union { +    uint16_t word; +    uint8_t  byte[2]; +} length; + +struct flags_struct { +    unsigned eeprom : 1; +    unsigned rampz  : 1; +} flags; + +uint8_t buff[256]; +uint8_t address_high; + +uint8_t pagesz=0x80; + +uint8_t i; +uint8_t bootuart = 0; + +void (*app_start)(void) = 0x0000; + + +/* main program starts here */ +int main(void) +{ +    uint8_t ch,ch2; +    uint16_t w; + +    asm volatile("nop\n\t"); + +    /* set pin direction for bootloader pin and enable pullup */ +    /* for ATmega128, two pins need to be initialized */ +#ifdef __AVR_ATmega128__ +    BL_DDR &= ~_BV(BL0); +    BL_DDR &= ~_BV(BL1); +    BL_PORT |= _BV(BL0); +    BL_PORT |= _BV(BL1); +#else +    BL_DDR &= ~_BV(BL); +    BL_PORT |= _BV(BL); +#endif + + +#ifdef __AVR_ATmega128__ +    /* check which UART should be used for booting */ +    if(bit_is_clear(BL_PIN, BL0)) { +      bootuart = 1; +    } +    else if(bit_is_clear(BL_PIN, BL1)) { +      bootuart = 2; +    } +#endif + +    /* check if flash is programmed already, if not start bootloader anyway */ +    if(pgm_read_byte_near(0x0000) != 0xFF) { + +#ifdef __AVR_ATmega128__ +	/* no UART was selected, start application */ +	if(!bootuart) { +          app_start(); +	} +#else +	/* check if bootloader pin is set low */ +	/* we don't start this part neither for the m8, nor m168 */ +	//if(bit_is_set(BL_PIN, BL)) { +    //      app_start(); +    //    } +#endif +    } + +#ifdef __AVR_ATmega128__     +    /* no bootuart was selected, default to uart 0 */ +    if(!bootuart) { +      bootuart = 1; +    } +#endif + + +    /* initialize UART(s) depending on CPU defined */ +#ifdef __AVR_ATmega128__ +    if(bootuart == 1) { +	UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); +	UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; +	UCSR0A = 0x00; +	UCSR0C = 0x06; +	UCSR0B = _BV(TXEN0)|_BV(RXEN0); +    } +    if(bootuart == 2) { +	UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); +	UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; +	UCSR1A = 0x00; +	UCSR1C = 0x06; +	UCSR1B = _BV(TXEN1)|_BV(RXEN1); +    } +#elif defined __AVR_ATmega163__ +    UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); +    UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8; +    UCSRA = 0x00; +    UCSRB = _BV(TXEN)|_BV(RXEN);	 +#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) + +	UBRR0H = ((F_CPU / 16 + BAUD_RATE / 2) / BAUD_RATE - 1) >> 8; +	UBRR0L = ((F_CPU / 16 + BAUD_RATE / 2) / BAUD_RATE - 1); + + +    //UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); +    //UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; +    UCSR0B = (1<<RXEN0) | (1<<TXEN0); +    UCSR0C = (1<<UCSZ00) | (1<<UCSZ01); +#elif defined __AVR_ATmega8__ +  /* m8 */ +  UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; 	// set baud rate +  UBRRL = (((F_CPU/BAUD_RATE)/16)-1); +  UCSRB = (1<<RXEN)|(1<<TXEN);  // enable Rx & Tx +  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // config USART; 8N1 +#else +    /* m16,m32,m169,m8515,m8535 */ +    UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); +    UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8; +    UCSRA = 0x00; +    UCSRC = 0x06; +    UCSRB = _BV(TXEN)|_BV(RXEN); +#endif + +    /* set LED pin as output */ +    LED_DDR |= _BV(LED); +               + +      +      set_output(DDRD,PIND7); +	  high(PORTD,PD7);     +	  for (i = 0; i < 16; i++) { +		  +			_delay_loop_2(0); +	  } +	 +	 +	  low(PORTD,PD7); + + +    /* flash onboard LED to signal entering of bootloader */ +#ifdef __AVR_ATmega128__ +    // 4x for UART0, 5x for UART1 +    flash_led(3 + bootuart); +#else +    flash_led(3); +#endif +     +    /* 20050803: by DojoCorp, this is one of the parts provoking the +                 system to stop listening, cancelled from the original */ +    //putch('\0'); +         + +   //message("SET BT PAGEMODE 3 2000 1");     +putch('S'); +putch('E'); +putch('T'); +putch(' '); +putch('B'); +putch('T'); +putch(' '); +putch('P'); +putch('A'); +putch('G'); +putch('E'); +putch('M'); +putch('O'); +putch('D'); +putch('E'); +putch(' '); +putch('3'); +putch(' '); +putch('2'); +putch('0'); +putch('0'); +putch('0'); +putch(' '); +putch('1'); +putch(0x0D); + +   +	  //put_s("SET BT ROLE 0 f 7d00");   +	putch('S'); +	putch('E'); +	putch('T'); +	putch(' '); +	putch('B'); +	putch('T'); +	putch(' '); +	putch('R'); +	putch('O'); +	putch('L'); +	putch('E'); +	putch(' '); +	putch('0'); +	putch(' '); +	putch('f'); +	putch(' '); +	putch('7'); +	putch('d'); +	putch('0'); +	putch('0'); +	putch(0x0D); + + + + + + +    /* forever loop */ +    for (;;) { + +	/* get character from UART */ +	ch = getch(); + +	/* A bunch of if...else if... gives smaller code than switch...case ! */ + +	/* Hello is anyone home ? */  +	if(ch=='0') { +	    nothing_response(); +	} + + +	/* Request programmer ID */ +	/* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry  */ +	/* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares.  */ +	else if(ch=='1') { +	    if (getch() == ' ') { +		putch(0x14); +		putch('A'); +		putch('V'); +		putch('R'); +		putch(' '); +		putch('I'); +		putch('S'); +		putch('P'); +		putch(0x10); +	    } +	} + + +	/* AVR ISP/STK500 board commands  DON'T CARE so default nothing_response */ +	else if(ch=='@') { +	    ch2 = getch(); +	    if (ch2>0x85) getch(); +	    nothing_response(); +	} + + +	/* AVR ISP/STK500 board requests */ +	else if(ch=='A') { +	    ch2 = getch(); +	    if(ch2==0x80) byte_response(HW_VER);		// Hardware version +	    else if(ch2==0x81) byte_response(SW_MAJOR);	// Software major version +	    else if(ch2==0x82) byte_response(SW_MINOR);	// Software minor version +	    else if(ch2==0x98) byte_response(0x03);		// Unknown but seems to be required by avr studio 3.56 +	    else byte_response(0x00);				// Covers various unnecessary responses we don't care about +	} + + +	/* Device Parameters  DON'T CARE, DEVICE IS FIXED  */ +	else if(ch=='B') { +	    getNch(20); +	    nothing_response(); +	} + + +	/* Parallel programming stuff  DON'T CARE  */ +	else if(ch=='E') { +	    getNch(5); +	    nothing_response(); +	} + + +	/* Enter programming mode  */ +	else if(ch=='P') { +	    nothing_response(); +	} + + +	/* Leave programming mode  */ +	else if(ch=='Q') { +	    nothing_response(); +	} + + +	/* Erase device, don't care as we will erase one page at a time anyway.  */ +	else if(ch=='R') { +	    nothing_response(); +	} + + +	/* Set address, little endian. EEPROM in bytes, FLASH in words  */ +	/* Perhaps extra address bytes may be added in future to support > 128kB FLASH.  */ +	/* This might explain why little endian was used here, big endian used everywhere else.  */ +	else if(ch=='U') { +	    address.byte[0] = getch(); +	    address.byte[1] = getch(); +	    nothing_response(); +	} + + +	/* Universal SPI programming command, disabled.  Would be used for fuses and lock bits.  */ +	else if(ch=='V') { +	    getNch(4); +	    byte_response(0x00); +	} + + +	/* Write memory, length is big endian and is in bytes  */ +	else if(ch=='d') { +	    length.byte[1] = getch(); +	    length.byte[0] = getch(); +	    flags.eeprom = 0; +	    if (getch() == 'E') flags.eeprom = 1; +	    for (w=0;w<length.word;w++) { +		buff[w] = getch();	                        // Store data in buffer, can't keep up with serial data stream whilst programming pages +	    } +	    if (getch() == ' ') { +		if (flags.eeprom) {		                //Write to EEPROM one byte at a time +		    for(w=0;w<length.word;w++) { +#if defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__) +			while(EECR & (1<<EEPE)); +			EEAR = (uint16_t)(void *)address.word; +			EEDR = buff[w]; +			EECR |= (1<<EEMPE); +			EECR |= (1<<EEPE); +#else +			eeprom_write_byte((void *)address.word,buff[w]); +#endif +			address.word++; +		    }			 +		} +		else {					        //Write to FLASH one page at a time +		    if (address.byte[1]>127) address_high = 0x01;	//Only possible with m128, m256 will need 3rd address byte. FIXME +		    else address_high = 0x00; +#ifdef __AVR_ATmega128__ +		    RAMPZ = address_high; +#endif +		    address.word = address.word << 1;	        //address * 2 -> byte location +		    /* if ((length.byte[0] & 0x01) == 0x01) length.word++;	//Even up an odd number of bytes */ +		    if ((length.byte[0] & 0x01)) length.word++;	//Even up an odd number of bytes +		    cli();					//Disable interrupts, just to be sure +			// HACKME: EEPE used to be EEWE +		    while(bit_is_set(EECR,EEPE));			//Wait for previous EEPROM writes to complete +		    asm volatile( +				 "clr	r17		\n\t"	//page_word_count +				 "lds	r30,address	\n\t"	//Address of FLASH location (in bytes) +				 "lds	r31,address+1	\n\t" +				 "ldi	r28,lo8(buff)	\n\t"	//Start of buffer array in RAM +				 "ldi	r29,hi8(buff)	\n\t" +				 "lds	r24,length	\n\t"	//Length of data to be written (in bytes) +				 "lds	r25,length+1	\n\t" +				 "length_loop:		\n\t"	//Main loop, repeat for number of words in block							 							  +				 "cpi	r17,0x00	\n\t"	//If page_word_count=0 then erase page +				 "brne	no_page_erase	\n\t"						  +				 "wait_spm1:		\n\t" +				 "lds	r16,%0		\n\t"	//Wait for previous spm to complete +				 "andi	r16,1           \n\t" +				 "cpi	r16,1           \n\t" +				 "breq	wait_spm1       \n\t" +				 "ldi	r16,0x03	\n\t"	//Erase page pointed to by Z +				 "sts	%0,r16		\n\t" +				 "spm			\n\t"							  +#ifdef __AVR_ATmega163__ +				 ".word 0xFFFF		\n\t" +				 "nop			\n\t" +#endif +				 "wait_spm2:		\n\t" +				 "lds	r16,%0		\n\t"	//Wait for previous spm to complete +				 "andi	r16,1           \n\t" +				 "cpi	r16,1           \n\t" +				 "breq	wait_spm2       \n\t"									  + +				 "ldi	r16,0x11	\n\t"	//Re-enable RWW section +				 "sts	%0,r16		\n\t"						 			  +				 "spm			\n\t" +#ifdef __AVR_ATmega163__ +				 ".word 0xFFFF		\n\t" +				 "nop			\n\t" +#endif +				 "no_page_erase:		\n\t"							  +				 "ld	r0,Y+		\n\t"	//Write 2 bytes into page buffer +				 "ld	r1,Y+		\n\t"							  +							  +				 "wait_spm3:		\n\t" +				 "lds	r16,%0		\n\t"	//Wait for previous spm to complete +				 "andi	r16,1           \n\t" +				 "cpi	r16,1           \n\t" +				 "breq	wait_spm3       \n\t" +				 "ldi	r16,0x01	\n\t"	//Load r0,r1 into FLASH page buffer +				 "sts	%0,r16		\n\t" +				 "spm			\n\t" +							  +				 "inc	r17		\n\t"	//page_word_count++ +				 "cpi r17,%1	        \n\t" +				 "brlo	same_page	\n\t"	//Still same page in FLASH +				 "write_page:		\n\t" +				 "clr	r17		\n\t"	//New page, write current one first +				 "wait_spm4:		\n\t" +				 "lds	r16,%0		\n\t"	//Wait for previous spm to complete +				 "andi	r16,1           \n\t" +				 "cpi	r16,1           \n\t" +				 "breq	wait_spm4       \n\t" +#ifdef __AVR_ATmega163__ +				 "andi	r30,0x80	\n\t"	// m163 requires Z6:Z1 to be zero during page write +#endif							 							  +				 "ldi	r16,0x05	\n\t"	//Write page pointed to by Z +				 "sts	%0,r16		\n\t" +				 "spm			\n\t" +#ifdef __AVR_ATmega163__ +				 ".word 0xFFFF		\n\t" +				 "nop			\n\t" +				 "ori	r30,0x7E	\n\t"	// recover Z6:Z1 state after page write (had to be zero during write) +#endif +				 "wait_spm5:		\n\t" +				 "lds	r16,%0		\n\t"	//Wait for previous spm to complete +				 "andi	r16,1           \n\t" +				 "cpi	r16,1           \n\t" +				 "breq	wait_spm5       \n\t"									  +				 "ldi	r16,0x11	\n\t"	//Re-enable RWW section +				 "sts	%0,r16		\n\t"						 			  +				 "spm			\n\t"					 		  +#ifdef __AVR_ATmega163__ +				 ".word 0xFFFF		\n\t" +				 "nop			\n\t" +#endif +				 "same_page:		\n\t"							  +				 "adiw	r30,2		\n\t"	//Next word in FLASH +				 "sbiw	r24,2		\n\t"	//length-2 +				 "breq	final_write	\n\t"	//Finished +				 "rjmp	length_loop	\n\t" +				 "final_write:		\n\t" +				 "cpi	r17,0		\n\t" +				 "breq	block_done	\n\t" +				 "adiw	r24,2		\n\t"	//length+2, fool above check on length after short page write +				 "rjmp	write_page	\n\t" +				 "block_done:		\n\t" +				 "clr	__zero_reg__	\n\t"	//restore zero register +#if defined __AVR_ATmega168__  || __AVR_ATmega328P__ +				 : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31" +#else +				 : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31" +#endif +				 ); +		    /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */ +		    /* exit the bootloader without a power cycle anyhow */ +		} +		putch(0x14); +		putch(0x10); +	    }		 +	} +     + +        /* Read memory block mode, length is big endian.  */ +        else if(ch=='t') { +	    length.byte[1] = getch(); +	    length.byte[0] = getch(); +#if defined __AVR_ATmega128__ +	    if (address.word>0x7FFF) flags.rampz = 1;		// No go with m256, FIXME +	    else flags.rampz = 0; +#endif +	    if (getch() == 'E') flags.eeprom = 1; +	    else { +		flags.eeprom = 0; +		address.word = address.word << 1;	        // address * 2 -> byte location +	    } +	    if (getch() == ' ') {		                // Command terminator +		putch(0x14); +		for (w=0;w < length.word;w++) {		        // Can handle odd and even lengths okay +		    if (flags.eeprom) {	                        // Byte access EEPROM read +#if defined __AVR_ATmega168__  || __AVR_ATmega328P__ +			while(EECR & (1<<EEPE)); +			EEAR = (uint16_t)(void *)address.word; +			EECR |= (1<<EERE); +			putch(EEDR); +#else +			putch(eeprom_read_byte((void *)address.word)); +#endif +			address.word++; +		    } +		    else { + +			if (!flags.rampz) putch(pgm_read_byte_near(address.word)); +#if defined __AVR_ATmega128__ +			else putch(pgm_read_byte_far(address.word + 0x10000)); +			// Hmmmm, yuck  FIXME when m256 arrvies +#endif +			address.word++; +		    } +		} +		putch(0x10); +	    } +	} + + +        /* Get device signature bytes  */ +        else if(ch=='u') { +	    if (getch() == ' ') { +		putch(0x14); +		putch(SIG1); +		putch(SIG2); +		putch(SIG3); +		putch(0x10); +	    } +	} + + +        /* Read oscillator calibration byte */ +        else if(ch=='v') { +	    byte_response(0x00); +	} + + +#ifdef MONITOR + +	/* here come the extended monitor commands by Erik Lins */ + +	/* check for three times exclamation mark pressed */ +	else if(ch=='!') { +	    ch = getch(); +	    if(ch=='!') { +		ch = getch(); +		if(ch=='!') { + +#ifdef __AVR_ATmega128__ +		    uint16_t extaddr; +#endif +		    uint8_t addrl, addrh; + +#ifdef CRUMB128 +		    PGM_P welcome = {"ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r"}; +#elif defined PROBOMEGA128 +		    PGM_P welcome = {"ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r"}; +#elif defined SAVVY128 +		    PGM_P welcome = {"ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r"}; +#endif + +		    /* turn on LED */ +		    LED_DDR |= _BV(LED); +		    LED_PORT &= ~_BV(LED); + +		    /* print a welcome message and command overview */ +		    for(i=0; welcome[i] != '\0'; ++i) { +			putch(welcome[i]); +		    } + +		    /* test for valid commands */ +		    for(;;) { +			putch('\n'); +			putch('\r'); +			putch(':'); +			putch(' '); + +			ch = getch(); +			putch(ch); + +			/* toggle LED */ +			if(ch == 't') { +			    if(bit_is_set(LED_PIN,LED)) { +				LED_PORT &= ~_BV(LED); +				putch('1'); +			    } else { +				LED_PORT |= _BV(LED); +				putch('0'); +			    } + +			}  + +			/* read byte from address */ +			else if(ch == 'r') { +			    ch = getch(); putch(ch); +			    addrh = gethex(); +			    addrl = gethex(); +			    putch('='); +			    ch = *(uint8_t *)((addrh << 8) + addrl); +			    puthex(ch); +			} + +			/* write a byte to address  */ +			else if(ch == 'w') { +			    ch = getch(); putch(ch); +			    addrh = gethex(); +			    addrl = gethex(); +			    ch = getch(); putch(ch); +			    ch = gethex(); +			    *(uint8_t *)((addrh << 8) + addrl) = ch; + +			} + +			/* read from uart and echo back */ +			else if(ch == 'u') { +			    for(;;) { +				putch(getch()); +			    } +			} +#ifdef __AVR_ATmega128__ +			/* external bus loop  */ +			else if(ch == 'b') { +			    putch('b'); +			    putch('u'); +			    putch('s'); +			    MCUCR = 0x80; +			    XMCRA = 0; +			    XMCRB = 0; +			    extaddr = 0x1100; +			    for(;;) { +				ch = *(volatile uint8_t *)extaddr; +				if(++extaddr == 0) { +				    extaddr = 0x1100; +				} +			    } +			} +#endif + +			else if(ch == 'j') { +			    app_start(); +			} + +		    } +		    /* end of monitor functions */ + +		} +	    } +	} +	/* end of monitor */ +#endif + + +    } +    /* end of forever loop */ + +} + + +char gethex(void) { +    char ah,al; + +    ah = getch(); putch(ah); +    al = getch(); putch(al); +    if(ah >= 'a') { +	ah = ah - 'a' + 0x0a; +    } else if(ah >= '0') { +	ah -= '0'; +    } +    if(al >= 'a') { +	al = al - 'a' + 0x0a; +    } else if(al >= '0') { +	al -= '0'; +    } +    return (ah << 4) + al; +} + + +void puthex(char ch) { +    char ah,al; + +    ah = (ch & 0xf0) >> 4; +    if(ah >= 0x0a) { +	ah = ah - 0x0a + 'a'; +    } else { +	ah += '0'; +    } +    al = (ch & 0x0f); +    if(al >= 0x0a) { +	al = al - 0x0a + 'a'; +    } else { +	al += '0'; +    } +    putch(ah); +    putch(al); +} + + +void putch(char ch) +{ +#ifdef __AVR_ATmega128__ +    if(bootuart == 1) { +	while (!(UCSR0A & _BV(UDRE0))); +	UDR0 = ch; +    } +    else if (bootuart == 2) { +	while (!(UCSR1A & _BV(UDRE1))); +	UDR1 = ch; +    } +#elif defined (__AVR_ATmega168__) || defined(__AVR_ATmega328P__) +    while (!(UCSR0A & _BV(UDRE0))); +    UDR0 = ch; +#else +    /* m8,16,32,169,8515,8535,163 */ +    while (!(UCSRA & _BV(UDRE))); +    UDR = ch; +#endif +} + + +char getch(void) +{ +#ifdef __AVR_ATmega128__ +    if(bootuart == 1) { +	while(!(UCSR0A & _BV(RXC0))); +	return UDR0; +    } +    else if(bootuart == 2) { +	while(!(UCSR1A & _BV(RXC1))); +	return UDR1; +    } +    return 0; +#elif defined (__AVR_ATmega168__) || defined(__AVR_ATmega328P__) +    uint32_t count = 0; +    while(!(UCSR0A & _BV(RXC0))){ +    	/* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/                +    	/* HACKME:: here is a good place to count times*/ +    	count++; +    	if (count > MAX_TIME_COUNT) +    		app_start(); +     } +    return UDR0; +#else +    /* m8,16,32,169,8515,8535,163 */ +    uint32_t count = 0; +    while(!(UCSRA & _BV(RXC))){ +    	/* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/                +    	/* HACKME:: here is a good place to count times*/ +    	count++; +    	if (count > MAX_TIME_COUNT) +    		app_start(); +     } +    return UDR; +#endif +} + + +void getNch(uint8_t count) +{ +    uint8_t i; +    for(i=0;i<count;i++) { +#ifdef __AVR_ATmega128__ +	if(bootuart == 1) { +	    while(!(UCSR0A & _BV(RXC0))); +	    UDR0; +	}  +	else if(bootuart == 2) { +	    while(!(UCSR1A & _BV(RXC1))); +	    UDR1; +	} +#elif (defined __AVR_ATmega168__) || defined(__AVR_ATmega328P__) +	while(!(UCSR0A & _BV(RXC0))); +	UDR0; +#else +	/* m8,16,32,169,8515,8535,163 */ +   	/* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/                +	//while(!(UCSRA & _BV(RXC))); +	//UDR; +    uint8_t i; +    for(i=0;i<count;i++) { +    	getch(); // need to handle time out +    } +#endif		 +    } +} + + +void byte_response(uint8_t val) +{ +    if (getch() == ' ') { +	putch(0x14); +	putch(val); +	putch(0x10); +    } +} + + +void nothing_response(void) +{ +    if (getch() == ' ') { +	putch(0x14); +	putch(0x10); +    } +} + +void flash_led(uint8_t count) +{ +    /* flash onboard LED three times to signal entering of bootloader */ +    uint32_t l; + +    if (count == 0) { +      count = 3; +    } +     +    for (i = 0; i < count; ++i) { +	LED_PORT |= _BV(LED); +	for(l = 0; l < (2 * F_CPU); ++l); +	LED_PORT &= ~_BV(LED); +	for(l = 0; l < (F_CPU / 5); ++l); +    } +} + + +/* end of file ATmegaBOOT.c */ diff --git a/bootloaders/bt/ATmegaBOOT_168.hex b/bootloaders/bt/ATmegaBOOT_168.hex new file mode 100644 index 0000000..036ae54 --- /dev/null +++ b/bootloaders/bt/ATmegaBOOT_168.hex @@ -0,0 +1,121 @@ +:103800000C94341C0C944F1C0C944F1C0C944F1CA7 +:103810000C944F1C0C944F1C0C944F1C0C944F1C7C +:103820000C944F1C0C944F1C0C944F1C0C944F1C6C +:103830000C944F1C0C944F1C0C944F1C0C944F1C5C +:103840000C944F1C0C944F1C0C944F1C0C944F1C4C +:103850000C944F1C0C944F1C0C944F1C0C944F1C3C +:103860000C944F1C0C944F1C11241FBECFEFD4E0BE +:10387000DEBFCDBF11E0A0E0B1E0E0E6FFE302C0B3 +:1038800005900D92A230B107D9F712E0A2E0B1E0A5 +:1038900001C01D92AC30B107E1F70C94D61C0C941A +:1038A000001C882309F483E01092090290E0981725 +:1038B000F0F4692F2D9A2FEF37E448EE51E02253B0 +:1038C00030404040504057FFFACF2D982FEF33ED56 +:1038D00040E350E0225330404040504057FFFACF81 +:1038E000962F9F5F692F981728F3909309020895E8 +:1038F000982F8091C00085FFFCCF9093C60008955B +:10390000EF92FF920F931F93EE24FF248701809183 +:10391000C00087FD17C00894E11CF11C011D111D9A +:1039200081E0E81682E1F8068AE7080780E01807D8 +:1039300070F3E0910201F091030109958091C000BC +:1039400087FFE9CF8091C600992787FD90951F9149 +:103950000F91FF90EF9008950E94801C803209F033 +:10396000089584E10E94781C80E10E94781C0895EB +:10397000CF93C82F0E94801C803249F484E10E94BA +:10398000781C8C2F0E94781C80E10E94781CCF91BB +:103990000895282F90E007C08091C0008823E4F7A5 +:1039A0008091C6009F5F9217B8F30895CFEFD4E0DF +:1039B000DEBFCDBF000056985E9A1092C50088E029 +:1039C0008093C40088E18093C10086E08093C200A8 +:1039D000259A579A5F9A109209022FE080E090E0B2 +:1039E0000197F1F7215027FFF9CF20E12093090239 +:1039F0005F9883E00E94511C83E50E94781C85E457 +:103A00000E94781C84E50E94781C80E20E94781C49 +:103A100082E40E94781C84E50E94781C80E20E9467 +:103A2000781C80E50E94781C81E40E94781C87E461 +:103A30000E94781C85E40E94781C8DE40E94781C0A +:103A40008FE40E94781C84E40E94781C85E40E9424 +:103A5000781C80E20E94781C83E30E94781C80E23C +:103A60000E94781C82E30E94781C80E30E94781CEC +:103A700080E30E94781C80E30E94781C80E20E9410 +:103A8000781C81E30E94781C8DE00E94781C83E5FD +:103A90000E94781C85E40E94781C84E50E94781CB2 +:103AA00080E20E94781C82E40E94781C84E50E94D7 +:103AB000781C80E20E94781C82E50E94781C8FE4CA +:103AC0000E94781C8CE40E94781C85E40E94781C7B +:103AD00080E20E94781C80E30E94781C80E20E94B1 +:103AE000781C86E60E94781C80E20E94781C87E39E +:103AF0000E94781C84E60E94781C80E30E94781C57 +:103B000080E30E94781C8DE00E94781C0E94801C3B +:103B1000803361F1813369F1803409F449C0813423 +:103B200009F44FC0823409F45DC0853409F460C0E3 +:103B30008035E1F08135D1F08235C1F0853509F469 +:103B40005BC0863509F463C0843609F465C08437E8 +:103B500009F4B9C0853709F414C18637B9F680E095 +:103B60000E94B81C0E94801C8033A1F60E94AC1CED +:103B7000CDCF0E94801CC82F803241F684E10E9484 +:103B8000781C81E40E94781C86E50E94781C82E5FE +:103B90000E94781C8C2F0E94781C89E40E94781C5B +:103BA00083E50E94781C80E50E94781C80E1ACCF00 +:103BB0000E94801C8638D0F20E94801C0E94AC1C9F +:103BC000A5CF0E94801C803809F4EDC0813809F42B +:103BD000EEC0823809F4EFC0883909F683E00E940C +:103BE000B81CC0CF84E10E94C91C0E94AC1C8ECFBF +:103BF00085E00E94C91CF9CF0E94801C80930501BA +:103C00000E94801C809306010E94AC1C7FCF84E040 +:103C10000E94C91C80E0A4CF0E94801C80930802EF +:103C20000E94801C8093070280910B028E7F8093FC +:103C30000B020E94801C853409F4C1C000E010E032 +:103C400080910702909108021816190670F4C7E0D7 +:103C5000D1E00E94801C89930F5F1F4F8091070263 +:103C60009091080208171907A0F30E94801C803267 +:103C700009F04CCF80910B0280FFADC000E010E056 +:103C8000209107023091080212161306C0F4E09149 +:103C90000501F0910601A7E0B1E0F999FECFF2BD70 +:103CA000E1BD8D9180BDFA9AF99A31960F5F1F4F51 +:103CB0000217130790F3F0930601E093050184E1E6 +:103CC0000E94781C73CF0E94801C809308020E947F +:103CD000801C809307020E94801C853409F475C003 +:103CE00080910B028E7F80930B0280910501909151 +:103CF0000601880F991F90930601809305010E9489 +:103D0000801C803209F002CF84E10E94781C00E020 +:103D100010E020910702309108021216130608F0F5 +:103D200045CFE0910501F091060180910B0280FFE3 +:103D30001FC0F999FECFF2BDE1BDF89A80B50E948F +:103D4000781CE0910501F09106013196F09306018F +:103D5000E093050120910702309108020F5F1F4F89 +:103D60000217130708F022CF80910B0280FDE1CFEC +:103D7000869580FF9BC03196F0930601E093050184 +:103D8000EDCF0E94801C803209F0C0CE84E10E94F9 +:103D9000781C8EE10E94781C84E90E94781C86E0E1 +:103DA0000E94781C03CF82E00E94B81CDBCE81E029 +:103DB0000E94B81CD7CE8FE00E94B81CD3CE809151 +:103DC0000B02816080930B0239CF80910B028160DE +:103DD00080930B0294CF8091060187FD73C01092EF +:103DE0000A028091050190910601880F991F909316 +:103DF0000601809305018091070280FF09C0809130 +:103E0000070290910802019690930802809307029E +:103E1000F894F999FECF1127E0910501F091060180 +:103E2000C7E0D1E08091070290910802103091F430 +:103E30000091570001700130D9F303E0009357005F +:103E4000E8950091570001700130D9F301E100932A +:103E50005700E895099019900091570001700130C2 +:103E6000D9F301E000935700E8951395103498F0CA +:103E700011270091570001700130D9F305E000933C +:103E80005700E8950091570001700130D9F301E126 +:103E900000935700E8953296029709F0C7CF10308B +:103EA00011F00296E5CF112484E10ACF84910E949B +:103EB000781C2091070230910802E0910501F091F1 +:103EC000060159CF81E080930A028BCF1F93CF93D5 +:103ED0000E94801CC82F0E94781C0E94801C182FF2 +:103EE0000E94781CC1362CF0C75511363CF017558E +:103EF00008C0C033D4F3C0531136CCF710330CF0E4 +:103F00001053C295C07FC10F8C2F992787FD9095C4 +:103F1000CF911F910895CF93282F992787FD9095D2 +:103F2000807F9070959587959595879595958795C0 +:103F3000959587958A303CF0895AC22FCF70CA3048 +:103F40003CF0C95A06C0805DC22FCF70CA30CCF792 +:103F5000C05D0E94781C8C2F0E94781CCF91089520 +:023F60008000DF +:0400000300003800C1 +:00000001FF diff --git a/bootloaders/bt/ATmegaBOOT_168_atmega328_bt.hex b/bootloaders/bt/ATmegaBOOT_168_atmega328_bt.hex new file mode 100644 index 0000000..a50c7c3 --- /dev/null +++ b/bootloaders/bt/ATmegaBOOT_168_atmega328_bt.hex @@ -0,0 +1,162 @@ +:107000000C9434380C9451380C9451380C945138F9
 +:107010000C9451380C9451380C9451380C945138CC
 +:107020000C9451380C9451380C9451380C945138BC
 +:107030000C9451380C9451380C9451380C945138AC
 +:107040000C9451380C9451380C9451380C9451389C
 +:107050000C9451380C9451380C9451380C9451388C
 +:107060000C9451380C94513811241FBECFEFD8E046
 +:10707000DEBFCDBF11E0A0E0B1E0E4EEF9E702C071
 +:1070800005900D92A230B107D9F712E0A2E0B1E06D
 +:1070900001C01D92AC30B107E1F70E942D390C946C
 +:1070A000F03C0C940038282F992787FD9095807F1D
 +:1070B00090709595879595958795959587959595D4
 +:1070C00087958A30C4F0382F395A822F8F708A30D2
 +:1070D0007CF0982F995A8091C00085FFFCCF3093A7
 +:1070E000C6008091C00085FFFCCF9093C600089534
 +:1070F000982F905DF0CF382F305DE7CF982F80919B
 +:10710000C00085FFFCCF9093C6000895EF92FF92D8
 +:107110000F931F93EE24FF2487018091C00087FD09
 +:1071200017C00894E11CF11C011D111D81E0E81637
 +:1071300082E1F8068AE7080780E0180770F3E0911B
 +:107140000301F091040109958091C00087FFE9CF08
 +:107150008091C6001F910F91FF90EF9008951F93AB
 +:107160000E948638182F8091C00085FFFCCF1093B5
 +:10717000C6000E948638982F8091C00085FFFCCF02
 +:107180009093C600113664F01755913674F490331D
 +:107190000CF090531295107F892F810F1F91089545
 +:1071A00010339CF31053913694F397551295107F3A
 +:1071B000892F810F1F910895282F882351F090E087
 +:1071C0008091C00087FFFCCF8091C6009F5F92171F
 +:1071D000B8F308951F93182F0E948638803211F05B
 +:1071E0001F9108958091C00085FFFCCF84E18093BA
 +:1071F000C6008091C00085FFFCCF1093C60080912F
 +:10720000C00085FFFCCF80E18093C6001F910895E8
 +:107210000E948638803209F008958091C00085FF71
 +:10722000FCCF84E18093C6008091C00085FFFCCF35
 +:1072300080E18093C6000895882359F010920902D6
 +:1072400090E02D9A2D989F5F9817D8F3909309029C
 +:1072500008951092090283E0F3CF3F924F925F921C
 +:107260006F927F928F929F92AF92BF92CF92DF9256
 +:10727000EF92FF920F931F93CF93DF9300005698E6
 +:107280005E9A1092C50088E08093C40088E18093E4
 +:10729000C10086E08093C200259A579A5F9A21E048
 +:1072A00040E050E0CA010197F1F72F5F2131D1F79B
 +:1072B00080E1809309025F9883E00E941C398091ED
 +:1072C000C00085FFFCCF83E58093C6008091C0009D
 +:1072D00085FFFCCF85E48093C6008091C00085FFC8
 +:1072E000FCCF84E58093C6008091C00085FFFCCF71
 +:1072F00080E28093C6008091C00085FFFCCF82E4CD
 +:107300008093C6008091C00085FFFCCF84E5809308
 +:10731000C6008091C00085FFFCCF80E28093C6004C
 +:107320008091C00085FFFCCF80E58093C6008091EE
 +:10733000C00085FFFCCF81E48093C6008091C0002F
 +:1073400085FFFCCF87E48093C6008091C00085FF55
 +:10735000FCCF85E48093C6008091C00085FFFCCF00
 +:107360008DE48093C6008091C00085FFFCCF8FE440
 +:107370008093C6008091C00085FFFCCF84E4809399
 +:10738000C6008091C00085FFFCCF85E48093C600D5
 +:107390008091C00085FFFCCF80E28093C600809181
 +:1073A000C00085FFFCCF83E38093C6008091C000BE
 +:1073B00085FFFCCF80E28093C6008091C00085FFEE
 +:1073C000FCCF82E38093C6008091C00085FFFCCF94
 +:1073D00080E38093C6008091C00085FFFCCF80E3EE
 +:1073E0008093C6008091C00085FFFCCF80E380932E
 +:1073F000C6008091C00085FFFCCF80E28093C6006C
 +:107400008091C00085FFFCCF81E38093C60080910E
 +:10741000C00085FFFCCF8DE08093C6008091C00046
 +:1074200085FFFCCF83E58093C6008091C00085FF77
 +:10743000FCCF85E48093C6008091C00085FFFCCF1F
 +:1074400084E58093C6008091C00085FFFCCF80E278
 +:107450008093C6008091C00085FFFCCF82E48093BA
 +:10746000C6008091C00085FFFCCF84E58093C600F4
 +:107470008091C00085FFFCCF80E28093C6008091A0
 +:10748000C00085FFFCCF82E58093C6008091C000DC
 +:1074900085FFFCCF8FE48093C6008091C00085FFFC
 +:1074A000FCCF8CE48093C6008091C00085FFFCCFA8
 +:1074B00085E48093C6008091C00085FFFCCF80E208
 +:1074C0008093C6008091C00085FFFCCF80E380934D
 +:1074D000C6008091C00085FFFCCF80E28093C6008B
 +:1074E0008091C00085FFFCCF86E68093C600809126
 +:1074F000C00085FFFCCF80E28093C6008091C00071
 +:1075000085FFFCCF87E38093C6008091C00085FF94
 +:10751000FCCF84E68093C6008091C00085FFFCCF3D
 +:1075200080E38093C6008091C00085FFFCCF80E39C
 +:107530008093C6008091C00085FFFCCF8DE08093D2
 +:10754000C60034E1F32E2EE1E22E95E9D92E8FE02C
 +:10755000C82E00E1B02EAA24A39411E4912EB6E522
 +:107560008B2EA2E57A2EF0E26F2EE9E45E2E73E513
 +:10757000472E60E5362E0E948638803359F18133DC
 +:10758000C9F1803409F472C0813409F486C08234B0
 +:1075900021F1853409F474C08035E1F08135D1F0F2
 +:1075A0008235C1F0853509F497C0863509F486C067
 +:1075B000843609F4A0C0843709F40BC1853709F477
 +:1075C00075C18637C1F680E00E94EA380E9486388D
 +:1075D0008033A9F60E940839CECF90E08091C00098
 +:1075E00087FFFCCF8091C6009F5F9431B9F70E945E
 +:1075F0000839C1CF0E948638803209F0BCCF809113
 +:10760000C00085FFFCCFF092C6008091C00085FFCE
 +:10761000FCCF9092C6008091C00085FFFCCF809285
 +:10762000C6008091C00085FFFCCF7092C60080919B
 +:10763000C00085FFFCCF6092C6008091C00085FF2E
 +:10764000FCCF5092C6008091C00085FFFCCF4092D5
 +:10765000C6008091C00085FFFCCF3092C6008091AB
 +:10766000C00085FFFCCFB092C60085CF0E9486384F
 +:10767000863808F4AFCF0E9486380E9408397BCF45
 +:1076800090E08091C00087FFFCCF8091C6009F5F93
 +:107690009530B9F70E9408396ECF0E94863880383D
 +:1076A00031F1813809F48DC0823809F48EC08839EF
 +:1076B00009F089CF83E00E94EA385DCF90E08091A5
 +:1076C000C00087FFFCCF8091C6009F5F9430B9F760
 +:1076D00080E00E94EA387ACF0E94863880930501C4
 +:1076E0000E948638809306010E94083944CF82E0C8
 +:1076F0000E94EA3840CF0E948638809308020E9498
 +:1077000086388093070280910B028E7F80930B0254
 +:107710000E948638853429F480910B028160809321
 +:107720000B028091070290910802892B89F000E0FA
 +:1077300010E00E948638F801E95FFE4F80830F5FFA
 +:107740001F4F80910702909108020817190788F3CC
 +:107750000E948638803209F00ECF80910B0280FFA4
 +:10776000CFC0A0910702B09108021097E9F0609194
 +:10777000050170910601E7E0F1E09B01AD014E0FBC
 +:107780005F1FF999FECF32BD21BD819180BDFA9A6C
 +:10779000F99A2F5F3F4FE417F50799F76A0F7B1FA0
 +:1077A00070930601609305018091C00085FFFCCFB6
 +:1077B000F092C6008091C00085FFFCCFB092C60059
 +:1077C000DACE81E00E94EA38D6CE8FE00E94EA3815
 +:1077D000D2CE0E948638809308020E948638809319
 +:1077E00007020E948638853409F484C080910B0218
 +:1077F0008E7F80930B028091050190910601880F86
 +:10780000991F90930601809305010E94863880326B
 +:1078100009F0B1CE8091C00085FFFCCFF092C60088
 +:10782000A0910702B09108021097B9F180910B0264
 +:10783000182F1170082F0270E0910501F0910601D8
 +:107840009F012F5F3F4FB90140E050E01123B1F499
 +:10785000002339F494918091C00085FFFCCF909370
 +:10786000C6004F5F5F4FCB010196F9014A175B07D6
 +:1078700080F4BC012F5F3F4F112351F3F999FECFE4
 +:10788000F2BDE1BDF89A90B58091C00085FFFCCFB4
 +:10789000E6CF70930601609305018091C00085FDDD
 +:1078A000E2CE8091C00085FFF8CFDDCE0E94863801
 +:1078B000803209F060CE8091C00085FFFCCFF0924D
 +:1078C000C6008091C00085FFFCCFE092C600809189
 +:1078D000C00085FFFCCFD092C6008091C00085FF1C
 +:1078E000FCCFC092C6008091C00085FFFCCFB09253
 +:1078F000C60041CE80910B02816080930B0285CF40
 +:10790000809106018823880F880B8A2180930A02C0
 +:107910008091050190910601880F991F90930601AF
 +:10792000809305018091070280FF09C080910702C2
 +:107930009091080201969093080280930702F894B0
 +:10794000F999FECF1127E0910501F0910601C7E0FA
 +:10795000D1E08091070290910802103091F40091DB
 +:10796000570001700130D9F303E000935700E89508
 +:107970000091570001700130D9F301E100935700E5
 +:10798000E895099019900091570001700130D9F3E2
 +:1079900001E000935700E8951395103498F01127F3
 +:1079A0000091570001700130D9F305E000935700B2
 +:1079B000E8950091570001700130D9F301E100937F
 +:1079C0005700E8953296029709F0C7CF103011F0B2
 +:1079D0000296E5CF11248091C00085FFE5CEE8CE68
 +:0479E000F894FFCF49
 +:0279E400800021
 +:040000030000700089
 +:00000001FF
 diff --git a/bootloaders/bt/Makefile b/bootloaders/bt/Makefile new file mode 100755 index 0000000..431f2e7 --- /dev/null +++ b/bootloaders/bt/Makefile @@ -0,0 +1,109 @@ +# Makefile for ATmegaBOOT +# E.Lins, 18.7.2005 +# $Id$ +# +# Instructions +# +# To make bootloader .hex file: +# make diecimila +# make lilypad +# make ng +# etc... +# +# To burn bootloader .hex file: +# make diecimila_isp +# make lilypad_isp +# make ng_isp +# etc... + +# program name should not be changed... +PROGRAM    = ATmegaBOOT_168 + +# enter the parameters for the avrdude isp tool +ISPTOOL	   = stk500v2 +ISPPORT	   = usb +ISPSPEED   = -b 115200 + +MCU_TARGET = atmega168 +LDSECTION  = --section-start=.text=0x3800 + +# the efuse should really be 0xf8; since, however, only the lower +# three bits of that byte are used on the atmega168, avrdude gets +# confused if you specify 1's for the higher bits, see: +# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/ +# +# similarly, the lock bits should be 0xff instead of 0x3f (to +# unlock the bootloader section) and 0xcf instead of 0x0f (to +# lock it), but since the high two bits of the lock byte are +# unused, avrdude would get confused. + +ISPFUSES    = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ +-e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m +ISPFLASH    = avrdude -c $(ISPTOOL) -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \ +-U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x0f:m + +STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe" +STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \ +-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt +STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt + + +OBJ        = $(PROGRAM).o +OPTIMIZE   = -O2 + +DEFS       =  +LIBS       = + +CC         = avr-gcc + +# Override is only needed by avr-lib build system. + +override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS) +override LDFLAGS       = -Wl,$(LDSECTION) +#override LDFLAGS       = -Wl,-Map,$(PROGRAM).map,$(LDSECTION) + +OBJCOPY        = avr-objcopy +OBJDUMP        = avr-objdump + +all: + +atmega328_bt: TARGET = atmega328_bt +atmega328_bt: MCU_TARGET = atmega328p +atmega328_bt: AVR_FREQ = 16000000L  +atmega328_bt: LDSECTION  = --section-start=.text=0x7000 +atmega328_bt: $(PROGRAM)_atmega328_bt.hex + +atmega328_bt_isp: atmega328_bt +atmega328_bt_isp: TARGET = atmega328_bt +atmega328_bt_isp: MCU_TARGET = atmega328p +atmega328_bt_isp: HFUSE = D8 +atmega328_bt_isp: LFUSE = FF +atmega328_bt_isp: EFUSE = 05 +atmega328_bt_isp: isp + +isp: $(TARGET) +	$(ISPFUSES) +	$(ISPFLASH) + +isp-stk500: $(PROGRAM)_$(TARGET).hex +	$(STK500-1) +	$(STK500-2) + +%.elf: $(OBJ) +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + +clean: +	rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex + +%.lst: %.elf +	$(OBJDUMP) -h -S $< > $@ + +%.hex: %.elf +	$(OBJCOPY) -j .text -j .data -O ihex $< $@ + +%.srec: %.elf +	$(OBJCOPY) -j .text -j .data -O srec $< $@ + +%.bin: %.elf +	$(OBJCOPY) -j .text -j .data -O binary $< $@ +	 | 
