Version 0.74

This commit is contained in:
Olaf Rempel 2006-05-01 19:19:59 +02:00
parent f2c227f428
commit 722e6d5d68
7 changed files with 575 additions and 621 deletions

View File

@ -1,93 +0,0 @@
:107800000C942A3C0C94453C0C94453C0C94453C0F
:107810000C94453C0C94453C0C94453C0C94453CE4
:107820000C94453C0C94453C0C94453C0C94453CD4
:107830000C94453C0C94453C0C94453C0C94453CC4
:107840000C94453C0C94453C0C94453C0C94453CB4
:107850000C94453C11241FBECFE5D8E0DEBFCDBF60
:1078600010E0A0E6B0E0EEEAFDE702C005900D9260
:10787000A036B107D9F710E0A0E6B0E001C01D9234
:10788000A73EB107E1F70C94803D0C94003C81E4E5
:107890000E94A73E86E50E94A73E82E50E94A73E81
:1078A00082E40E94A73E8FE40E94A73E8FE40E94DC
:1078B000A73E84E50E94A73E0895BF92CF92DF9233
:1078C000EF92FF920F931F93CF93DF938C01B62E0D
:1078D00020E030E0E901CE59DF4F79010894E11C46
:1078E000F11C2017310718F40E94BC3E01C08FEF35
:1078F000888397012038310568F320E030E0C0909C
:10790000E200D090E300E090E400F090E5008CB35A
:10791000992796958795AC014170507080FDF7CFFF
:107920008091E600833709F08EC086E4B81609F02E
:1079300048C041E0C2E6D0E08991282F33278991E1
:107940009927982F8827282B392B07B600FCFDCFC5
:10795000E199FECF8091E2009091E3000901FC01E2
:1079600040935700E89511248091E2009091E30044
:10797000A091E400B091E5000296A11DB11D809395
:10798000E2009093E300A093E400B093E50002507E
:10799000104091F607B600FCFDCFE199FECF85E0DF
:1079A000F60180935700E89507B600FCFDCF07B6B7
:1079B00000FCFDCFE199FECF81E180935700E8956F
:1079C0003FC085E4B816E1F58091E2009091E300B4
:1079D000A091E400B091E500B695A795979587959D
:1079E0008093E2009093E300A093E400B093E5005D
:1079F000F901EF59FF4F8091E2008EBB8091E200C8
:107A00009091E300A091E400B091E500292F3A2F76
:107A10004B2F55272FBB0196A11DB11D8093E2006E
:107A20009093E300A093E400B093E5003196808149
:107A30008DBBE29AE19AE199FECF01501040D9F650
:107A40008DE090E001C0CA01DF91CF911F910F91AD
:107A5000FF90EF90DF90CF90BF9008950F931F930A
:107A6000CF93DF93EC01E199FECF653411F580915E
:107A7000E2008EBB8091E2009091E300A091E400CF
:107A8000B091E500292F3A2F4B2F55272FBB019698
:107A9000A11DB11D8093E2009093E300A093E40048
:107AA000B093E500E09A8DB30E94A73E2197F9F6C6
:107AB00022C0E091E200F091E30005911491802F43
:107AC0000E94A73E812F99270E94A73E8091E20045
:107AD0009091E300A091E400B091E5000296A11D11
:107AE000B11D8093E2009093E300A093E400B09373
:107AF000E5002297F1F6DF91CF911F910F91089544
:107B0000CFE5D8E0DEBFCDBFF89401E005BF82E04D
:107B100085BF60E08BE090E00E949D3EA098A89A0F
:107B2000989B08C0A89805BF15BEE0916000F09131
:107B3000610009950E94BC3E682F813611F489E5E9
:107B4000F9C0813439F50E94BC3E9927AA27BB278A
:107B50008093E2009093E300A093E400B093E500EB
:107B6000EE24F82E092F1A2F0E94BC3E9927AA272F
:107B7000BB27E82AF92A0A2B1B2BEE0CFF1C001F3F
:107B8000111FE092E200F092E3000093E4001093F2
:107B9000E50072C0823641F489E50E94A73E80E08C
:107BA0000E94A73E80E8C6C0823489F40E94BC3E91
:107BB0009927182F00270E94BC3E9927082B192BC4
:107BC0000E94BC3E682FC8010E945D3CB3C087364E
:107BD00089F40E94BC3E9927182F00270E94BC3EC2
:107BE0009927082B192B0E94BC3E682FC8010E94C0
:107BF0002E3DA0CF853609F041C08091E600833745
:107C000091F51092E2001092E3001092E4001092BD
:107C1000E50023E007B600FCFDCFE199FECF80919F
:107C2000E2009091E300FC0120935700E89507B62D
:107C300000FCFDCF8091E2009091E300A091E40070
:107C4000B091E50080589F4FAF4FBF4F8093E20047
:107C50009093E300A093E400B093E5008050984730
:107C6000A040B040B8F207B600FCFDCFE199FECFCE
:107C700081E180935700E8958DE05CC0853451F434
:107C800088E190E028E00FB6F894A89581BD0FBE7A
:107C900021BDF2CF803581F38C3471F3803711F43C
:107CA00083E548C0863421F469E080E090E005C0B7
:107CB000823731F469E081E090E00E94D03E3AC022
:107CC0008E3421F469E083E090E0F7CF813521F430
:107CD00069E082E090E0F1CF843729F483E70E94E5
:107CE000A73E80E027C08857823018F40E94BC3E2F
:107CF000C3CF643529F40E94BC3E8093E600BCCF1C
:107D0000633519F40E94473C15CF663529F480E3AA
:107D10000E94A73E87E30EC0633741F482E00E94D1
:107D2000A73E85E90E94A73E8EE104C06B3109F4AD
:107D300001CF8FE30E94A73EFDCE9C01832F9927A0
:107D400080BD29B988E18AB986E880BD089520E020
:107D500030E08CB90FB607FE0BC05E990BC02F5FE9
:107D60003F4F5E9907C087E220313807C4F302C055
:107D70005E9BFECF5E9A089580E090E00FB607FE0E
:107D80000AC05F990AC001965F9907C027E2803157
:107D90009207CCF302C05F9BFECF8CB19927089568
:0E7DA000FC0160935700C895802D9927089527
:040000030000780081
:00000001FF

