diff options
Diffstat (limited to 'bootloaders/atmega8')
| -rwxr-xr-x | bootloaders/atmega8/ATmegaBOOT.c | 507 | ||||
| -rw-r--r-- | bootloaders/atmega8/ATmegaBOOT.hex | 66 | ||||
| -rw-r--r-- | bootloaders/atmega8/Makefile | 88 | 
3 files changed, 661 insertions, 0 deletions
| diff --git a/bootloaders/atmega8/ATmegaBOOT.c b/bootloaders/atmega8/ATmegaBOOT.c new file mode 100755 index 0000000..17977e6 --- /dev/null +++ b/bootloaders/atmega8/ATmegaBOOT.c @@ -0,0 +1,507 @@ +/**********************************************************/ +/* Serial Bootloader for Atmel mega8 AVR Controller       */ +/*                                                        */ +/* ATmegaBOOT.c                                           */ +/*                                                        */ +/* Copyright (c) 2003, Jason P. Kyle                      */ +/*                                                        */ +/* Hacked by DojoCorp - ZGZ - MMX - IVR                   */ +/* Hacked by David A. Mellis                              */ +/*                                                        */ +/* 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 m8                                  */ +/**********************************************************/ + +#include <inttypes.h> +#include <avr/io.h> +#include <avr/pgmspace.h> +#include <avr/eeprom.h> +#include <avr/interrupt.h> +#include <avr/delay.h> + +//#define F_CPU			16000000 + +/* We, Malmoitians, like slow interaction + * therefore the slow baud rate ;-) + */ +//#define BAUD_RATE		9600 + +/* 6.000.000 is more or less 8 seconds at the + * speed configured here + */ +//#define MAX_TIME_COUNT	6000000 +#define MAX_TIME_COUNT (F_CPU>>1) +///#define MAX_TIME_COUNT_MORATORY	1600000 + +/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */ +#define HW_VER	 0x02 +#define SW_MAJOR 0x01 +#define SW_MINOR 0x12 + +// AVR-GCC compiler compatibility +// avr-gcc compiler v3.1.x and older doesn't support outb() and inb() +//      if necessary, convert outb and inb to outp and inp +#ifndef outb +	#define outb(sfr,val)  (_SFR_BYTE(sfr) = (val)) +#endif +#ifndef inb +	#define inb(sfr) _SFR_BYTE(sfr) +#endif + +/* defines for future compatibility */ +#ifndef cbi +	#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +	#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +/* Adjust to suit whatever pin your hardware uses to enter the bootloader */ +#define eeprom_rb(addr)   eeprom_read_byte ((uint8_t *)(addr)) +#define eeprom_rw(addr)   eeprom_read_word ((uint16_t *)(addr)) +#define eeprom_wb(addr, val)   eeprom_write_byte ((uint8_t *)(addr), (uint8_t)(val)) + +/* Onboard LED is connected to pin PB5 */ +#define LED_DDR  DDRB +#define LED_PORT PORTB +#define LED_PIN  PINB +#define LED      PINB5 + + +#define SIG1	0x1E	// Yep, Atmel is the only manufacturer of AVR micros.  Single source :( +#define SIG2	0x93 +#define SIG3	0x07 +#define PAGE_SIZE	0x20U	//32 words + + +void putch(char); +char getch(void); +void getNch(uint8_t); +void byte_response(uint8_t); +void nothing_response(void); + +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 bootuart0=0,bootuart1=0; + + +void (*app_start)(void) = 0x0000; + +int main(void) +{ +  uint8_t ch,ch2; +  uint16_t w; + +  //cbi(BL_DDR,BL); +  //sbi(BL_PORT,BL); + +  asm volatile("nop\n\t"); + +  /* check if flash is programmed already, if not start bootloader anyway */ +  //if(pgm_read_byte_near(0x0000) != 0xFF) { + +    /* check if bootloader pin is set low */ +    //if(bit_is_set(BL_PIN,BL)) app_start(); +  //} + +  /* initialize UART(s) depending on CPU defined */ +  /* 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 + +  //UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); +  //UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8; +  //UCSRA = 0x00; +  //UCSRC = 0x86; +  //UCSRB = _BV(TXEN)|_BV(RXEN); + + +  /* this was giving uisp problems, so I removed it; without it, the boot +     works on with uisp and avrdude on the mac (at least). */ +  //putch('\0'); + +  //uint32_t l; +  //uint32_t time_count; +  //time_count=0; + +  /* set LED pin as output */ +  sbi(LED_DDR,LED); +	for (i = 0; i < 16; i++) { +		outb(LED_PORT, inb(LED_PORT) ^ _BV(LED)); +		_delay_loop_2(0); +	} +	 +	//for (l=0; l<40000000; l++) +		//outb(LED_PORT, inb(LED_PORT) ^= _BV(LED)); + +  /* flash onboard LED three times to signal entering of bootloader */ +  //for(i=0; i<3; ++i) { +    //for(l=0; l<40000000; ++l); +    //sbi(LED_PORT,LED); +    //for(l=0; l<40000000; ++l); +    //cbi(LED_PORT,LED); +  //} + + /* see comment at previous call to putch() */ + //putch('\0'); // this line is needed for the synchronization of the programmer + +  /* forever */ +  for (;;) { +    //if((inb(UCSRA) & _BV(RXC))){ +    /* 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(); +		  // FIXME: modified only here by DojoCorp, Mumbai, India, 20050626 +		  //time_count=0; // exted the delay once entered prog.mode +		} +	 +		/* Leave programming mode  */ +		else if(ch=='Q') { +		  nothing_response(); +		  //time_count=MAX_TIME_COUNT_MORATORY; 	// once the programming is done,  +												// we should start the application +												// but uisp has problems with this, +												// therefore we just change the times +												// and give the programmer 1 sec to react +		} +	 +		/* 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++) { +						eeprom_wb(address.word,buff[w]); +						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; +			 +					//address.word = address.word << 1;	        //address * 2 -> byte location +					//if ((length.byte[0] & 0x01)) length.word++;	//Even up an odd number of bytes +					cli();					//Disable interrupts, just to be sure +					while(bit_is_set(EECR,EEWE));			//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 words) +							 "lds	r31,address+1	\n\t" +							 "lsl r30				\n\t"  //address * 2 -> byte location +							 "rol r31				\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" +							 "sbrs r24,0		\n\t"  //Even up an odd number of bytes +							 "rjmp length_loop		\n\t" +							 "adiw r24,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"						  +							 "rcall  wait_spm		\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"							  +							 "rcall  wait_spm		\n\t" +//							 "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" +							 "no_page_erase:		\n\t"							  +							 "ld	r0,Y+		\n\t"	//Write 2 bytes into page buffer +							 "ld	r1,Y+		\n\t"							  +										  +							 "rcall  wait_spm		\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 +							 "rcall  wait_spm		\n\t" +//							 "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" +							 "ldi	r16,0x05	\n\t"	//Write page pointed to by Z +							 "sts	%0,r16		\n\t" +							 "spm			\n\t" +							 "rcall  wait_spm		\n\t" +//							 "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"					 		  +							 "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" +							  +							 "wait_spm:  \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_spm       \n\t" +							 "ret			\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 +							 : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"); +			 +					/* 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 (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 +						putch(eeprom_rb(address.word)); +						address.word++; +					} else {	 +						if (!flags.rampz) putch(pgm_read_byte_near(address.word)); +						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); +		} +//    } else { +//			time_count++; +//			if (time_count>=MAX_TIME_COUNT) { +//				app_start(); +//			} +//		} +	} /* end of forever loop */ +} + +void putch(char ch) +{ +  /* m8 */ +  while (!(inb(UCSRA) & _BV(UDRE))); +  outb(UDR,ch); +} + +char getch(void) +{ +  /* m8 */ +	uint32_t count = 0; +  while(!(inb(UCSRA) & _BV(RXC))) { +		/* HACKME:: here is a good place to count times*/ +		count++; +		if (count > MAX_TIME_COUNT) +			app_start(); +  } +  return (inb(UDR)); +} + +void getNch(uint8_t count) +{ +  uint8_t i; +  for(i=0;i<count;i++) { +    /* m8 */ +    //while(!(inb(UCSRA) & _BV(RXC))); +    //inb(UDR); +		getch(); // need to handle time out +  } +} + +void byte_response(uint8_t val) +{ +  if (getch() == ' ') { +    putch(0x14); +    putch(val); +    putch(0x10); +  } +} + +void nothing_response(void) +{ +  if (getch() == ' ') { +    putch(0x14); +    putch(0x10); +  } +} + +/* end of file ATmegaBOOT.c */ + + + diff --git a/bootloaders/atmega8/ATmegaBOOT.hex b/bootloaders/atmega8/ATmegaBOOT.hex new file mode 100644 index 0000000..6190d48 --- /dev/null +++ b/bootloaders/atmega8/ATmegaBOOT.hex @@ -0,0 +1,66 @@ +:101C000012C02BC02AC029C028C027C026C025C0AA
 +:101C100024C023C022C021C020C01FC01EC01DC0C0
 +:101C20001CC01BC01AC011241FBECFE5D4E0DEBF0C
 +:101C3000CDBF10E0A0E6B0E0E8EEFFE102C0059005
 +:101C40000D92A236B107D9F711E0A2E6B0E001C0CB
 +:101C50001D92AA36B107E1F74FC0D2CFEF92FF92A3
 +:101C60000F931F93EE24FF24870113C00894E11CF7
 +:101C7000F11C011D111D81E0E81682E1F8068AE7DA
 +:101C8000080780E0180728F0E0916200F0916300F7
 +:101C900009955F9BEBCF8CB1992787FD90951F919C
 +:101CA0000F91FF90EF9008955D9BFECF8CB9089542
 +:101CB000D5DF803221F484E1F7DF80E1F5DF08959C
 +:101CC0001F93182FCBDF803231F484E1EDDF812FB9
 +:101CD000EBDF80E1E9DF1F9108951F93CF93DF933E
 +:101CE000182FC0E0D0E002C0B9DF2196C117E0F3A1
 +:101CF000DF91CF911F910895CFE5D4E0DEBFCDBF36
 +:101D0000000010BC83E389B988E18AB986E880BD08
 +:101D1000BD9A1092680130E2E0E0F0E02FE088B375
 +:101D2000832788BBCF010197F1F7215027FFF7CF19
 +:101D300020E12093680192DF803381F1813399F4AF
 +:101D40008DDF8032C1F784E1AFDF81E4ADDF86E56E
 +:101D5000ABDF82E5A9DF80E2A7DF89E4A5DF83E5C9
 +:101D6000A3DF80E5C7C0803429F478DF8638B0F07F
 +:101D700075DF14C0813471F471DF803811F482E0B2
 +:101D80001DC1813811F481E019C1823809F015C1F3
 +:101D900082E114C1823421F484E19FDF89DFCBCF5B
 +:101DA000853411F485E0F9CF8035C1F38135B1F385
 +:101DB0008235A1F3853539F451DF809364004EDF1D
 +:101DC00080936500EBCF863519F484E086DFF5C09B
 +:101DD000843609F093C042DF809367013FDF809330
 +:101DE0006601809169018E7F8093690137DF8534B8
 +:101DF00029F480916901816080936901C0E0D0E09D
 +:101E000006E610E005C02ADFF80181938F012196D4
 +:101E10008091660190916701C817D907A0F31EDF72
 +:101E2000803209F088CF8091690180FF1FC020E0D7
 +:101E300030E0E6E6F0E012C0A0916400B0916500E9
 +:101E40008191082EC5D08091640090916500019623
 +:101E500090936500809364002F5F3F4F80916601EF
 +:101E6000909167012817390738F343C0F894E19936
 +:101E7000FECF1127E0916400F0916500EE0FFF1F87
 +:101E8000C6E6D0E0809166019091670180FF01C0B5
 +:101E90000196103051F422D003E000935700E895EA
 +:101EA0001DD001E100935700E8950990199016D0D4
 +:101EB00001E000935700E8951395103258F0112770
 +:101EC0000DD005E000935700E89508D001E100939C
 +:101ED0005700E8953296029739F0DBCF0091570012
 +:101EE00001700130D9F30895103011F00296E7CF58
 +:101EF000112484E1D9DE80E1D7DE1DCF843709F0DB
 +:101F00004BC0ACDE80936701A9DE80936601A6DE3C
 +:101F100090916901853421F49160909369010DC01D
 +:101F20009E7F909369018091640090916500880F75
 +:101F3000991F909365008093640090DE803209F0D1
 +:101F4000FACE84E1B1DEC0E0D0E01EC0809169012C
 +:101F500080FF07C0A0916400B091650031D0802D52
 +:101F600008C081FD07C0E0916400F0916500E49134
 +:101F70008E2F9ADE80916400909165000196909377
 +:101F800065008093640021968091660190916701BD
 +:101F9000C817D907D8F2AFCF853761F45FDE80323A
 +:101FA00009F0C9CE84E180DE8EE17EDE83E97CDE4D
 +:101FB00087E0A0CF863709F0BECE80E081DEBBCEC1
 +:101FC000E199FECFBFBBAEBBE09A11960DB208956A
 +:101FD000E199FECFBFBBAEBB0DBA11960FB6F89418
 +:081FE000E29AE19A0FBE089598
 +:021FE800800077
 +:0400000300001C00DD
 +:00000001FF
 diff --git a/bootloaders/atmega8/Makefile b/bootloaders/atmega8/Makefile new file mode 100644 index 0000000..8c0edd3 --- /dev/null +++ b/bootloaders/atmega8/Makefile @@ -0,0 +1,88 @@ +# Makefile for ATmegaBOOT +# E.Lins, 2004-10-14 + +# program name should not be changed... +PROGRAM    = ATmegaBOOT + +PRODUCT=atmega8 + +# enter the parameters for the UISP isp tool +ISPPARAMS  = -dprog=stk500 -dserial=$(SERIAL) -dspeed=115200 + + +#DIRAVR = /usr/local/avr +DIRAVRBIN = $(DIRAVR)/bin +DIRAVRUTILS = $(DIRAVR)/utils/bin +DIRINC = $(DIRAVR)/include +DIRLIB = $(DIRAVR)/avr/lib + + +MCU_TARGET = atmega8 +LDSECTION  = --section-start=.text=0x1c00 +FUSE_L     = 0xdf +FUSE_H     = 0xca +ISPFUSES   = $(DIRAVRBIN)/uisp -dpart=ATmega8 $(ISPPARAMS) --wr_fuse_l=$(FUSE_L) --wr_fuse_h=$(FUSE_H) +ISPFLASH   = $(DIRAVRBIN)/uisp -dpart=ATmega8 $(ISPPARAMS) --erase --upload if=$(PROGRAM).hex -v + + +OBJ        = $(PROGRAM).o +OPTIMIZE   = -Os + +DEFS       = -DF_CPU=16000000 -DBAUD_RATE=19200 +LIBS       = + +CC         = $(DIRAVRBIN)/avr-gcc + + +# Override is only needed by avr-lib build system. + +override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -D$(PRODUCT) $(DEFS) -I$(DIRINC) +override LDFLAGS       = -Wl,-Map,$(PROGRAM).map,$(LDSECTION) + +OBJCOPY        = $(DIRAVRBIN)/avr-objcopy +OBJDUMP        = $(DIRAVRBIN)/avr-objdump +SIZE           = $(DIRAVRBIN)/avr-size + +all: $(PROGRAM).elf lst text asm size + +isp: $(PROGRAM).hex +	$(ISPFUSES) +	$(ISPFLASH) + +$(PROGRAM).elf: $(OBJ) +	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) + +clean: +	rm -rf *.s +	rm -rf *.o *.elf +	rm -rf *.lst *.map + +asm: $(PROGRAM).s + +%.s: %.c +	$(CC) -S $(CFLAGS) -g1 $^ + +lst:  $(PROGRAM).lst + +%.lst: %.elf +	$(OBJDUMP) -h -S $< > $@ + +size: $(PROGRAM).hex +	$(SIZE) $^ + +# Rules for building the .text rom images + +text: hex bin srec + +hex:  $(PROGRAM).hex +bin:  $(PROGRAM).bin +srec: $(PROGRAM).srec + +%.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 $< $@ | 
