+++ /dev/null
-/**********************************************************/\r
-/* Serial Bootloader for Atmel megaAVR Controllers */\r
-/* */\r
-/* tested with ATmega8, ATmega128 and ATmega168 */\r
-/* should work with other mega's, see code for details */\r
-/* */\r
-/* ATmegaBOOT.c */\r
-/* */\r
-/* */\r
-/* 20090308: integrated Mega changes into main bootloader */\r
-/* source by D. Mellis */\r
-/* 20080930: hacked for Arduino Mega (with the 1280 */\r
-/* processor, backwards compatible) */\r
-/* by D. Cuartielles */\r
-/* 20070626: hacked for Arduino Diecimila (which auto- */\r
-/* resets when a USB connection is made to it) */\r
-/* by D. Mellis */\r
-/* 20060802: hacked for Arduino by D. Cuartielles */\r
-/* based on a previous hack by D. Mellis */\r
-/* and D. Cuartielles */\r
-/* */\r
-/* Monitor and debug functions were added to the original */\r
-/* code by Dr. Erik Lins, chip45.com. (See below) */\r
-/* */\r
-/* Thanks to Karl Pitrich for fixing a bootloader pin */\r
-/* problem and more informative LED blinking! */\r
-/* */\r
-/* For the latest version see: */\r
-/* http://www.chip45.com/ */\r
-/* */\r
-/* ------------------------------------------------------ */\r
-/* */\r
-/* based on stk500boot.c */\r
-/* Copyright (c) 2003, Jason P. Kyle */\r
-/* All rights reserved. */\r
-/* see avr1.org for original file and information */\r
-/* */\r
-/* This program is free software; you can redistribute it */\r
-/* and/or modify it under the terms of the GNU General */\r
-/* Public License as published by the Free Software */\r
-/* Foundation; either version 2 of the License, or */\r
-/* (at your option) any later version. */\r
-/* */\r
-/* This program is distributed in the hope that it will */\r
-/* be useful, but WITHOUT ANY WARRANTY; without even the */\r
-/* implied warranty of MERCHANTABILITY or FITNESS FOR A */\r
-/* PARTICULAR PURPOSE. See the GNU General Public */\r
-/* License for more details. */\r
-/* */\r
-/* You should have received a copy of the GNU General */\r
-/* Public License along with this program; if not, write */\r
-/* to the Free Software Foundation, Inc., */\r
-/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */\r
-/* */\r
-/* Licence can be viewed at */\r
-/* http://www.fsf.org/licenses/gpl.txt */\r
-/* */\r
-/* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */\r
-/* m8515,m8535. ATmega161 has a very small boot block so */\r
-/* isn't supported. */\r
-/* */\r
-/* Tested with m168 */\r
-/**********************************************************/\r
-\r
-\r
-/* some includes */\r
-#include <inttypes.h>\r
-#include <avr/io.h>\r
-#include <avr/pgmspace.h>\r
-#include <avr/interrupt.h>\r
-#include <avr/wdt.h>\r
-#include <util/delay.h>\r
-\r
-/* the current avr-libc eeprom functions do not support the ATmega168 */\r
-/* own eeprom write/read functions are used instead */\r
-#if !defined(__AVR_ATmega168__) || !defined(__AVR_ATmega328P__) || !defined(__AVR_ATmega328__) || defined(__AVR_ATmega644P__)\r
-#include <avr/eeprom.h>\r
-#endif\r
-\r
-/* Use the F_CPU defined in Makefile */\r
-\r
-/* 20060803: hacked by DojoCorp */\r
-/* 20070626: hacked by David A. Mellis to decrease waiting time for auto-reset */\r
-/* set the waiting time for the bootloader */\r
-/* get this from the Makefile instead */\r
-/* #define MAX_TIME_COUNT (F_CPU>>4) */\r
-\r
-/* 20070707: hacked by David A. Mellis - after this many errors give up and launch application */\r
-#define MAX_ERROR_COUNT 5\r
-\r
-/* set the UART baud rate */\r
-/* 20060803: hacked by DojoCorp */\r
-//#define BAUD_RATE 115200\r
-#ifndef BAUD_RATE\r
-#define BAUD_RATE 19200\r
-#endif\r
-\r
-\r
-/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */\r
-/* never allow AVR Studio to do an update !!!! */\r
-#define HW_VER 0x02\r
-#define SW_MAJOR 0x01\r
-#define SW_MINOR 0x10\r
-\r
-\r
-/* Adjust to suit whatever pin your hardware uses to enter the bootloader */\r
-/* ATmega128 has two UARTS so two pins are used to enter bootloader and select UART */\r
-/* ATmega1280 has four UARTS, but for Arduino Mega, we will only use RXD0 to get code */\r
-/* BL0... means UART0, BL1... means UART1 */\r
-#ifdef __AVR_ATmega128__\r
-#define BL_DDR DDRF\r
-#define BL_PORT PORTF\r
-#define BL_PIN PINF\r
-#define BL0 PINF7\r
-#define BL1 PINF6\r
-#elif defined __AVR_ATmega1280__ \r
-/* we just don't do anything for the MEGA and enter bootloader on reset anyway*/\r
-#else\r
-/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */\r
-#define BL_DDR DDRD\r
-#define BL_PORT PORTD\r
-#define BL_PIN PIND\r
-#define BL PIND6\r
-#endif\r
-\r
-\r
-/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */\r
-/* if monitor functions are included, LED goes on after monitor was entered */\r
-#if defined __AVR_ATmega128__ || defined __AVR_ATmega1280__\r
-/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128, Arduino Mega) */\r
-#define LED_DDR DDRB\r
-#define LED_PORT PORTB\r
-#define LED_PIN PINB\r
-#define LED PINB7\r
-#elif __AVR_ATmega644P__\r
-#define LED_DDR DDRC\r
-#define LED_PORT PORTC\r
-#define LED_PIN PINC\r
-#define LED PINC4\r
-\r
-#else\r
-/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duomilanuove */ \r
-/* other boards like e.g. Crumb8, Crumb168 are using PB2 */\r
-#define LED_DDR DDRB\r
-#define LED_PORT PORTB\r
-#define LED_PIN PINB\r
-#define LED PINB5\r
-#endif\r
-\r
-\r
-/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
-#define MONITOR 1\r
-#endif\r
-\r
-\r
-/* define various device id's */\r
-/* manufacturer byte is always the same */\r
-#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :(\r
-\r
-#if defined __AVR_ATmega1280__\r
-#define SIG2 0x97\r
-#define SIG3 0x03\r
-#define PAGE_SIZE 0x80U //128 words\r
-\r
-#elif defined __AVR_ATmega1281__\r
-#define SIG2 0x97\r
-#define SIG3 0x04\r
-#define PAGE_SIZE 0x80U //128 words\r
-\r
-#elif defined __AVR_ATmega128__\r
-#define SIG2 0x97\r
-#define SIG3 0x02\r
-#define PAGE_SIZE 0x80U //128 words\r
-\r
-#elif defined __AVR_ATmega64__\r
-#define SIG2 0x96\r
-#define SIG3 0x02\r
-#define PAGE_SIZE 0x80U //128 words\r
-\r
-#elif defined __AVR_ATmega32__\r
-#define SIG2 0x95\r
-#define SIG3 0x02\r
-#define PAGE_SIZE 0x40U //64 words\r
-\r
-#elif defined __AVR_ATmega16__\r
-#define SIG2 0x94\r
-#define SIG3 0x03\r
-#define PAGE_SIZE 0x40U //64 words\r
-\r
-#elif defined __AVR_ATmega8__\r
-#define SIG2 0x93\r
-#define SIG3 0x07\r
-#define PAGE_SIZE 0x20U //32 words\r
-\r
-#elif defined __AVR_ATmega88__\r
-#define SIG2 0x93\r
-#define SIG3 0x0a\r
-#define PAGE_SIZE 0x20U //32 words\r
-\r
-#elif defined __AVR_ATmega168__\r
-#define SIG2 0x94\r
-#define SIG3 0x06\r
-#define PAGE_SIZE 0x40U //64 words\r
-\r
-#elif defined __AVR_ATmega328P__\r
-#define SIG2 0x95\r
-#define SIG3 0x0F\r
-#define PAGE_SIZE 0x40U //64 words\r
-\r
-#elif defined __AVR_ATmega328__\r
-#define SIG2 0x95\r
-#define SIG3 0x14\r
-#define PAGE_SIZE 0x40U //64 words\r
-\r
-#elif defined __AVR_ATmega644P__\r
-#define SIG2 0x96\r
-#define SIG3 0x0A\r
-#define PAGE_SIZE 0x80U //128 words\r
-\r
-#elif defined __AVR_ATmega162__\r
-#define SIG2 0x94\r
-#define SIG3 0x04\r
-#define PAGE_SIZE 0x40U //64 words\r
-\r
-#elif defined __AVR_ATmega163__\r
-#define SIG2 0x94\r
-#define SIG3 0x02\r
-#define PAGE_SIZE 0x40U //64 words\r
-\r
-#elif defined __AVR_ATmega169__\r
-#define SIG2 0x94\r
-#define SIG3 0x05\r
-#define PAGE_SIZE 0x40U //64 words\r
-\r
-#elif defined __AVR_ATmega8515__\r
-#define SIG2 0x93\r
-#define SIG3 0x06\r
-#define PAGE_SIZE 0x20U //32 words\r
-\r
-#elif defined __AVR_ATmega8535__\r
-#define SIG2 0x93\r
-#define SIG3 0x08\r
-#define PAGE_SIZE 0x20U //32 words\r
-#endif\r
-\r
-\r
-/* function prototypes */\r
-void putch(char);\r
-char getch(void);\r
-void getNch(uint8_t);\r
-void byte_response(uint8_t);\r
-void nothing_response(void);\r
-char gethex(void);\r
-void puthex(char);\r
-void flash_led(uint8_t);\r
-\r
-/* some variables */\r
-union address_union {\r
- uint16_t word;\r
- uint8_t byte[2];\r
-} address;\r
-\r
-union length_union {\r
- uint16_t word;\r
- uint8_t byte[2];\r
-} length;\r
-\r
-struct flags_struct {\r
- unsigned eeprom : 1;\r
- unsigned rampz : 1;\r
-} flags;\r
-\r
-uint8_t buff[256];\r
-uint8_t address_high;\r
-\r
-uint8_t pagesz=0x80;\r
-\r
-uint8_t i;\r
-uint8_t bootuart = 0;\r
-\r
-uint8_t error_count = 0;\r
-\r
-void (*app_start)(void) = 0x0000;\r
-\r
-\r
-/* main program starts here */\r
-int main(void)\r
-{\r
- uint8_t ch,ch2;\r
- uint16_t w;\r
-\r
-\r
-#ifdef __AVR_ATmega644P__\r
- DDRC = 0x1C;\r
- PORTC = 0;\r
-#endif\r
-\r
-#ifdef WATCHDOG_MODS\r
- ch = MCUSR;\r
- MCUSR = 0;\r
-\r
- WDTCSR |= _BV(WDCE) | _BV(WDE);\r
- WDTCSR = 0;\r
-\r
- // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot.\r
- if (! (ch & _BV(EXTRF))) // if its a not an external reset...\r
- app_start(); // skip bootloader\r
-#else\r
- asm volatile("nop\n\t");\r
-#endif\r
-\r
- /* set pin direction for bootloader pin and enable pullup */\r
- /* for ATmega128, two pins need to be initialized */\r
-#ifdef __AVR_ATmega128__\r
- BL_DDR &= ~_BV(BL0);\r
- BL_DDR &= ~_BV(BL1);\r
- BL_PORT |= _BV(BL0);\r
- BL_PORT |= _BV(BL1);\r
-#else\r
- /* We run the bootloader regardless of the state of this pin. Thus, don't\r
- put it in a different state than the other pins. --DAM, 070709\r
- This also applies to Arduino Mega -- DC, 080930\r
- BL_DDR &= ~_BV(BL);\r
- BL_PORT |= _BV(BL);\r
- */\r
-#endif\r
-\r
-\r
-#ifdef __AVR_ATmega128__\r
- /* check which UART should be used for booting */\r
- if(bit_is_clear(BL_PIN, BL0)) {\r
- bootuart = 1;\r
- }\r
- else if(bit_is_clear(BL_PIN, BL1)) {\r
- bootuart = 2;\r
- }\r
-#endif\r
-\r
-#if defined __AVR_ATmega1280__\r
- /* the mega1280 chip has four serial ports ... we could eventually use any of them, or not? */\r
- /* however, we don't wanna confuse people, to avoid making a mess, we will stick to RXD0, TXD0 */\r
- bootuart = 1;\r
-#endif\r
-\r
- /* check if flash is programmed already, if not start bootloader anyway */\r
- if(pgm_read_byte_near(0x0000) != 0xFF) {\r
-\r
-#ifdef __AVR_ATmega128__\r
- /* no UART was selected, start application */\r
- if(!bootuart) {\r
- app_start();\r
- }\r
-#else\r
- /* check if bootloader pin is set low */\r
- /* we don't start this part neither for the m8, nor m168 */\r
- //if(bit_is_set(BL_PIN, BL)) {\r
- // app_start();\r
- // }\r
-#endif\r
- }\r
-\r
-#ifdef __AVR_ATmega128__ \r
- /* no bootuart was selected, default to uart 0 */\r
- if(!bootuart) {\r
- bootuart = 1;\r
- }\r
-#endif\r
-\r
-\r
- /* initialize UART(s) depending on CPU defined */\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- if(bootuart == 1) {\r
- UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);\r
- UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;\r
- UCSR0A = 0x00;\r
- UCSR0C = 0x06;\r
- UCSR0B = _BV(TXEN0)|_BV(RXEN0);\r
- }\r
- if(bootuart == 2) {\r
- UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);\r
- UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;\r
- UCSR1A = 0x00;\r
- UCSR1C = 0x06;\r
- UCSR1B = _BV(TXEN1)|_BV(RXEN1);\r
- }\r
-#elif defined __AVR_ATmega163__\r
- UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);\r
- UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8;\r
- UCSRA = 0x00;\r
- UCSRB = _BV(TXEN)|_BV(RXEN); \r
-#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined __AVR_ATmega644P__\r
-\r
-#ifdef DOUBLE_SPEED\r
- UCSR0A = (1<<U2X0); //Double speed mode USART0\r
- UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*8L)-1);\r
- UBRR0H = (F_CPU/(BAUD_RATE*8L)-1) >> 8;\r
-#else\r
- UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);\r
- UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;\r
-#endif\r
-\r
- UCSR0B = (1<<RXEN0) | (1<<TXEN0);\r
- UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);\r
-\r
- /* Enable internal pull-up resistor on pin D0 (RX), in order\r
- to suppress line noise that prevents the bootloader from\r
- timing out (DAM: 20070509) */\r
- DDRD &= ~_BV(PIND0);\r
- PORTD |= _BV(PIND0);\r
-#elif defined __AVR_ATmega8__\r
- /* m8 */\r
- UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate\r
- UBRRL = (((F_CPU/BAUD_RATE)/16)-1);\r
- UCSRB = (1<<RXEN)|(1<<TXEN); // enable Rx & Tx\r
- UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // config USART; 8N1\r
-#else\r
- /* m16,m32,m169,m8515,m8535 */\r
- UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);\r
- UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;\r
- UCSRA = 0x00;\r
- UCSRC = 0x06;\r
- UCSRB = _BV(TXEN)|_BV(RXEN);\r
-#endif\r
-\r
-#if defined __AVR_ATmega1280__\r
- /* Enable internal pull-up resistor on pin D0 (RX), in order\r
- to suppress line noise that prevents the bootloader from\r
- timing out (DAM: 20070509) */\r
- /* feature added to the Arduino Mega --DC: 080930 */\r
- DDRE &= ~_BV(PINE0);\r
- PORTE |= _BV(PINE0);\r
-#endif\r
-\r
-\r
- /* set LED pin as output */\r
- LED_DDR |= _BV(LED);\r
-\r
-\r
- /* flash onboard LED to signal entering of bootloader */\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- // 4x for UART0, 5x for UART1\r
- flash_led(NUM_LED_FLASHES + bootuart);\r
-#else\r
- flash_led(NUM_LED_FLASHES);\r
-#endif\r
-\r
- /* 20050803: by DojoCorp, this is one of the parts provoking the\r
- system to stop listening, cancelled from the original */\r
- //putch('\0');\r
-\r
- /* forever loop */\r
- for (;;) {\r
-\r
- /* get character from UART */\r
- ch = getch();\r
-\r
- /* A bunch of if...else if... gives smaller code than switch...case ! */\r
-\r
- /* Hello is anyone home ? */ \r
- if(ch=='0') {\r
- nothing_response();\r
- }\r
-\r
-\r
- /* Request programmer ID */\r
- /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundary */\r
- /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares. */\r
- else if(ch=='1') {\r
- if (getch() == ' ') {\r
- putch(0x14);\r
- putch('A');\r
- putch('V');\r
- putch('R');\r
- putch(' ');\r
- putch('I');\r
- putch('S');\r
- putch('P');\r
- putch(0x10);\r
- } else {\r
- if (++error_count == MAX_ERROR_COUNT)\r
- app_start();\r
- }\r
- }\r
-\r
-\r
- /* AVR ISP/STK500 board commands DON'T CARE so default nothing_response */\r
- else if(ch=='@') {\r
- ch2 = getch();\r
- if (ch2>0x85) getch();\r
- nothing_response();\r
- }\r
-\r
-\r
- /* AVR ISP/STK500 board requests */\r
- else if(ch=='A') {\r
- ch2 = getch();\r
- if(ch2==0x80) byte_response(HW_VER); // Hardware version\r
- else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version\r
- else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version\r
- else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56\r
- else byte_response(0x00); // Covers various unnecessary responses we don't care about\r
- }\r
-\r
-\r
- /* Device Parameters DON'T CARE, DEVICE IS FIXED */\r
- else if(ch=='B') {\r
- getNch(20);\r
- nothing_response();\r
- }\r
-\r
-\r
- /* Parallel programming stuff DON'T CARE */\r
- else if(ch=='E') {\r
- getNch(5);\r
- nothing_response();\r
- }\r
-\r
-\r
- /* P: Enter programming mode */\r
- /* R: Erase device, don't care as we will erase one page at a time anyway. */\r
- else if(ch=='P' || ch=='R') {\r
- nothing_response();\r
- }\r
-\r
-\r
- /* Leave programming mode */\r
- else if(ch=='Q') {\r
- nothing_response();\r
-#ifdef WATCHDOG_MODS\r
- // autoreset via watchdog (sneaky!)\r
- WDTCSR = _BV(WDE);\r
- while (1); // 16 ms\r
-#endif\r
- }\r
-\r
-\r
- /* Set address, little endian. EEPROM in bytes, FLASH in words */\r
- /* Perhaps extra address bytes may be added in future to support > 128kB FLASH. */\r
- /* This might explain why little endian was used here, big endian used everywhere else. */\r
- else if(ch=='U') {\r
- address.byte[0] = getch();\r
- address.byte[1] = getch();\r
- nothing_response();\r
- }\r
-\r
-\r
- /* Universal SPI programming command, disabled. Would be used for fuses and lock bits. */\r
- else if(ch=='V') {\r
- if (getch() == 0x30) {\r
- getch();\r
- ch = getch();\r
- getch();\r
- if (ch == 0) {\r
- byte_response(SIG1);\r
- } else if (ch == 1) {\r
- byte_response(SIG2); \r
- } else {\r
- byte_response(SIG3);\r
- } \r
- } else {\r
- getNch(3);\r
- byte_response(0x00);\r
- }\r
- }\r
-\r
-\r
- /* Write memory, length is big endian and is in bytes */\r
- else if(ch=='d') {\r
- length.byte[1] = getch();\r
- length.byte[0] = getch();\r
- flags.eeprom = 0;\r
- if (getch() == 'E') flags.eeprom = 1;\r
- for (w=0;w<length.word;w++) {\r
- buff[w] = getch(); // Store data in buffer, can't keep up with serial data stream whilst programming pages\r
- }\r
- if (getch() == ' ') {\r
- if (flags.eeprom) { //Write to EEPROM one byte at a time\r
- address.word <<= 1;\r
- for(w=0;w<length.word;w++) {\r
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega644P__)\r
- while(EECR & (1<<EEPE));\r
- EEAR = (uint16_t)(void *)address.word;\r
- EEDR = buff[w];\r
- EECR |= (1<<EEMPE);\r
- EECR |= (1<<EEPE);\r
-#else\r
- eeprom_write_byte((void *)address.word,buff[w]);\r
-#endif\r
- address.word++;\r
- } \r
- }\r
- else { //Write to FLASH one page at a time\r
- if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME\r
- else address_high = 0x00;\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)\r
- RAMPZ = address_high;\r
-#endif\r
- address.word = address.word << 1; //address * 2 -> byte location\r
- /* if ((length.byte[0] & 0x01) == 0x01) length.word++; //Even up an odd number of bytes */\r
- if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes\r
- cli(); //Disable interrupts, just to be sure\r
-#if defined(EEPE)\r
- while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete\r
-#else\r
- while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete\r
-#endif\r
- asm volatile(\r
- "clr r17 \n\t" //page_word_count\r
- "lds r30,address \n\t" //Address of FLASH location (in bytes)\r
- "lds r31,address+1 \n\t"\r
- "ldi r28,lo8(buff) \n\t" //Start of buffer array in RAM\r
- "ldi r29,hi8(buff) \n\t"\r
- "lds r24,length \n\t" //Length of data to be written (in bytes)\r
- "lds r25,length+1 \n\t"\r
- "length_loop: \n\t" //Main loop, repeat for number of words in block \r
- "cpi r17,0x00 \n\t" //If page_word_count=0 then erase page\r
- "brne no_page_erase \n\t" \r
- "wait_spm1: \n\t"\r
- "lds r16,%0 \n\t" //Wait for previous spm to complete\r
- "andi r16,1 \n\t"\r
- "cpi r16,1 \n\t"\r
- "breq wait_spm1 \n\t"\r
- "ldi r16,0x03 \n\t" //Erase page pointed to by Z\r
- "sts %0,r16 \n\t"\r
- "spm \n\t" \r
-#ifdef __AVR_ATmega163__\r
- ".word 0xFFFF \n\t"\r
- "nop \n\t"\r
-#endif\r
- "wait_spm2: \n\t"\r
- "lds r16,%0 \n\t" //Wait for previous spm to complete\r
- "andi r16,1 \n\t"\r
- "cpi r16,1 \n\t"\r
- "breq wait_spm2 \n\t" \r
-\r
- "ldi r16,0x11 \n\t" //Re-enable RWW section\r
- "sts %0,r16 \n\t" \r
- "spm \n\t"\r
-#ifdef __AVR_ATmega163__\r
- ".word 0xFFFF \n\t"\r
- "nop \n\t"\r
-#endif\r
- "no_page_erase: \n\t" \r
- "ld r0,Y+ \n\t" //Write 2 bytes into page buffer\r
- "ld r1,Y+ \n\t" \r
- \r
- "wait_spm3: \n\t"\r
- "lds r16,%0 \n\t" //Wait for previous spm to complete\r
- "andi r16,1 \n\t"\r
- "cpi r16,1 \n\t"\r
- "breq wait_spm3 \n\t"\r
- "ldi r16,0x01 \n\t" //Load r0,r1 into FLASH page buffer\r
- "sts %0,r16 \n\t"\r
- "spm \n\t"\r
- \r
- "inc r17 \n\t" //page_word_count++\r
- "cpi r17,%1 \n\t"\r
- "brlo same_page \n\t" //Still same page in FLASH\r
- "write_page: \n\t"\r
- "clr r17 \n\t" //New page, write current one first\r
- "wait_spm4: \n\t"\r
- "lds r16,%0 \n\t" //Wait for previous spm to complete\r
- "andi r16,1 \n\t"\r
- "cpi r16,1 \n\t"\r
- "breq wait_spm4 \n\t"\r
-#ifdef __AVR_ATmega163__\r
- "andi r30,0x80 \n\t" // m163 requires Z6:Z1 to be zero during page write\r
-#endif \r
- "ldi r16,0x05 \n\t" //Write page pointed to by Z\r
- "sts %0,r16 \n\t"\r
- "spm \n\t"\r
-#ifdef __AVR_ATmega163__\r
- ".word 0xFFFF \n\t"\r
- "nop \n\t"\r
- "ori r30,0x7E \n\t" // recover Z6:Z1 state after page write (had to be zero during write)\r
-#endif\r
- "wait_spm5: \n\t"\r
- "lds r16,%0 \n\t" //Wait for previous spm to complete\r
- "andi r16,1 \n\t"\r
- "cpi r16,1 \n\t"\r
- "breq wait_spm5 \n\t" \r
- "ldi r16,0x11 \n\t" //Re-enable RWW section\r
- "sts %0,r16 \n\t" \r
- "spm \n\t" \r
-#ifdef __AVR_ATmega163__\r
- ".word 0xFFFF \n\t"\r
- "nop \n\t"\r
-#endif\r
- "same_page: \n\t" \r
- "adiw r30,2 \n\t" //Next word in FLASH\r
- "sbiw r24,2 \n\t" //length-2\r
- "breq final_write \n\t" //Finished\r
- "rjmp length_loop \n\t"\r
- "final_write: \n\t"\r
- "cpi r17,0 \n\t"\r
- "breq block_done \n\t"\r
- "adiw r24,2 \n\t" //length+2, fool above check on length after short page write\r
- "rjmp write_page \n\t"\r
- "block_done: \n\t"\r
- "clr __zero_reg__ \n\t" //restore zero register\r
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega644P__)\r
- : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"\r
-\r
-#else\r
- : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"\r
-#endif\r
- );\r
- /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */\r
- /* exit the bootloader without a power cycle anyhow */\r
- }\r
- putch(0x14);\r
- putch(0x10);\r
- } else {\r
- if (++error_count == MAX_ERROR_COUNT)\r
- app_start();\r
- } \r
- }\r
-\r
-\r
- /* Read memory block mode, length is big endian. */\r
- else if(ch=='t') {\r
- length.byte[1] = getch();\r
- length.byte[0] = getch();\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- if (address.word>0x7FFF) flags.rampz = 1; // No go with m256, FIXME\r
- else flags.rampz = 0;\r
-#endif\r
- address.word = address.word << 1; // address * 2 -> byte location\r
- if (getch() == 'E') flags.eeprom = 1;\r
- else flags.eeprom = 0;\r
- if (getch() == ' ') { // Command terminator\r
- putch(0x14);\r
- for (w=0;w < length.word;w++) { // Can handle odd and even lengths okay\r
- if (flags.eeprom) { // Byte access EEPROM read\r
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega644P__)\r
- while(EECR & (1<<EEPE));\r
- EEAR = (uint16_t)(void *)address.word;\r
- EECR |= (1<<EERE);\r
- putch(EEDR);\r
-#else\r
- putch(eeprom_read_byte((void *)address.word));\r
-#endif\r
- address.word++;\r
- }\r
- else {\r
-\r
- if (!flags.rampz) putch(pgm_read_byte_near(address.word));\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- else putch(pgm_read_byte_far(address.word + 0x10000));\r
- // Hmmmm, yuck FIXME when m256 arrives\r
-#endif\r
- address.word++;\r
- }\r
- }\r
- putch(0x10);\r
- }\r
- }\r
-\r
-\r
- /* Get device signature bytes */\r
- else if(ch=='u') {\r
- if (getch() == ' ') {\r
- putch(0x14);\r
- putch(SIG1);\r
- putch(SIG2);\r
- putch(SIG3);\r
- putch(0x10);\r
- } else {\r
- if (++error_count == MAX_ERROR_COUNT)\r
- app_start();\r
- }\r
- }\r
-\r
-\r
- /* Read oscillator calibration byte */\r
- else if(ch=='v') {\r
- byte_response(0x00);\r
- }\r
-\r
-\r
-#if defined MONITOR \r
-\r
- /* here come the extended monitor commands by Erik Lins */\r
-\r
- /* check for three times exclamation mark pressed */\r
- else if(ch=='!') {\r
- ch = getch();\r
- if(ch=='!') {\r
- ch = getch();\r
- if(ch=='!') {\r
- PGM_P welcome = "";\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- uint16_t extaddr;\r
-#endif\r
- uint8_t addrl, addrh;\r
-\r
-#ifdef CRUMB128\r
- welcome = "ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r";\r
-#elif defined PROBOMEGA128\r
- welcome = "ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r";\r
-#elif defined SAVVY128\r
- welcome = "ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r";\r
-#elif defined __AVR_ATmega1280__ \r
- welcome = "ATmegaBOOT / Arduino Mega - (C) Arduino LLC - 090930\n\r";\r
-#endif\r
-\r
- /* turn on LED */\r
- LED_DDR |= _BV(LED);\r
- LED_PORT &= ~_BV(LED);\r
-\r
- /* print a welcome message and command overview */\r
- for(i=0; welcome[i] != '\0'; ++i) {\r
- putch(welcome[i]);\r
- }\r
-\r
- /* test for valid commands */\r
- for(;;) {\r
- putch('\n');\r
- putch('\r');\r
- putch(':');\r
- putch(' ');\r
-\r
- ch = getch();\r
- putch(ch);\r
-\r
- /* toggle LED */\r
- if(ch == 't') {\r
- if(bit_is_set(LED_PIN,LED)) {\r
- LED_PORT &= ~_BV(LED);\r
- putch('1');\r
- } else {\r
- LED_PORT |= _BV(LED);\r
- putch('0');\r
- }\r
- } \r
-\r
- /* read byte from address */\r
- else if(ch == 'r') {\r
- ch = getch(); putch(ch);\r
- addrh = gethex();\r
- addrl = gethex();\r
- putch('=');\r
- ch = *(uint8_t *)((addrh << 8) + addrl);\r
- puthex(ch);\r
- }\r
-\r
- /* write a byte to address */\r
- else if(ch == 'w') {\r
- ch = getch(); putch(ch);\r
- addrh = gethex();\r
- addrl = gethex();\r
- ch = getch(); putch(ch);\r
- ch = gethex();\r
- *(uint8_t *)((addrh << 8) + addrl) = ch;\r
- }\r
-\r
- /* read from uart and echo back */\r
- else if(ch == 'u') {\r
- for(;;) {\r
- putch(getch());\r
- }\r
- }\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- /* external bus loop */\r
- else if(ch == 'b') {\r
- putch('b');\r
- putch('u');\r
- putch('s');\r
- MCUCR = 0x80;\r
- XMCRA = 0;\r
- XMCRB = 0;\r
- extaddr = 0x1100;\r
- for(;;) {\r
- ch = *(volatile uint8_t *)extaddr;\r
- if(++extaddr == 0) {\r
- extaddr = 0x1100;\r
- }\r
- }\r
- }\r
-#endif\r
-\r
- else if(ch == 'j') {\r
- app_start();\r
- }\r
-\r
- } /* end of monitor functions */\r
-\r
- }\r
- }\r
- }\r
- /* end of monitor */\r
-#endif\r
- else if (++error_count == MAX_ERROR_COUNT) {\r
- app_start();\r
- }\r
- } /* end of forever loop */\r
-\r
-}\r
-\r
-\r
-char gethexnib(void) {\r
- char a;\r
- a = getch(); putch(a);\r
- if(a >= 'a') {\r
- return (a - 'a' + 0x0a);\r
- } else if(a >= '0') {\r
- return(a - '0');\r
- }\r
- return a;\r
-}\r
-\r
-\r
-char gethex(void) {\r
- return (gethexnib() << 4) + gethexnib();\r
-}\r
-\r
-\r
-void puthex(char ch) {\r
- char ah;\r
-\r
- ah = ch >> 4;\r
- if(ah >= 0x0a) {\r
- ah = ah - 0x0a + 'a';\r
- } else {\r
- ah += '0';\r
- }\r
- \r
- ch &= 0x0f;\r
- if(ch >= 0x0a) {\r
- ch = ch - 0x0a + 'a';\r
- } else {\r
- ch += '0';\r
- }\r
- \r
- putch(ah);\r
- putch(ch);\r
-}\r
-\r
-\r
-void putch(char ch)\r
-{\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- if(bootuart == 1) {\r
- while (!(UCSR0A & _BV(UDRE0)));\r
- UDR0 = ch;\r
- }\r
- else if (bootuart == 2) {\r
- while (!(UCSR1A & _BV(UDRE1)));\r
- UDR1 = ch;\r
- }\r
-#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega644P__)\r
- while (!(UCSR0A & _BV(UDRE0)));\r
- UDR0 = ch;\r
-#else\r
- /* m8,16,32,169,8515,8535,163 */\r
- while (!(UCSRA & _BV(UDRE)));\r
- UDR = ch;\r
-#endif\r
-}\r
-\r
-\r
-char getch(void)\r
-{\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- uint32_t count = 0;\r
- if(bootuart == 1) {\r
- while(!(UCSR0A & _BV(RXC0))) {\r
- /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ \r
- /* HACKME:: here is a good place to count times*/\r
- count++;\r
- if (count > MAX_TIME_COUNT)\r
- app_start();\r
- }\r
-\r
- return UDR0;\r
- }\r
- else if(bootuart == 2) {\r
- while(!(UCSR1A & _BV(RXC1))) {\r
- /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ \r
- /* HACKME:: here is a good place to count times*/\r
- count++;\r
- if (count > MAX_TIME_COUNT)\r
- app_start();\r
- }\r
-\r
- return UDR1;\r
- }\r
- return 0;\r
-#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega644P__)\r
- uint32_t count = 0;\r
- while(!(UCSR0A & _BV(RXC0))){\r
- /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ \r
- /* HACKME:: here is a good place to count times*/\r
- count++;\r
- if (count > MAX_TIME_COUNT) {\r
- app_start();\r
- }\r
- }\r
- return UDR0;\r
-\r
-#else\r
- /* m8,16,32,169,8515,8535,163 */\r
- uint32_t count = 0;\r
- while(!(UCSRA & _BV(RXC))){\r
- /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ \r
- /* HACKME:: here is a good place to count times*/\r
- count++;\r
- if (count > MAX_TIME_COUNT)\r
- app_start();\r
- }\r
- return UDR;\r
-#endif\r
-}\r
-\r
-\r
-void getNch(uint8_t count)\r
-{\r
- while(count--) {\r
-#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)\r
- if(bootuart == 1) {\r
- while(!(UCSR0A & _BV(RXC0)));\r
- UDR0;\r
- } \r
- else if(bootuart == 2) {\r
- while(!(UCSR1A & _BV(RXC1)));\r
- UDR1;\r
- }\r
-#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega644P__)\r
- getch();\r
-#else\r
- /* m8,16,32,169,8515,8535,163 */\r
- /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ \r
- //while(!(UCSRA & _BV(RXC)));\r
- //UDR;\r
- getch(); // need to handle time out\r
-#endif \r
- }\r
-}\r
-\r
-\r
-void byte_response(uint8_t val)\r
-{\r
- if (getch() == ' ') {\r
- putch(0x14);\r
- putch(val);\r
- putch(0x10);\r
- } else {\r
- if (++error_count == MAX_ERROR_COUNT)\r
- app_start();\r
- }\r
-}\r
-\r
-\r
-void nothing_response(void)\r
-{\r
- if (getch() == ' ') {\r
- putch(0x14);\r
- putch(0x10);\r
- } else {\r
- if (++error_count == MAX_ERROR_COUNT)\r
- app_start();\r
- }\r
-}\r
-\r
-void flash_led(uint8_t count)\r
-{\r
- while (count--) {\r
- LED_PORT |= _BV(LED);\r
- _delay_ms(100);\r
- LED_PORT &= ~_BV(LED);\r
- _delay_ms(100);\r
- }\r
-}\r
-\r
-\r
-/* end of file ATmegaBOOT.c */\r
+++ /dev/null
-# Makefile for ATmegaBOOT
-# E.Lins, 18.7.2005
-#
-# 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 = -Os
-
-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:
-
-lilypad: TARGET = lilypad
-lilypad: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>1' '-DNUM_LED_FLASHES=3'
-lilypad: AVR_FREQ = 8000000L
-lilypad: $(PROGRAM)_lilypad.hex
-
-lilypad_isp: lilypad
-lilypad_isp: TARGET = lilypad
-lilypad_isp: HFUSE = DD
-lilypad_isp: LFUSE = E2
-lilypad_isp: EFUSE = 00
-lilypad_isp: isp
-
-lilypad_resonator: TARGET = lilypad_resonator
-lilypad_resonator: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=3'
-lilypad_resonator: AVR_FREQ = 8000000L
-lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
-
-lilypad_resonator_isp: lilypad_resonator
-lilypad_resonator_isp: TARGET = lilypad_resonator
-lilypad_resonator_isp: HFUSE = DD
-lilypad_resonator_isp: LFUSE = C6
-lilypad_resonator_isp: EFUSE = 00
-lilypad_resonator_isp: isp
-
-pro8: TARGET = pro_8MHz
-pro8: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS'
-pro8: AVR_FREQ = 8000000L
-pro8: $(PROGRAM)_pro_8MHz.hex
-
-pro8_isp: pro8
-pro8_isp: TARGET = pro_8MHz
-pro8_isp: HFUSE = DD
-pro8_isp: LFUSE = C6
-pro8_isp: EFUSE = 00
-pro8_isp: isp
-
-pro16: TARGET = pro_16MHz
-pro16: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS'
-pro16: AVR_FREQ = 16000000L
-pro16: $(PROGRAM)_pro_16MHz.hex
-
-pro16_isp: pro16
-pro16_isp: TARGET = pro_16MHz
-pro16_isp: HFUSE = DD
-pro16_isp: LFUSE = C6
-pro16_isp: EFUSE = 00
-pro16_isp: isp
-
-pro20: TARGET = pro_20mhz
-pro20: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' '-DWATCHDOG_MODS'
-pro20: AVR_FREQ = 20000000L
-pro20: $(PROGRAM)_pro_20mhz.hex
-
-pro20_isp: pro20
-pro20_isp: TARGET = pro_20mhz
-pro20_isp: HFUSE = DD
-pro20_isp: LFUSE = C6
-pro20_isp: EFUSE = 00
-pro20_isp: isp
-
-diecimila: TARGET = diecimila
-diecimila: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1'
-diecimila: AVR_FREQ = 16000000L
-diecimila: $(PROGRAM)_diecimila.hex
-
-diecimila_isp: diecimila
-diecimila_isp: TARGET = diecimila
-diecimila_isp: HFUSE = DD
-diecimila_isp: LFUSE = FF
-diecimila_isp: EFUSE = 00
-diecimila_isp: isp
-
-ng: TARGET = ng
-ng: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>1' '-DNUM_LED_FLASHES=3'
-ng: AVR_FREQ = 16000000L
-ng: $(PROGRAM)_ng.hex
-
-ng_isp: ng
-ng_isp: TARGET = ng
-ng_isp: HFUSE = DD
-ng_isp: LFUSE = FF
-ng_isp: EFUSE = 00
-ng_isp: isp
-
-atmega644: TARGET = atmega644
-atmega644: MCU_TARGET = atmega644p
-atmega644: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DDOUBLE_SPEED -DBAUD_RATE=115200
-atmega644: AVR_FREQ = 12000000L
-atmega644: LDSECTION = --section-start=.text=0x7000
-atmega644: $(PROGRAM)_atmega644p.hex
-
-atmega644_isp: atmega644
-atmega644_isp: TARGET = atmega644
-atmega644_isp: MCU_TARGET = atmega644p
-atmega644_isp: HFUSE = D8
-atmega644_isp: LFUSE = FF
-atmega644_isp: EFUSE = FF
-atmega644_isp: isp
-
-atmega328: TARGET = atmega328
-atmega328: MCU_TARGET = atmega328p
-atmega328: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600
-atmega328: AVR_FREQ = 16000000L
-atmega328: LDSECTION = --section-start=.text=0x7800
-atmega328: $(PROGRAM)_atmega328.hex
-
-atmega328_isp: atmega328
-atmega328_isp: TARGET = atmega328
-atmega328_isp: MCU_TARGET = atmega328p
-atmega328_isp: HFUSE = DA
-atmega328_isp: LFUSE = FF
-atmega328_isp: EFUSE = 05
-atmega328_isp: isp
-
-atmega328_notp: TARGET = atmega328_notp
-atmega328_notp: MCU_TARGET = atmega328
-atmega328_notp: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600
-atmega328_notp: AVR_FREQ = 16000000L
-atmega328_notp: LDSECTION = --section-start=.text=0x7800
-atmega328_notp: $(PROGRAM)_atmega328_notp.hex
-
-atmega328_notp_isp: atmega328_notp
-atmega328_notp_isp: TARGET = atmega328
-atmega328_notp_isp: MCU_TARGET = atmega328
-atmega328_notp_isp: HFUSE = DA
-atmega328_notp_isp: LFUSE = FF
-atmega328_notp_isp: EFUSE = 05
-atmega328_notp_isp: isp
-
-atmega328_pro8: TARGET = atmega328_pro_8MHz
-atmega328_pro8: MCU_TARGET = atmega328p
-atmega328_pro8: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -DDOUBLE_SPEED
-atmega328_pro8: AVR_FREQ = 8000000L
-atmega328_pro8: LDSECTION = --section-start=.text=0x7800
-atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
-
-atmega328_pro8_isp: atmega328_pro8
-atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
-atmega328_pro8_isp: MCU_TARGET = atmega328p
-atmega328_pro8_isp: HFUSE = DA
-atmega328_pro8_isp: LFUSE = FF
-atmega328_pro8_isp: EFUSE = 05
-atmega328_pro8_isp: isp
-
-mega: TARGET = atmega1280
-mega: MCU_TARGET = atmega1280
-mega: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=0' -DBAUD_RATE=57600
-mega: AVR_FREQ = 16000000L
-mega: LDSECTION = --section-start=.text=0x1F000
-mega: $(PROGRAM)_atmega1280.hex
-
-mega_isp: mega
-mega_isp: TARGET = atmega1280
-mega_isp: MCU_TARGET = atmega1280
-mega_isp: HFUSE = DA
-mega_isp: LFUSE = FF
-mega_isp: EFUSE = F5
-mega_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 $< $@
-