View File

@ -133,7 +133,35 @@
#define sig_byte2 0x97
#define sig_byte1 0x02
#define devtype 0x44 // Mega128 device code
#define devtype 0x44 //
// #define PAGESIZE 128 // Size in Bytes
#ifdef _B512
#define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE
#endif
#ifdef _B1024
#define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE
#endif
#ifdef _B2048
#define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE
#endif
#ifdef _B4096
#define APP_PAGES ((2*65536UL / SPM_PAGESIZE)- (2*4096 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE
#endif
#elif defined(__AVR_AT90CAN128__)
#define sig_byte3 0x1E
#define sig_byte2 0x97
#define sig_byte1 0x81
#define devtype 0x43 /* Dummy device code for now, must be same as
used in avrdude.conf */
// #define PAGESIZE 128 // Size in Bytes

962
main.c
View File

@ -1,497 +1,467 @@
/*****************************************************************************
*
* AVRPROG compatible boot-loader
* Version : 0.7 (Feb. 2005)
* Compiler : avr-gcc 3.4.1 / avr-libc 1.0.2
* size : depends on features and startup ( minmal features < 512 words)
* by : Martin Thomas, Kaiserslautern, Germany
* eversmith@heizung-thomas.de
*
* License : Copyright (c) 2005 Martin Thomas
* Free to use. You have to mention the copyright
* owners in source-code and documentation of derived
* work. No warranty.
*
* Tested with ATmega8, ATmega16, ATmega32, ATmega128
*
* - based on the Butterfly Bootloader-Code
* Copyright (C) 1996-1998 Atmel Corporation
* Author(s) : BBrandal, PKastnes, ARodland, LHM
* The orignal code has been made available by ATMEL together with the
* Butterfly application code. Since ATMEL.NO had no problem with
* the application gcc-port they hopefully will not have any concerns about
* publishing this port. A lot of things have been change but the ATMEL
* "skeleton" is still in this code. Make sure to keep the copyright notice
* in derived work to avoid trouble.
*
* - based on boot.h from the avr-libc (c) Eric Weddington
*
****************************************************************************
*
* The boot interrupt vector is included (this bootloader is completly in
* ".text" section). If you need this space for further functions you have to
* add a separate section for the bootloader-functions and add an attribute
* for this section to _all_ function prototypes of functions in the loader.
* With this the interrupt vector will be placed at .0000 and the bootloader
* code (without interrupt vector) at the adress you define in the linker
* options for the newly created section. See the avr-libc FAQ, the avr-
* libc's avr/boot.h documentation and the makefile for further details.
*
* See the makefile for information how to adopt the linker-settings to
* the selected Boot Size (_Bxxx below)
*
* With BOOT_SIMPLE this bootloader has 0x3DE bytes size and should fit
* into a 512word bootloader-section.
*
* Set AVR clock-frequency and the baudrate below, set MCU-type in
* makefile.
*
****************************************************************************/
/*
Does not work reliably so far:
- lock bits set
*/
// programmers-notepad tabsize 4
#define VERSION_HIGH '0'
#define VERSION_LOW '7'
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/boot.h>
#include <avr/pgmspace.h>
// function not found in boot.h to read lock/fuses
#include "lowlevel.h"
/* Pin "BLPNUM" on port "BLPORT" in this port has to grounded
(active low) to start the bootloader */
#define BLPORT PORTC
#define BLDDR DDRC
#define BLPIN PINC
#define BLPNUM PINC0
/*
Select startup-mode
* SIMPLE-Mode - Jump to bootloader main BL-loop if key is
pressed (Pin grounded) "during" reset or jump to the
application if the pin is not grounded (=pulled up by
internal pull-up-resistor)
* POWERSAVE-Mode - Startup is separated in two loops
which makes power-saving a little easier if no firmware
is on the chip. Needs more memory
* BOOTICE-Mode - to flash the JTAGICE upgrade.ebn file.
No startup-sequence in this mode. Jump directly to the
parser-loop on reset
XTAL in BOOTICEMODE must be 7372800 Hz to be compatible
with the org. JTAGICE-Firmware */
#define START_SIMPLE
//#define START_POWERSAVE
//#define START_BOOTICE
#ifndef START_BOOTICE
#define XTAL 3686400
// #define XTAL 8000000UL
#else
#warning "BOOTICE mode - External Crystal/Oszillator must be 7,3728 MHz"
#define XTAL 7372800
#endif
// UART handling - some definitions from P. Fleury's Library - thanks
#define BAUDRATE 19200
#include "uart.h"
/* enable/disable readout of fuse and lock-bits
(will not work for Mega169 since not supported by AVRPROG 1.37 */
#define ENABLEREADFUSELOCK
/* enable/disable write of lock-bits
WARNING: lock-bits can not be reseted by bootloader (as far as I know)
Only protection no unprotection, "chip erase" from bootloader only
clears the flash but does no real "chip erase" (this is not possible
with a bootloader as far as I know)
Keep this undefined!
*/
// #define WRITELOCKBITS
/* Select Boot Size (select one, comment out the others) */
// NO! #define _B128
// NO! #define _B256
// MAYBE: #define _B512
#define _B1024
//#define _B2048
#include "chipdef.h"
#define UART_RX_BUFFER_SIZE SPM_PAGESIZE
unsigned char gBuffer[UART_RX_BUFFER_SIZE];
#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
#define my_eeprom_busy_wait() do{}while(!eeprom_is_ready())
unsigned char BufferLoad(unsigned int , unsigned char ) ;
void BlockRead(unsigned int , unsigned char ) ;
uint32_t address;
unsigned char device;
void send_boot(void)
{
sendchar('A');
sendchar('V');
sendchar('R');
sendchar('B');
sendchar('O');
sendchar('O');
sendchar('T');
}
void (*jump_to_app)(void) = 0x0000;
int main(void)
{
unsigned tempi;
char val;
#ifdef START_POWERSAVE
char OK = 1;
#endif
cli();
MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL); //move interruptvectors to the Boot sector
USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // single speed
// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed
#if defined(START_POWERSAVE)
/*
This is an adoption of the Butterfly Bootloader startup-sequence.
It may look a little strange but separating the login-loop from
the main parser-loop gives a lot a possibilities (timeout, sleep-modes
etc.).
*/
BLDDR &= ~(1<<BLPNUM); // set as Input
BLPORT |= (1<<BLPNUM); // Enable pullup
for(;OK;)
{
if((BLPIN & (1<<BLPNUM)))
{
// jump to main app if pin is not grounded
BLPORT &= ~(1<<BLPNUM); // set to default
MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL); // move interruptvectors to the Application sector
jump_to_app(); // Jump to application sector
}
else
{
val = recchar();
if( val == 0x1B ) /* ESC */
{ // AVRPROG connection
while (val != 'S') // Wait for signon
{
val = recchar();
}
send_boot(); // Report signon
OK = 0;
}
else
sendchar('?');
}
// Power-Save code here
}
#elif defined(START_SIMPLE)
BLDDR &= ~(1<<BLPNUM); // set as Input
BLPORT |= (1<<BLPNUM); // Enable pullup
if((BLPIN & (1<<BLPNUM)))
{
// jump to main app if pin is not grounded
BLPORT &= ~(1<<BLPNUM); // set to default
MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
jump_to_app(); // Jump to application sector
}
#elif defined(START_BOOTICE)
#warning "BOOTICE mode - no startup-condition"
#else
#error "Select START_ condition for bootloader in main.c"
#endif
for(;;)
{
val=recchar();
if(val=='a') //Autoincrement?
{
sendchar('Y'); //Autoincrement is quicker
}
else if(val=='A') //write address
{
address=recchar(); //read address 8 MSB
address=(address<<8)|recchar();
address=address<<1; // !! convert from word address to byte address
sendchar('\r');
}
else if(val=='b')
{ // Buffer load support
sendchar('Y'); // Report buffer load supported
sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF);
// Report buffer size in bytes
sendchar(UART_RX_BUFFER_SIZE & 0xFF);
}
else if(val=='B') // Start buffer load
{
tempi = recchar() << 8; // Load high byte of buffersize
tempi |= recchar(); // Load low byte of buffersize
val = recchar(); // Load memory type ('E' or 'F')
sendchar (BufferLoad(tempi,val));
// Start downloading of buffer
}
else if(val == 'g') // Block read
{
tempi = (recchar() << 8) | recchar();
val = recchar(); // Get memtype
BlockRead(tempi,val); // Perform the block read
}
else if(val=='e') //Chip erase
{
if (device == devtype)
{
// erase only main section (bootloader protection)
address = 0;
while ( APP_END > address )
{
/*****************************************************************************
*
* AVRPROG compatible boot-loader
* Version : 0.7 (Feb. 2005)
* Compiler : avr-gcc 3.4.1 / avr-libc 1.0.2
* size : depends on features and startup ( minmal features < 512 words)
* by : Martin Thomas, Kaiserslautern, Germany
* eversmith@heizung-thomas.de
*
* License : Copyright (c) 2005 Martin Thomas
* Free to use. You have to mention the copyright
* owners in source-code and documentation of derived
* work. No warranty.
*
* Tested with ATmega8, ATmega16, ATmega32, ATmega128
*
* - based on the Butterfly Bootloader-Code
* Copyright (C) 1996-1998 Atmel Corporation
* Author(s) : BBrandal, PKastnes, ARodland, LHM
* The orignal code has been made available by ATMEL together with the
* Butterfly application code. Since ATMEL.NO had no problem with
* the application gcc-port they hopefully will not have any concerns about
* publishing this port. A lot of things have been change but the ATMEL
* "skeleton" is still in this code. Make sure to keep the copyright notice
* in derived work to avoid trouble.
*
* - based on boot.h from the avr-libc (c) Eric Weddington
*
****************************************************************************
*
* The boot interrupt vector is included (this bootloader is completly in
* ".text" section). If you need this space for further functions you have to
* add a separate section for the bootloader-functions and add an attribute
* for this section to _all_ function prototypes of functions in the loader.
* With this the interrupt vector will be placed at .0000 and the bootloader
* code (without interrupt vector) at the adress you define in the linker
* options for the newly created section. See the avr-libc FAQ, the avr-
* libc's avr/boot.h documentation and the makefile for further details.
*
* See the makefile for information how to adopt the linker-settings to
* the selected Boot Size (_Bxxx below)
*
* With BOOT_SIMPLE this bootloader has 0x3DE bytes size and should fit
* into a 512word bootloader-section.
*
* Set AVR clock-frequency and the baudrate below, set MCU-type in
* makefile.
*
****************************************************************************/
/*
Does not work reliably so far:
- lock bits set
*/
// programmers-notepad tabsize 4
#define VERSION_HIGH '0'
#define VERSION_LOW '7'
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/boot.h>
#include <avr/pgmspace.h>
// function not found in boot.h to read lock/fuses
#include "lowlevel.h"
#ifndef XTAL
#warning "Set XTAL in Makefile"
#endif
#ifdef START_BOOTICE
#warning "Using START_BOOTICE"
#if XTAL == 7372800
#else
#warning "BOOTICE mode - External Crystal/Oszillator must be 7,3728 MHz"
#undef XTAL
#define XTAL 7372800
#endif
#endif
// UART handling - some definitions from P. Fleury's Library - thanks
#include "uart.h"
/* enable/disable readout of fuse and lock-bits
(will not work for Mega169 since not supported by AVRPROG 1.37 */
#define ENABLEREADFUSELOCK
/* enable/disable write of lock-bits
WARNING: lock-bits can not be reseted by bootloader (as far as I know)
Only protection no unprotection, "chip erase" from bootloader only
clears the flash but does no real "chip erase" (this is not possible
with a bootloader as far as I know)
Keep this undefined!
*/
// #define WRITELOCKBITS
#include "chipdef.h"
#define UART_RX_BUFFER_SIZE SPM_PAGESIZE
unsigned char gBuffer[UART_RX_BUFFER_SIZE];
#define eeprom_is_ready() bit_is_clear(EECR, EEWE)
#define my_eeprom_busy_wait() do{}while(!eeprom_is_ready())
unsigned char BufferLoad(unsigned int , unsigned char ) ;
void BlockRead(unsigned int , unsigned char ) ;
uint32_t address;
unsigned char device;
void send_boot(void)
{
sendchar('A');
sendchar('V');
sendchar('R');
sendchar('B');
sendchar('O');
sendchar('O');
sendchar('T');
}
void (*jump_to_app)(void) = 0x0000;
int main(void)
{
unsigned tempi;
char val;
#ifdef START_POWERSAVE
char OK = 1;
#endif
cli();
MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL); //move interruptvectors to the Boot sector
BLDDR &= ~(1<<BLPNUM); // set as Input
BLPORT |= (1<<BLPNUM); // Enable pullup
USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // single speed
// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed
#ifdef START_POWERSAVE
/*
This is an adoption of the Butterfly Bootloader startup-sequence.
It may look a little strange but separating the login-loop from
the main parser-loop gives a lot a possibilities (timeout, sleep-modes
etc.).
*/
for(;OK;)
{
if((BLPIN & (1<<BLPNUM)))
{
// jump to main app if pin is not grounded
BLPORT &= ~(1<<BLPNUM); // set to default
MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL); // move interruptvectors to the Application sector
jump_to_app(); // Jump to application sector
}
else
{
val = recchar();
if( val == 0x1B ) /* ESC */
{ // AVRPROG connection
while (val != 'S') // Wait for signon
{
val = recchar();
}
send_boot(); // Report signon
OK = 0;
}
else
sendchar('?');
}
// Power-Save code here
}
#elif defined(START_SIMPLE)
if((BLPIN & (1<<BLPNUM)))
{
// jump to main app if pin is not grounded
BLPORT &= ~(1<<BLPNUM); // set to default
MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
jump_to_app(); // Jump to application sector
}
#elif defined(START_BOOTICE)
#warning "BOOTICE mode - no startup-condition"
#else
#error "Select START_ condition for bootloader in main.c"
#endif
for(;;)
{
val=recchar();
if(val=='a') //Autoincrement?
{
sendchar('Y'); //Autoincrement is quicker
}
else if(val=='A') //write address
{
address=recchar(); //read address 8 MSB
address=(address<<8)|recchar();
address=address<<1; // !! convert from word address to byte address
sendchar('\r');
}
else if(val=='b')
{ // Buffer load support
sendchar('Y'); // Report buffer load supported
sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF);
// Report buffer size in bytes
sendchar(UART_RX_BUFFER_SIZE & 0xFF);
}
else if(val=='B') // Start buffer load
{
tempi = recchar() << 8; // Load high byte of buffersize
tempi |= recchar(); // Load low byte of buffersize
val = recchar(); // Load memory type ('E' or 'F')
sendchar (BufferLoad(tempi,val));
// Start downloading of buffer
}
else if(val == 'g') // Block read
{
tempi = (recchar() << 8) | recchar();
val = recchar(); // Get memtype
BlockRead(tempi,val); // Perform the block read
}
else if(val=='e') //Chip erase
{
if (device == devtype)
{
// erase only main section (bootloader protection)
address = 0;
while ( APP_END > address )
{
boot_page_erase(address); // Perform page erase
boot_spm_busy_wait(); // Wait until the memory is erased.
address += SPM_PAGESIZE;
}
}
boot_rww_enable();
sendchar('\r');
}
else if(val=='E') //Exit upgrade
{
wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset
sendchar('\r');
}
#ifdef WRITELOCKBITS
#warning "Extension 'WriteLockBits' enabled"
// TODO: does not work reliably
else if(val=='l') // write lockbits
{
if (device == devtype)
{
// write_lock_bits(recchar());
boot_lock_bits_set(recchar()); // boot.h takes care of mask
boot_spm_busy_wait();
}
sendchar('\r');
}
#endif
else if(val=='P') // Enter programming mode
{
sendchar('\r');
}
else if(val=='L') // Leave programming mode
{
sendchar('\r');
}
else if (val=='p') // return programmer type
{
sendchar('S'); // always serial programmer
}
#ifdef ENABLEREADFUSELOCK
#warning "Extension 'ReadFuseLock' enabled"
else if(val=='F') // read "low" fuse bits
{
sendchar( read_fuse_lock(0x0000, _BV(BLBSET)|_BV(SPMEN)) );
}
else if(val=='r') // read lock bits
{
sendchar( read_fuse_lock(0x0001, _BV(BLBSET)|_BV(SPMEN)) );
}
else if(val=='N') // read high fuse bits
{
sendchar( read_fuse_lock(0x0003,_BV(BLBSET)|_BV(SPMEN)) );
}
else if(val=='Q') // read extended fuse bits
{
sendchar( read_fuse_lock(0x0002,_BV(BLBSET)|_BV(SPMEN)) );
}
#endif
// end of ENABLEREADFUSELOCK section
else if(val=='t') // Return device type
{
sendchar(devtype);
sendchar(0);
}
else if ((val=='x')||(val=='y')) // clear and set LED ignored
{
recchar();
sendchar('\r');
}
else if (val=='T') // set device
{
device = recchar();
sendchar('\r');
}
else if (val=='S') // Return software identifier
{
send_boot();
}
else if (val=='V') // Return Software Version
{
sendchar(VERSION_HIGH);
sendchar(VERSION_LOW);
}
else if (val=='s') // Return Signature Byte
{
sendchar(sig_byte1);
sendchar(sig_byte2);
sendchar(sig_byte3);
}
else if(val != 0x1b) /* ESC */
{
sendchar('?');
}
} // end of "parser" for-loop
return 0;
}
unsigned char BufferLoad(unsigned int size, unsigned char mem)
{
unsigned int data, cnt;
uint32_t tempaddress;
for (cnt=0; cnt<UART_RX_BUFFER_SIZE; cnt++) {
if (cnt<size) gBuffer[cnt]=recchar();
else gBuffer[cnt]=0xFF;
}
cnt=0;
tempaddress = address; // Store address in page
my_eeprom_busy_wait();
if (device == devtype)
{
if (mem == 'F') // Flash
{
do {
data=gBuffer[cnt++];
data|=(gBuffer[cnt++]<<8);
boot_page_fill(address,data);
//call asm routine.
address=address+2; // Select next word in memory
size -= 2; // Reduce number of bytes to write by two
} while(size); // Loop until all bytes written
/* commented out since not compatible with mega8 -
secondary benefit: saves memory
tempaddress &= 0xFF80; // Ensure the address points to the first byte in the page
*/
boot_page_write(tempaddress);
boot_spm_busy_wait();
boot_rww_enable(); //Re-enable the RWW section
/* commented out since not compatible with mega8
if (address != (address & 0xFF80))
{ // Ensure that the address points to the beginning of the next page
address &= 0xFF80;
address += SPM_PAGESIZE;
}
*/
} // End FLASH
if (mem == 'E') // Start EEPROM
{
address>>=1;
do {
EEARL = address; // Setup EEPROM address
EEARH = (address >> 8);
address++; // Select next byte
EEDR=gBuffer[cnt++];
EECR |= (1<<EEMWE); // Write data into EEPROM
EECR |= (1<<EEWE);
while (EECR & (1<<EEWE)); // Wait for EEPROM write to finish
size--; // Decreas number of bytes to write
} while(size); // Loop until all bytes written
}
return '\r'; // Report programming OK
}
return 0; // Report programming failed
}
void BlockRead(unsigned int size, unsigned char mem)
{
unsigned int data;
my_eeprom_busy_wait();
if (mem == 'E') // Read EEPROM
{
// address>>=1; // not needed here - hmm, somehow inconsistant TODO
do {
EEARL = address; // Setup EEPROM address
EEARH = (address >> 8);
address++; // Select next EEPROM byte
EECR |= (1<<EERE); // Read EEPROM
sendchar(EEDR); // Transmit EEPROM data to PC
size--; // Decrease number of bytes to read
} while (size); // Repeat until all block has been read
}
else // Read Flash
{
do {
#if defined(RAMPZ)
data = pgm_read_word_far(address);
#else
data = pgm_read_word_near((uint16_t)address);
#endif
sendchar((unsigned char)data); //send LSB
sendchar((unsigned char)(data >> 8)); //send MSB
address += 2; // Select next word in memory
size -= 2; // Subtract two bytes from number of bytes to read
} while (size); // Repeat until all block has been read
}
}
boot_spm_busy_wait(); // Wait until the memory is erased.
address += SPM_PAGESIZE;
}
}
boot_rww_enable();
sendchar('\r');
}
else if(val=='E') //Exit upgrade
{
wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset
sendchar('\r');
}
#ifdef WRITELOCKBITS
#warning "Extension 'WriteLockBits' enabled"
// TODO: does not work reliably
else if(val=='l') // write lockbits
{
if (device == devtype)
{
// write_lock_bits(recchar());
boot_lock_bits_set(recchar()); // boot.h takes care of mask
boot_spm_busy_wait();
}
sendchar('\r');
}
#endif
else if(val=='P') // Enter programming mode
{
sendchar('\r');
}
else if(val=='L') // Leave programming mode
{
sendchar('\r');
}
else if (val=='p') // return programmer type
{
sendchar('S'); // always serial programmer
}
#ifdef ENABLEREADFUSELOCK
#warning "Extension 'ReadFuseLock' enabled"
else if(val=='F') // read "low" fuse bits
{
sendchar( read_fuse_lock(0x0000, _BV(BLBSET)|_BV(SPMEN)) );
}
else if(val=='r') // read lock bits
{
sendchar( read_fuse_lock(0x0001, _BV(BLBSET)|_BV(SPMEN)) );
}
else if(val=='N') // read high fuse bits
{
sendchar( read_fuse_lock(0x0003,_BV(BLBSET)|_BV(SPMEN)) );
}
else if(val=='Q') // read extended fuse bits
{
sendchar( read_fuse_lock(0x0002,_BV(BLBSET)|_BV(SPMEN)) );
}
#endif
// end of ENABLEREADFUSELOCK section
else if(val=='t') // Return device type
{
sendchar(devtype);
sendchar(0);
}
else if ((val=='x')||(val=='y')) // clear and set LED ignored
{
recchar();
sendchar('\r');
}
else if (val=='T') // set device
{
device = recchar();
sendchar('\r');
}
else if (val=='S') // Return software identifier
{
send_boot();
}
else if (val=='V') // Return Software Version
{
sendchar(VERSION_HIGH);
sendchar(VERSION_LOW);
}
else if (val=='s') // Return Signature Byte
{
sendchar(sig_byte1);
sendchar(sig_byte2);
sendchar(sig_byte3);
}
else if(val != 0x1b) /* ESC */
{
sendchar('?');
}
} // end of "parser" for-loop
return 0;
}
unsigned char BufferLoad(unsigned int size, unsigned char mem)
{
unsigned int data, cnt;
uint32_t tempaddress;
for (cnt=0; cnt<UART_RX_BUFFER_SIZE; cnt++) {
if (cnt<size) gBuffer[cnt]=recchar();
else gBuffer[cnt]=0xFF;
}
cnt=0;
tempaddress = address; // Store address in page
my_eeprom_busy_wait();
if (device == devtype)
{
if (mem == 'F') // Flash
{
do {
data=gBuffer[cnt++];
data|=(gBuffer[cnt++]<<8);
boot_page_fill(address,data);
//call asm routine.
address=address+2; // Select next word in memory
size -= 2; // Reduce number of bytes to write by two
} while(size); // Loop until all bytes written
/* commented out since not compatible with mega8 -
secondary benefit: saves memory
tempaddress &= 0xFF80; // Ensure the address points to the first byte in the page
*/
boot_page_write(tempaddress);
boot_spm_busy_wait();
boot_rww_enable(); //Re-enable the RWW section
/* commented out since not compatible with mega8
if (address != (address & 0xFF80))
{ // Ensure that the address points to the beginning of the next page
address &= 0xFF80;
address += SPM_PAGESIZE;
}
*/
} // End FLASH
if (mem == 'E') // Start EEPROM
{
address>>=1;
do {
EEARL = address; // Setup EEPROM address
EEARH = (address >> 8);
address++; // Select next byte
EEDR=gBuffer[cnt++];
EECR |= (1<<EEMWE); // Write data into EEPROM
EECR |= (1<<EEWE);
while (EECR & (1<<EEWE)); // Wait for EEPROM write to finish
size--; // Decreas number of bytes to write
} while(size); // Loop until all bytes written
}
return '\r'; // Report programming OK
}
return 0; // Report programming failed
}
void BlockRead(unsigned int size, unsigned char mem)
{
unsigned int data;
my_eeprom_busy_wait();
if (mem == 'E') // Read EEPROM
{
// address>>=1; // not needed here - hmm, somehow inconsistant TODO
do {
EEARL = address; // Setup EEPROM address
EEARH = (address >> 8);
address++; // Select next EEPROM byte
EECR |= (1<<EERE); // Read EEPROM
sendchar(EEDR); // Transmit EEPROM data to PC
size--; // Decrease number of bytes to read
} while (size); // Repeat until all block has been read
}
else // Read Flash
{
do {
#if defined(RAMPZ)
data = pgm_read_word_far(address);
#else
data = pgm_read_word_near((uint16_t)address);
#endif
sendchar((unsigned char)data); //send LSB
sendchar((unsigned char)(data >> 8)); //send MSB
address += 2; // Select next word in memory
size -= 2; // Subtract two bytes from number of bytes to read
} while (size); // Repeat until all block has been read
}
}

