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_byte2 0x97
#define sig_byte1 0x02 #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 // #define PAGESIZE 128 // Size in Bytes

962
main.c
View File

@ -1,497 +1,467 @@
/***************************************************************************** /*****************************************************************************
* *
* AVRPROG compatible boot-loader * AVRPROG compatible boot-loader
* Version : 0.7 (Feb. 2005) * Version : 0.7 (Feb. 2005)
* Compiler : avr-gcc 3.4.1 / avr-libc 1.0.2 * Compiler : avr-gcc 3.4.1 / avr-libc 1.0.2
* size : depends on features and startup ( minmal features < 512 words) * size : depends on features and startup ( minmal features < 512 words)
* by : Martin Thomas, Kaiserslautern, Germany * by : Martin Thomas, Kaiserslautern, Germany
* eversmith@heizung-thomas.de * eversmith@heizung-thomas.de
* *
* License : Copyright (c) 2005 Martin Thomas * License : Copyright (c) 2005 Martin Thomas
* Free to use. You have to mention the copyright * Free to use. You have to mention the copyright
* owners in source-code and documentation of derived * owners in source-code and documentation of derived
* work. No warranty. * work. No warranty.
* *
* Tested with ATmega8, ATmega16, ATmega32, ATmega128 * Tested with ATmega8, ATmega16, ATmega32, ATmega128
* *
* - based on the Butterfly Bootloader-Code * - based on the Butterfly Bootloader-Code
* Copyright (C) 1996-1998 Atmel Corporation * Copyright (C) 1996-1998 Atmel Corporation
* Author(s) : BBrandal, PKastnes, ARodland, LHM * Author(s) : BBrandal, PKastnes, ARodland, LHM
* The orignal code has been made available by ATMEL together with the * The orignal code has been made available by ATMEL together with the
* Butterfly application code. Since ATMEL.NO had no problem with * Butterfly application code. Since ATMEL.NO had no problem with
* the application gcc-port they hopefully will not have any concerns about * 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 * 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 * "skeleton" is still in this code. Make sure to keep the copyright notice
* in derived work to avoid trouble. * in derived work to avoid trouble.
* *
* - based on boot.h from the avr-libc (c) Eric Weddington * - based on boot.h from the avr-libc (c) Eric Weddington
* *
**************************************************************************** ****************************************************************************
* *
* The boot interrupt vector is included (this bootloader is completly in * The boot interrupt vector is included (this bootloader is completly in
* ".text" section). If you need this space for further functions you have to * ".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 * add a separate section for the bootloader-functions and add an attribute
* for this section to _all_ function prototypes of functions in the loader. * 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 * 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 * 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- * 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. * libc's avr/boot.h documentation and the makefile for further details.
* *
* See the makefile for information how to adopt the linker-settings to * See the makefile for information how to adopt the linker-settings to
* the selected Boot Size (_Bxxx below) * the selected Boot Size (_Bxxx below)
* *
* With BOOT_SIMPLE this bootloader has 0x3DE bytes size and should fit * With BOOT_SIMPLE this bootloader has 0x3DE bytes size and should fit
* into a 512word bootloader-section. * into a 512word bootloader-section.
* *
* Set AVR clock-frequency and the baudrate below, set MCU-type in * Set AVR clock-frequency and the baudrate below, set MCU-type in
* makefile. * makefile.
* *
****************************************************************************/ ****************************************************************************/
/* /*
Does not work reliably so far: Does not work reliably so far:
- lock bits set - lock bits set
*/ */
// programmers-notepad tabsize 4 // programmers-notepad tabsize 4
#define VERSION_HIGH '0' #define VERSION_HIGH '0'
#define VERSION_LOW '7' #define VERSION_LOW '7'
#include <inttypes.h> #include <inttypes.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/wdt.h> #include <avr/wdt.h>
#include <avr/boot.h> #include <avr/boot.h>
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
// function not found in boot.h to read lock/fuses // function not found in boot.h to read lock/fuses
#include "lowlevel.h" #include "lowlevel.h"
/* Pin "BLPNUM" on port "BLPORT" in this port has to grounded #ifndef XTAL
(active low) to start the bootloader */ #warning "Set XTAL in Makefile"
#define BLPORT PORTC #endif
#define BLDDR DDRC
#define BLPIN PINC #ifdef START_BOOTICE
#define BLPNUM PINC0 #warning "Using START_BOOTICE"
#if XTAL == 7372800
/* #else
Select startup-mode #warning "BOOTICE mode - External Crystal/Oszillator must be 7,3728 MHz"
* SIMPLE-Mode - Jump to bootloader main BL-loop if key is #undef XTAL
pressed (Pin grounded) "during" reset or jump to the #define XTAL 7372800
application if the pin is not grounded (=pulled up by #endif
internal pull-up-resistor) #endif
* POWERSAVE-Mode - Startup is separated in two loops
which makes power-saving a little easier if no firmware // UART handling - some definitions from P. Fleury's Library - thanks
is on the chip. Needs more memory #include "uart.h"
* BOOTICE-Mode - to flash the JTAGICE upgrade.ebn file.
No startup-sequence in this mode. Jump directly to the /* enable/disable readout of fuse and lock-bits
parser-loop on reset (will not work for Mega169 since not supported by AVRPROG 1.37 */
XTAL in BOOTICEMODE must be 7372800 Hz to be compatible #define ENABLEREADFUSELOCK
with the org. JTAGICE-Firmware */
#define START_SIMPLE /* enable/disable write of lock-bits
//#define START_POWERSAVE WARNING: lock-bits can not be reseted by bootloader (as far as I know)
//#define START_BOOTICE Only protection no unprotection, "chip erase" from bootloader only
clears the flash but does no real "chip erase" (this is not possible
#ifndef START_BOOTICE with a bootloader as far as I know)
#define XTAL 3686400 Keep this undefined!
// #define XTAL 8000000UL */
#else // #define WRITELOCKBITS
#warning "BOOTICE mode - External Crystal/Oszillator must be 7,3728 MHz"
#define XTAL 7372800 #include "chipdef.h"
#endif
#define UART_RX_BUFFER_SIZE SPM_PAGESIZE
// UART handling - some definitions from P. Fleury's Library - thanks unsigned char gBuffer[UART_RX_BUFFER_SIZE];
#define BAUDRATE 19200
#include "uart.h" #define eeprom_is_ready() bit_is_clear(EECR, EEWE)
#define my_eeprom_busy_wait() do{}while(!eeprom_is_ready())
/* enable/disable readout of fuse and lock-bits
(will not work for Mega169 since not supported by AVRPROG 1.37 */ unsigned char BufferLoad(unsigned int , unsigned char ) ;
#define ENABLEREADFUSELOCK void BlockRead(unsigned int , unsigned char ) ;
/* enable/disable write of lock-bits uint32_t address;
WARNING: lock-bits can not be reseted by bootloader (as far as I know) unsigned char device;
Only protection no unprotection, "chip erase" from bootloader only
clears the flash but does no real "chip erase" (this is not possible void send_boot(void)
with a bootloader as far as I know) {
Keep this undefined! sendchar('A');
*/ sendchar('V');
// #define WRITELOCKBITS sendchar('R');
sendchar('B');
/* Select Boot Size (select one, comment out the others) */ sendchar('O');
// NO! #define _B128 sendchar('O');
// NO! #define _B256 sendchar('T');
// MAYBE: #define _B512 }
#define _B1024
//#define _B2048 void (*jump_to_app)(void) = 0x0000;
#include "chipdef.h" int main(void)
{
#define UART_RX_BUFFER_SIZE SPM_PAGESIZE unsigned tempi;
unsigned char gBuffer[UART_RX_BUFFER_SIZE]; char val;
#define eeprom_is_ready() bit_is_clear(EECR, EEWE) #ifdef START_POWERSAVE
#define my_eeprom_busy_wait() do{}while(!eeprom_is_ready()) char OK = 1;
#endif
unsigned char BufferLoad(unsigned int , unsigned char ) ;
void BlockRead(unsigned int , unsigned char ) ; cli();
uint32_t address; MCUCR = (1<<IVCE);
unsigned char device; MCUCR = (1<<IVSEL); //move interruptvectors to the Boot sector
void send_boot(void) BLDDR &= ~(1<<BLPNUM); // set as Input
{ BLPORT |= (1<<BLPNUM); // Enable pullup
sendchar('A');
sendchar('V'); USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // single speed
sendchar('R'); // USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed
sendchar('B');
sendchar('O'); #ifdef START_POWERSAVE
sendchar('O'); /*
sendchar('T'); 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
void (*jump_to_app)(void) = 0x0000; etc.).
*/
int main(void) for(;OK;)
{ {
unsigned tempi; if((BLPIN & (1<<BLPNUM)))
char val; {
// jump to main app if pin is not grounded
#ifdef START_POWERSAVE BLPORT &= ~(1<<BLPNUM); // set to default
char OK = 1; MCUCR = (1<<IVCE);
#endif MCUCR = (0<<IVSEL); // move interruptvectors to the Application sector
jump_to_app(); // Jump to application sector
cli(); }
else
MCUCR = (1<<IVCE); {
MCUCR = (1<<IVSEL); //move interruptvectors to the Boot sector val = recchar();
USART_Init(UART_BAUD_SELECT(BAUDRATE,XTAL),UARTSINGLE); // single speed if( val == 0x1B ) /* ESC */
// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed { // AVRPROG connection
while (val != 'S') // Wait for signon
#if defined(START_POWERSAVE) {
/* val = recchar();
This is an adoption of the Butterfly Bootloader startup-sequence. }
It may look a little strange but separating the login-loop from send_boot(); // Report signon
the main parser-loop gives a lot a possibilities (timeout, sleep-modes OK = 0;
etc.). }
*/ else
BLDDR &= ~(1<<BLPNUM); // set as Input sendchar('?');
BLPORT |= (1<<BLPNUM); // Enable pullup }
// Power-Save code here
for(;OK;) }
{
if((BLPIN & (1<<BLPNUM))) #elif defined(START_SIMPLE)
{ if((BLPIN & (1<<BLPNUM)))
// jump to main app if pin is not grounded {
BLPORT &= ~(1<<BLPNUM); // set to default // jump to main app if pin is not grounded
MCUCR = (1<<IVCE); BLPORT &= ~(1<<BLPNUM); // set to default
MCUCR = (0<<IVSEL); // move interruptvectors to the Application sector MCUCR = (1<<IVCE);
jump_to_app(); // Jump to application sector MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
} jump_to_app(); // Jump to application sector
else }
{
val = recchar(); #elif defined(START_BOOTICE)
#warning "BOOTICE mode - no startup-condition"
if( val == 0x1B ) /* ESC */
{ // AVRPROG connection #else
while (val != 'S') // Wait for signon #error "Select START_ condition for bootloader in main.c"
{ #endif
val = recchar();
} for(;;)
send_boot(); // Report signon {
OK = 0; val=recchar();
}
else if(val=='a') //Autoincrement?
sendchar('?'); {
} sendchar('Y'); //Autoincrement is quicker
// Power-Save code here }
}
else if(val=='A') //write address
#elif defined(START_SIMPLE) {
BLDDR &= ~(1<<BLPNUM); // set as Input address=recchar(); //read address 8 MSB
BLPORT |= (1<<BLPNUM); // Enable pullup address=(address<<8)|recchar();
if((BLPIN & (1<<BLPNUM))) address=address<<1; // !! convert from word address to byte address
{ sendchar('\r');
// jump to main app if pin is not grounded }
BLPORT &= ~(1<<BLPNUM); // set to default
MCUCR = (1<<IVCE); else if(val=='b')
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector { // Buffer load support
jump_to_app(); // Jump to application sector sendchar('Y'); // Report buffer load supported
} sendchar((UART_RX_BUFFER_SIZE >> 8) & 0xFF);
// Report buffer size in bytes
#elif defined(START_BOOTICE) sendchar(UART_RX_BUFFER_SIZE & 0xFF);
#warning "BOOTICE mode - no startup-condition" }
#else else if(val=='B') // Start buffer load
#error "Select START_ condition for bootloader in main.c" {
#endif tempi = recchar() << 8; // Load high byte of buffersize
tempi |= recchar(); // Load low byte of buffersize
for(;;) val = recchar(); // Load memory type ('E' or 'F')
{ sendchar (BufferLoad(tempi,val));
val=recchar(); // Start downloading of buffer
}
if(val=='a') //Autoincrement?
{ else if(val == 'g') // Block read
sendchar('Y'); //Autoincrement is quicker {
} tempi = (recchar() << 8) | recchar();
else if(val=='A') //write address val = recchar(); // Get memtype
{ BlockRead(tempi,val); // Perform the block read
address=recchar(); //read address 8 MSB }
address=(address<<8)|recchar();
else if(val=='e') //Chip erase
address=address<<1; // !! convert from word address to byte address {
sendchar('\r'); if (device == devtype)
} {
// erase only main section (bootloader protection)
else if(val=='b') address = 0;
{ // Buffer load support while ( APP_END > address )
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_page_erase(address); // Perform page erase
boot_spm_busy_wait(); // Wait until the memory is erased. boot_spm_busy_wait(); // Wait until the memory is erased.
address += SPM_PAGESIZE; address += SPM_PAGESIZE;
} }
} }
boot_rww_enable(); boot_rww_enable();
sendchar('\r'); sendchar('\r');
} }
else if(val=='E') //Exit upgrade else if(val=='E') //Exit upgrade
{ {
wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset
sendchar('\r'); sendchar('\r');
} }
#ifdef WRITELOCKBITS #ifdef WRITELOCKBITS
#warning "Extension 'WriteLockBits' enabled" #warning "Extension 'WriteLockBits' enabled"
// TODO: does not work reliably // TODO: does not work reliably
else if(val=='l') // write lockbits else if(val=='l') // write lockbits
{ {
if (device == devtype) if (device == devtype)
{ {
// write_lock_bits(recchar()); // write_lock_bits(recchar());
boot_lock_bits_set(recchar()); // boot.h takes care of mask boot_lock_bits_set(recchar()); // boot.h takes care of mask
boot_spm_busy_wait(); boot_spm_busy_wait();
} }
sendchar('\r'); sendchar('\r');
} }
#endif #endif
else if(val=='P') // Enter programming mode else if(val=='P') // Enter programming mode
{ {
sendchar('\r'); sendchar('\r');
} }
else if(val=='L') // Leave programming mode else if(val=='L') // Leave programming mode
{ {
sendchar('\r'); sendchar('\r');
} }
else if (val=='p') // return programmer type else if (val=='p') // return programmer type
{ {
sendchar('S'); // always serial programmer sendchar('S'); // always serial programmer
} }
#ifdef ENABLEREADFUSELOCK #ifdef ENABLEREADFUSELOCK
#warning "Extension 'ReadFuseLock' enabled" #warning "Extension 'ReadFuseLock' enabled"
else if(val=='F') // read "low" fuse bits else if(val=='F') // read "low" fuse bits
{ {
sendchar( read_fuse_lock(0x0000, _BV(BLBSET)|_BV(SPMEN)) ); sendchar( read_fuse_lock(0x0000, _BV(BLBSET)|_BV(SPMEN)) );
} }
else if(val=='r') // read lock bits else if(val=='r') // read lock bits
{ {
sendchar( read_fuse_lock(0x0001, _BV(BLBSET)|_BV(SPMEN)) ); sendchar( read_fuse_lock(0x0001, _BV(BLBSET)|_BV(SPMEN)) );
} }
else if(val=='N') // read high fuse bits else if(val=='N') // read high fuse bits
{ {
sendchar( read_fuse_lock(0x0003,_BV(BLBSET)|_BV(SPMEN)) ); sendchar( read_fuse_lock(0x0003,_BV(BLBSET)|_BV(SPMEN)) );
} }
else if(val=='Q') // read extended fuse bits else if(val=='Q') // read extended fuse bits
{ {
sendchar( read_fuse_lock(0x0002,_BV(BLBSET)|_BV(SPMEN)) ); sendchar( read_fuse_lock(0x0002,_BV(BLBSET)|_BV(SPMEN)) );
} }
#endif #endif
// end of ENABLEREADFUSELOCK section // end of ENABLEREADFUSELOCK section
else if(val=='t') // Return device type else if(val=='t') // Return device type
{ {
sendchar(devtype); sendchar(devtype);
sendchar(0); sendchar(0);
} }
else if ((val=='x')||(val=='y')) // clear and set LED ignored else if ((val=='x')||(val=='y')) // clear and set LED ignored
{ {
recchar(); recchar();
sendchar('\r'); sendchar('\r');
} }
else if (val=='T') // set device else if (val=='T') // set device
{ {
device = recchar(); device = recchar();
sendchar('\r'); sendchar('\r');
} }
else if (val=='S') // Return software identifier else if (val=='S') // Return software identifier
{ {
send_boot(); send_boot();
} }
else if (val=='V') // Return Software Version else if (val=='V') // Return Software Version
{ {
sendchar(VERSION_HIGH); sendchar(VERSION_HIGH);
sendchar(VERSION_LOW); sendchar(VERSION_LOW);
} }
else if (val=='s') // Return Signature Byte else if (val=='s') // Return Signature Byte
{ {
sendchar(sig_byte1); sendchar(sig_byte1);
sendchar(sig_byte2); sendchar(sig_byte2);
sendchar(sig_byte3); sendchar(sig_byte3);
} }
else if(val != 0x1b) /* ESC */ else if(val != 0x1b) /* ESC */
{ {
sendchar('?'); sendchar('?');
} }
} // end of "parser" for-loop } // end of "parser" for-loop
return 0; return 0;
} }
unsigned char BufferLoad(unsigned int size, unsigned char mem) unsigned char BufferLoad(unsigned int size, unsigned char mem)
{ {
unsigned int data, cnt; unsigned int data, cnt;
uint32_t tempaddress; uint32_t tempaddress;
for (cnt=0; cnt<UART_RX_BUFFER_SIZE; cnt++) { for (cnt=0; cnt<UART_RX_BUFFER_SIZE; cnt++) {
if (cnt<size) gBuffer[cnt]=recchar(); if (cnt<size) gBuffer[cnt]=recchar();
else gBuffer[cnt]=0xFF; else gBuffer[cnt]=0xFF;
} }
cnt=0; cnt=0;
tempaddress = address; // Store address in page tempaddress = address; // Store address in page
my_eeprom_busy_wait(); my_eeprom_busy_wait();
if (device == devtype) if (device == devtype)
{ {
if (mem == 'F') // Flash if (mem == 'F') // Flash
{ {
do { do {
data=gBuffer[cnt++]; data=gBuffer[cnt++];
data|=(gBuffer[cnt++]<<8); data|=(gBuffer[cnt++]<<8);
boot_page_fill(address,data); boot_page_fill(address,data);
//call asm routine. //call asm routine.
address=address+2; // Select next word in memory address=address+2; // Select next word in memory
size -= 2; // Reduce number of bytes to write by two size -= 2; // Reduce number of bytes to write by two
} while(size); // Loop until all bytes written } while(size); // Loop until all bytes written
/* commented out since not compatible with mega8 - /* commented out since not compatible with mega8 -
secondary benefit: saves memory secondary benefit: saves memory
tempaddress &= 0xFF80; // Ensure the address points to the first byte in the page tempaddress &= 0xFF80; // Ensure the address points to the first byte in the page
*/ */
boot_page_write(tempaddress); boot_page_write(tempaddress);
boot_spm_busy_wait(); boot_spm_busy_wait();
boot_rww_enable(); //Re-enable the RWW section boot_rww_enable(); //Re-enable the RWW section
/* commented out since not compatible with mega8 /* commented out since not compatible with mega8
if (address != (address & 0xFF80)) if (address != (address & 0xFF80))
{ // Ensure that the address points to the beginning of the next page { // Ensure that the address points to the beginning of the next page
address &= 0xFF80; address &= 0xFF80;
address += SPM_PAGESIZE; address += SPM_PAGESIZE;
} }
*/ */
} // End FLASH } // End FLASH
if (mem == 'E') // Start EEPROM if (mem == 'E') // Start EEPROM
{ {
address>>=1; address>>=1;
do { do {
EEARL = address; // Setup EEPROM address EEARL = address; // Setup EEPROM address
EEARH = (address >> 8); EEARH = (address >> 8);
address++; // Select next byte address++; // Select next byte
EEDR=gBuffer[cnt++]; EEDR=gBuffer[cnt++];
EECR |= (1<<EEMWE); // Write data into EEPROM EECR |= (1<<EEMWE); // Write data into EEPROM
EECR |= (1<<EEWE); EECR |= (1<<EEWE);
while (EECR & (1<<EEWE)); // Wait for EEPROM write to finish while (EECR & (1<<EEWE)); // Wait for EEPROM write to finish
size--; // Decreas number of bytes to write size--; // Decreas number of bytes to write
} while(size); // Loop until all bytes written } while(size); // Loop until all bytes written
} }
return '\r'; // Report programming OK return '\r'; // Report programming OK
} }
return 0; // Report programming failed return 0; // Report programming failed
} }
void BlockRead(unsigned int size, unsigned char mem) void BlockRead(unsigned int size, unsigned char mem)
{ {
unsigned int data; unsigned int data;
my_eeprom_busy_wait(); my_eeprom_busy_wait();
if (mem == 'E') // Read EEPROM if (mem == 'E') // Read EEPROM
{ {
// address>>=1; // not needed here - hmm, somehow inconsistant TODO // address>>=1; // not needed here - hmm, somehow inconsistant TODO
do { do {
EEARL = address; // Setup EEPROM address EEARL = address; // Setup EEPROM address
EEARH = (address >> 8); EEARH = (address >> 8);
address++; // Select next EEPROM byte address++; // Select next EEPROM byte
EECR |= (1<<EERE); // Read EEPROM EECR |= (1<<EERE); // Read EEPROM
sendchar(EEDR); // Transmit EEPROM data to PC sendchar(EEDR); // Transmit EEPROM data to PC
size--; // Decrease number of bytes to read size--; // Decrease number of bytes to read
} while (size); // Repeat until all block has been read } while (size); // Repeat until all block has been read
} }
else // Read Flash else // Read Flash
{ {
do { do {
#if defined(RAMPZ) #if defined(RAMPZ)
data = pgm_read_word_far(address); data = pgm_read_word_far(address);
#else #else
data = pgm_read_word_near((uint16_t)address); data = pgm_read_word_near((uint16_t)address);
#endif #endif
sendchar((unsigned char)data); //send LSB sendchar((unsigned char)data); //send LSB
sendchar((unsigned char)(data >> 8)); //send MSB sendchar((unsigned char)(data >> 8)); //send MSB
address += 2; // Select next word in memory address += 2; // Select next word in memory
size -= 2; // Subtract two bytes from number of bytes to read size -= 2; // Subtract two bytes from number of bytes to read
} while (size); // Repeat until all block has been 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". # To rebuild project do "make clean" then "make all".
# #
# user defined values
# MCU name # MCU name
## MCU = atmega16 ## MCU = atmega16
## MCU = atmega8 ## MCU = atmega8
MCU = atmega32 ## MCU = atmega32
## MCU = atmega128 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 ###################### ################## BOOTLOADER ######################
# mt: Boot loader support. So far not done with a separate section # mt: Boot loader support. So far not done with a separate section
@ -46,20 +83,33 @@ MCU = atmega32
# (see LDFLAGS further down) # (see LDFLAGS further down)
# 0x1C00*2=0x3800 for ATmega16 1024 words Boot Size # 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 # 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 # 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 # 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) # Output format. (can be srec, ihex, binary)
FORMAT = ihex FORMAT = srec
# Target file name (without extension). # Target file name (without extension).
TARGET = main TARGET = main
@ -103,8 +153,11 @@ EXTRAINCDIRS =
CSTANDARD = -std=gnu99 CSTANDARD = -std=gnu99
# Place -D or -U options here # 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 # Place -I options here
CINCS = CINCS =
@ -196,7 +249,8 @@ LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
AVRDUDE_PROGRAMMER = stk500v2 AVRDUDE_PROGRAMMER = stk500v2
# com1 = serial port. Use lpt1 to connect to parallel port. # 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_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
@ -235,11 +289,11 @@ DIRLIB = $(DIRAVR)/avr/lib
# Define programs and commands. # Define programs and commands.
SHELL = sh SHELL = sh
CC = avr-gcc CC = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-gcc
OBJCOPY = avr-objcopy OBJCOPY = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-objcopy
OBJDUMP = avr-objdump OBJDUMP = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-objdump
SIZE = avr-size SIZE = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-size
NM = avr-nm NM = env WINEDLLOVERRIDES=msvcrt=n /spare/bon/wine/wine/wine c:/WinAVR/bin/avr-nm
AVRDUDE = avrdude AVRDUDE = avrdude
REMOVE = rm -f REMOVE = rm -f
COPY = cp 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 23. Feb. 2005 - Version 0.7
* (Version 0.6 has never been available on the web-page) * (Version 0.6 has never been available on the web-page)
@ -98,31 +104,20 @@ not enabled (TODO).
ATmega16 has been tested, ATmega169, ATmega8 ATmega16 has been tested, ATmega169, ATmega8
and ATmega32 should be o.k. too. 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), bootloader is larger than 512 words (1024 bytes),
so select at least _B1024! 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 of your board (keep BAUDRATE at 19200). See
the datasheet for frequencies with minimum the datasheet for frequencies with minimum
error at 19200bps and select Crystal/Oscillator error at 19200bps and select Crystal/Oscillator
to get minimum errors. 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 is: enter bootloader if Pin A7 is connected to
GND during reset/startup 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 - Please use at least avr-gcc 3.3.1/avr-libc 1.0
or WINAVR Sept. 2003 or later to compile and link or WINAVR Sept. 2003 or later to compile and link
the bootloader. the bootloader.

2
uart.c
View File

@ -39,7 +39,7 @@
#define UART1_CONTROL2 UCSR1C #define UART1_CONTROL2 UCSR1C
#define UART1_DATA UDR1 #define UART1_DATA UDR1
#define UART1_UDRIE UDRIE1 #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 */ /* ATMega with two USART */
#define ATMEGA_USART0 #define ATMEGA_USART0
#define ATMEGA_USART1 #define ATMEGA_USART1

2
uart.h
View File

@ -1,7 +1,7 @@
#ifndef UART_H #ifndef UART_H
#define 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 UARTDOUBLE 1
#define UARTSINGLE 0 #define UARTSINGLE 0