add arduino-0018-linux (32 bit)
This commit is contained in:
		
							parent
							
								
									7fa52a235a
								
							
						
					
					
						commit
						297de2a227
					
				
					 425 changed files with 64818 additions and 0 deletions
				
			
		
							
								
								
									
										507
									
								
								arduino-0018-linux/hardware/arduino/bootloaders/atmega8/ATmegaBOOT.c
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										507
									
								
								arduino-0018-linux/hardware/arduino/bootloaders/atmega8/ATmegaBOOT.c
									
										
									
									
									
										Executable file
									
								
							| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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 $< $@
 | 
			
		||||
		Reference in a new issue