View File

@ -31,12 +31,49 @@
# To rebuild project do "make clean" then "make all".
#
# user defined values
# MCU name
## MCU = atmega16
## MCU = atmega8
MCU = atmega32
## MCU = atmega128
## MCU = atmega32
MCU = at90can128
XTAL=16000000
BAUDRATE=115200
#Pin "STARTPIN" on port "STARTPORT" in this port has to grounded
# (active low) to start the bootloader
BLPORT = PORTB
BLDDR = DDRB
BLPIN = PINB
BLPNUM = PINB0
# Select startup-mode
# * SIMPLE-Mode - Jump to bootloader main BL-loop if key is
# pressed (Pin grounded) "during" reset or jump to the
# application if the pin is not grounded (=pulled up by
# internal pull-up-resistor)
# * POWERSAVE-Mode - Startup is separated in two loops
# which makes power-saving a little easier if no firmware
# is on the chip. Needs more memory
# * BOOTICE-Mode - to flash the JTAGICE upgrade.ebn file.
# No startup-sequence in this mode. Jump directly to the
# parser-loop on reset
# XTAL in BOOTICEMODE must be 7372800 Hz to be compatible
# with the org. JTAGICE-Firmware */
STARTMODE=START_SIMPLE
##STARTMODE=START_POWERSAVE
##STARTMODE=START_BOOTICE
#/* Select Boot Size in Words (select one, comment out the others) */
## NO! BOOTSIZE=_B128
## NO! BOOTSIZE=_B256
## MAYBE: BOOTSIZE=_B512
BOOTSIZE=_B1024
##BOOTSIZE=_B2048
################## BOOTLOADER ######################
# mt: Boot loader support. So far not done with a separate section
@ -46,20 +83,33 @@ MCU = atmega32
# (see LDFLAGS further down)
# 0x1C00*2=0x3800 for ATmega16 1024 words Boot Size
## MT_BOOTLOADER_ADDRESS = 3800
ifeq ($(MCU), atmega16)
MT_BOOTLOADER_ADDRESS = 3800
endif
# 0x0C00*2=0x1800 for ATmega8 1024 words Boot Size
## MT_BOOTLOADER_ADDRESS = 1800
ifeq ($(MCU), atmega8)
MT_BOOTLOADER_ADDRESS = 1800
endif
# 0x3C00*2=0x7800 for ATmega32 1024 words Boot Size
MT_BOOTLOADER_ADDRESS = 7800
ifeq ($(MCU), atmega32)
MT_BOOTLOADER_ADDRESS = 7800
endif
# 0xFC00*2=0x1F800 for ATmega128 1024 words Boot Size
##MT_BOOTLOADER_ADDRESS = 1F800
ifeq ($(MCU), atmega128)
MT_BOOTLOADER_ADDRESS = 1F800
endif
# 0xFC00*2=0x1F800 for AT90Can128 1024 words Boot Size
ifeq ($(MCU), at90can128)
MT_BOOTLOADER_ADDRESS = 1f800
endif
# Output format. (can be srec, ihex, binary)
FORMAT = ihex
FORMAT = srec
# Target file name (without extension).
TARGET = main
@ -103,8 +153,11 @@ EXTRAINCDIRS =
CSTANDARD = -std=gnu99
# Place -D or -U options here
CDEFS =
CDEFS = -DBLPORT=$(BLPORT) -DBLDDR=$(BLDDR) -DBLPIN=$(BLPIN) -DBLPNUM=$(BLPNUM)
CDEFS += -D$(STARTMODE) -D$(BOOTSIZE) -DBAUDRATE=$(BAUDRATE)
ifdef XTAL
CDEFS += -DXTAL=$(XTAL)
endif
# Place -I options here
CINCS =
@ -196,7 +249,8 @@ LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
AVRDUDE_PROGRAMMER = stk500v2
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com1 # programmer connected to serial device
#AVRDUDE_PORT = com1 # programmer connected to serial device
AVRDUDE_PORT = /dev/ttyS1 # programmer connected to serial device
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
@ -235,11 +289,11 @@ DIRLIB = $(DIRAVR)/avr/lib
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
NM = avr-nm
CC = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-gcc
OBJCOPY = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-objcopy
OBJDUMP = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-objdump
SIZE = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-size
NM = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp

View File

@ -12,6 +12,12 @@
======================================================
18. Aug. 2005 - Version 0.74
* AT90CAN128 support contributed by Uwe Bonnes
* Makefile modifications contributed by Uwe Bonnes
23. Feb. 2005 - Version 0.7
* (Version 0.6 has never been available on the web-page)
@ -98,31 +104,20 @@ not enabled (TODO).
ATmega16 has been tested, ATmega169, ATmega8
and ATmega32 should be o.k. too.
- Change the boot(loader)-size in main.c, this
- Change the boot(loader)-size in Makefile, this
bootloader is larger than 512 words (1024 bytes),
so select at least _B1024!
- Change the XTAL in main.c to the clock-frequency
- Change the XTAL in Makefile to the clock-frequency
of your board (keep BAUDRATE at 19200). See
the datasheet for frequencies with minimum
error at 19200bps and select Crystal/Oscillator
to get minimum errors.
- Change the start-condition in main.c. Default
- Change the start-condition in Makefile. Default
is: enter bootloader if Pin A7 is connected to
GND during reset/startup
- Edit the value MT_BOOTLOADER_ADDRESS in the
makefile according to the selected bootloader
size. Keep in mind that this value has to be
given in bytes (not words) in the linker options.
i.e. ATMega16, boot-size 1024 words, see
datasheet and find "Boot Reset Adress" for
"Boot Size" 1024 words is 1C00. 1C00 is given
in words, so set MT_BOOTLOADER_ADDRESS to
3800 (=2*1C00)
- Please use at least avr-gcc 3.3.1/avr-libc 1.0
or WINAVR Sept. 2003 or later to compile and link
the bootloader.

2
uart.c
View File

@ -39,7 +39,7 @@
#define UART1_CONTROL2 UCSR1C
#define UART1_DATA UDR1
#define UART1_UDRIE UDRIE1
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
#elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) || defined(__AVR_AT90CAN128__)
/* ATMega with two USART */
#define ATMEGA_USART0
#define ATMEGA_USART1

2
uart.h
View File

@ -1,7 +1,7 @@
#ifndef UART_H
#define UART_H
#define UART_BAUD_SELECT(baudRate,xtalCpu) ((xtalCpu)/((baudRate)*16L)-1)
#define UART_BAUD_SELECT(baudRate,xtalCpu) (((xtalCpu)+(baudRate*8))/((baudRate)*16)-1)
#define UARTDOUBLE 1
#define UARTSINGLE 0