Version 0.7 (20050226)

This commit is contained in:
Olaf Rempel 2006-05-01 19:15:27 +02:00
parent f32c7e3131
commit f2c227f428
9 changed files with 715 additions and 1182 deletions

1
avrprog_boot.pnproj Normal file
View File

@ -0,0 +1 @@
<Project name="avrprog_boot"><File path="uart.h"></File><File path="lowlevel.c"></File><File path="lowlevel.h"></File><File path="main.c"></File><File path="makefile"></File><File path="readme.txt"></File><File path="uart.c"></File><File path="chipdef.h"></File><File path="main.lss"></File></Project>

View File

@ -0,0 +1,93 @@
: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

@ -107,23 +107,50 @@
// #define PAGESIZE 128 // Size in Bytes // #define PAGESIZE 128 // Size in Bytes
#ifdef _B128 #ifdef _B128
#define APP_PAGES ((2*16384 / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE )) #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*128 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE #define APP_END APP_PAGES * SPM_PAGESIZE
#endif #endif
#ifdef _B256 #ifdef _B256
#define APP_PAGES ((2*16384 / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE )) #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*256 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE #define APP_END APP_PAGES * SPM_PAGESIZE
#endif #endif
#ifdef _B512 #ifdef _B512
#define APP_PAGES ((2*16384 / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE )) #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*512 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE #define APP_END APP_PAGES * SPM_PAGESIZE
#endif #endif
#ifdef _B1024 #ifdef _B1024
#define APP_PAGES ((2*16384 / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE )) #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*1024 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE #define APP_END APP_PAGES * SPM_PAGESIZE
#endif #endif
#ifdef _B2048 #ifdef _B2048
#define APP_PAGES ((2*16384 / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE )) #define APP_PAGES ((2*16384UL / SPM_PAGESIZE)- (2*2048 / SPM_PAGESIZE ))
#define APP_END APP_PAGES * SPM_PAGESIZE
#endif
#elif defined(__AVR_ATmega128__)
#define sig_byte3 0x1E
#define sig_byte2 0x97
#define sig_byte1 0x02
#define devtype 0x44 // Mega128 device code
// #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 #define APP_END APP_PAGES * SPM_PAGESIZE
#endif #endif

View File

@ -1,42 +1,25 @@
// //
// Low-level bootloader routines to replace "assembly.s90" // Low-level routines to read lock and fuse-bytes
// from the original ATMEL Butterfly bootloader code
// which are not included in avr-libc's boot.h by the
// time of writing this.
// //
// 3/2004 Martin Thomas, Kaiserslautern, Germany // Copyright (C) 2/2005 Martin Thomas, Kaiserslautern, Germany
// //
#include "lowlevel.h" #include "lowlevel.h"
unsigned int read_program_memory(unsigned int adr, unsigned char param) unsigned char read_fuse_lock(unsigned short addr, unsigned char mode)
// to read lockbits give param=0x09, if param!=0 it is written to SPMCSR
// this is a "translation" from the original code to gcc-inline-assembler
{ {
unsigned int retval; unsigned char retval;
asm volatile asm volatile
( (
"movw r30, %3\n\t" "movw r30, %3\n\t" /* Z to addr */ \
"sbrc %2,0x00\n\t" "sts %0, %2\n\t" /* set mode in SPM_REG */ \
"sts %0, %2\n\t" "lpm\n\t" /* load fuse/lock value into r0 */ \
#ifdef LARGE_MEMORY // If large memory (>64K) ELPM is needed to use RAMPZ "mov %1,r0\n\t" /* save return value */ \
"elpm\n\t" // read LSB
#else
"lpm\n\t" // R0 is now the LSB of the return value
#endif
"mov %A1,r0\n\t"
"inc r30\n\t"
#ifdef LARGE_MEMORY // If large memory (>64K) ELPM is needed to use RAMPZ
"elpm\n\t" // read MSB
#else
"lpm\n\t" // R0 is now the MSB of the return value
#endif
"mov %B1,r0\n\t"
: "=m" (SPM_REG), : "=m" (SPM_REG),
"=r" (retval) "=r" (retval)
: "r" ((unsigned char)param), : "r" (mode),
"r" ((unsigned short)adr) "r" (addr)
: "r30", "r31", "r0" : "r30", "r31", "r0"
); );
return retval; return retval;

View File

@ -12,7 +12,7 @@
# error AVR processor does not provide bootloader support! # error AVR processor does not provide bootloader support!
#endif #endif
unsigned int read_program_memory (unsigned int,unsigned char); unsigned char read_fuse_lock(unsigned short addr, unsigned char mode);
#endif #endif

350
main.c
View File

@ -1,17 +1,18 @@
/***************************************************************************** /*****************************************************************************
* *
* AVRPROG compatible boot-loader * AVRPROG compatible boot-loader
* Version : 0.5 (7. Apr. 2004) * Version : 0.7 (Feb. 2005)
* Compiler : avr-gcc 3.3.1 / avr-libc 1.0 * 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 : none. free code and free to use and modify * License : Copyright (c) 2005 Martin Thomas
* BUT: Please send me bug-reports if you find out that * Free to use. You have to mention the copyright
* something has been done wrong. You may mention where * owners in source-code and documentation of derived
* you've got the source in the documention of your * work. No warranty.
* project if you're using this bootloader. *
* 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
@ -27,11 +28,6 @@
* *
**************************************************************************** ****************************************************************************
* *
* Many functions used by "AVRPROG" (fuses) have been disabled by ATMEL in
* the original source code of the Butterfly Boot-loader not by me.
* I will try to make all of them available in later versions but i.e the
* ATmega169 is not completly supported by AVRPROG 1.37.
*
* 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
@ -47,25 +43,32 @@
* 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
* makefile.
*
****************************************************************************/ ****************************************************************************/
/* /*
Does not work so far: Does not work reliably so far:
- fuse high byte read (or parse in AVRPROG?)
- 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 '5' #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/pgmspace.h>
// function not found in boot.h to read lock/fuses
#include "lowlevel.h"
/* Port and Pin in this port that has to grounded /* Pin "BLPNUM" on port "BLPORT" in this port has to grounded
(active low) to start the bootloader */ (active low) to start the bootloader */
#define BLPORT PORTC #define BLPORT PORTC
#define BLDDR DDRC
#define BLPIN PINC #define BLPIN PINC
#define BLPNUM PINC0 #define BLPNUM PINC0
@ -89,6 +92,7 @@
#ifndef START_BOOTICE #ifndef START_BOOTICE
#define XTAL 3686400 #define XTAL 3686400
// #define XTAL 8000000UL
#else #else
#warning "BOOTICE mode - External Crystal/Oszillator must be 7,3728 MHz" #warning "BOOTICE mode - External Crystal/Oszillator must be 7,3728 MHz"
#define XTAL 7372800 #define XTAL 7372800
@ -100,13 +104,14 @@
/* enable/disable readout of fuse and lock-bits /* enable/disable readout of fuse and lock-bits
(will not work for Mega169 since not supported by AVRPROG 1.37 */ (will not work for Mega169 since not supported by AVRPROG 1.37 */
// #define ENABLEREADFUSELOCK #define ENABLEREADFUSELOCK
/* enable/disable write of lock-bits /* enable/disable write of lock-bits
WARNING: lock-bits can not be reseted by bootloader (as far as I know) WARNING: lock-bits can not be reseted by bootloader (as far as I know)
Only protection no unprotection, "chip erase" from bootloader only Only protection no unprotection, "chip erase" from bootloader only
clears the flash but does no real "chip erase" (this is not possible clears the flash but does no real "chip erase" (this is not possible
with a bootloader as far as I know) with a bootloader as far as I know)
Keep this undefined!
*/ */
// #define WRITELOCKBITS // #define WRITELOCKBITS
@ -119,14 +124,6 @@
#include "chipdef.h" #include "chipdef.h"
// this uses the latest version from avr-libc CVS not the one that comes
// with WINAVR Sep./03 (6.Apr.04: it's like the boot.h from the Apr/04
// WINAVR but the lock-bit-mask has been changed. Found out during the
// development of a STK500-plugin-compatible-bootloader)
#include "myboot.h"
// functions not found in boot.h
#include "lowlevel.h"
#define UART_RX_BUFFER_SIZE SPM_PAGESIZE #define UART_RX_BUFFER_SIZE SPM_PAGESIZE
unsigned char gBuffer[UART_RX_BUFFER_SIZE]; unsigned char gBuffer[UART_RX_BUFFER_SIZE];
@ -136,7 +133,7 @@ unsigned char gBuffer[UART_RX_BUFFER_SIZE];
unsigned char BufferLoad(unsigned int , unsigned char ) ; unsigned char BufferLoad(unsigned int , unsigned char ) ;
void BlockRead(unsigned int , unsigned char ) ; void BlockRead(unsigned int , unsigned char ) ;
unsigned short address; uint32_t address;
unsigned char device; unsigned char device;
void send_boot(void) void send_boot(void)
@ -154,15 +151,17 @@ void (*jump_to_app)(void) = 0x0000;
int main(void) int main(void)
{ {
unsigned short tempi; unsigned tempi;
char val; char val;
#ifdef START_POWERSAVE #ifdef START_POWERSAVE
char OK = 1; char OK = 1;
#endif #endif
cli();
MCUCR = (1<<IVCE); MCUCR = (1<<IVCE);
MCUCR = (1<<IVSEL); //move interruptvectors to the Boot sector 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,XTAL),UARTSINGLE); // single speed
// USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed // USART_Init(UART_BAUD_SELECT(BAUDRATE/2,XTAL),UARTDOUBLE); // double speed
@ -174,50 +173,54 @@ int main(void)
the main parser-loop gives a lot a possibilities (timeout, sleep-modes the main parser-loop gives a lot a possibilities (timeout, sleep-modes
etc.). etc.).
*/ */
BLPORT = 0xFF; // Enable pullups on Port C BLDDR &= ~(1<<BLPNUM); // set as Input
BLPORT |= (1<<BLPNUM); // Enable pullup
for(;OK;) for(;OK;)
{ {
if((BLPIN & (1<<BLPNUM))) if((BLPIN & (1<<BLPNUM)))
{ {
// jump to main app if PIN C0 is not grounded // jump to main app if pin is not grounded
BLPORT = 0x00; // set to default BLPORT &= ~(1<<BLPNUM); // set to default
MCUCR = (1<<IVCE); MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector MCUCR = (0<<IVSEL); // move interruptvectors to the Application sector
jump_to_app(); // Jump to application sector jump_to_app(); // Jump to application sector
} }
else else
{ {
val = recchar(); val = recchar();
if( val == 0x1B) if( val == 0x1B ) /* ESC */
{ // AVRPROG connection { // AVRPROG connection
while (val != 'S') // Wait for signon while (val != 'S') // Wait for signon
{ {
val = recchar(); val = recchar();
} }
send_boot(); // Report signon send_boot(); // Report signon
OK = 0; OK = 0;
} }
else else
sendchar('?'); sendchar('?');
} }
// Power-Save code here // Power-Save code here
} }
#elif defined(START_SIMPLE) #elif defined(START_SIMPLE)
BLPORT = 0xFF; // Enable pullups on Port C BLDDR &= ~(1<<BLPNUM); // set as Input
BLPORT |= (1<<BLPNUM); // Enable pullup
if((BLPIN & (1<<BLPNUM))) if((BLPIN & (1<<BLPNUM)))
{ {
// jump to main app if PIN C0 is not grounded // jump to main app if pin is not grounded
BLPORT = 0x00; // set to default BLPORT &= ~(1<<BLPNUM); // set to default
MCUCR = (1<<IVCE); MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector MCUCR = (0<<IVSEL); //move interruptvectors to the Application sector
jump_to_app(); // Jump to application sector jump_to_app(); // Jump to application sector
} }
#elif defined(START_BOOTICE) #elif defined(START_BOOTICE)
#warning "BOOTICE mode - no startup-condition" #warning "BOOTICE mode - no startup-condition"
#else #else
#error "Select START_ condition for bootloader in main.c" #error "Select START_ condition for bootloader in main.c"
#endif #endif
@ -228,16 +231,16 @@ int main(void)
if(val=='a') //Autoincrement? if(val=='a') //Autoincrement?
{ {
sendchar('Y'); //Autoincrement is quicker sendchar('Y'); //Autoincrement is quicker
} }
else if(val=='A') //write address else if(val=='A') //write address
{ {
address=recchar(); //read address 8 MSB address=recchar(); //read address 8 MSB
address=(address<<8)|recchar(); address=(address<<8)|recchar();
address=address<<1; //convert from word address to byte address address=address<<1; // !! convert from word address to byte address
sendchar('\r'); sendchar('\r');
} }
else if(val=='b') else if(val=='b')
@ -264,175 +267,102 @@ int main(void)
val = recchar(); // Get memtype val = recchar(); // Get memtype
BlockRead(tempi,val); // Perform the block read BlockRead(tempi,val); // Perform the block read
} }
/*
else if(val=='c') //Write program memory, low byte
{
ldata=recchar();
sendchar('\r');
}
else if(val== 'C') //Write program memory, high byte
{
data=ldata|(recchar()<<8);
if (device == devtype)
{
fill_temp_buffer(data,(address)); //call asm routine.
}
address=address+2;
sendchar('\r');
}
*/
else if(val=='e') //Chip erase else if(val=='e') //Chip erase
{ {
if (device == devtype) if (device == devtype)
{ {
// erase only main section (bootloader protection) // erase only main section (bootloader protection)
for(address=0;address < APP_END;address += SPM_PAGESIZE) //Application section = 60 pages address = 0;
{ while ( APP_END > address )
//write_page(address,(1<<PGERS) + (1<<SPMEN)); //Perform page erase {
boot_page_erase(address); 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;
} }
// write_page(address,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section }
boot_rww_enable(); boot_rww_enable();
sendchar('\r'); sendchar('\r');
} }
else if(val=='E') //Exit upgrade else if(val=='E') //Exit upgrade
{ {
// WDTCR = (1<<WDTCE) | (1<<WDE); //Enable Watchdog Timer to give reset wdt_enable(WDTO_15MS); // Enable Watchdog Timer to give reset
wdt_enable(WDTO_15MS); sendchar('\r');
sendchar('\r');
} }
#ifdef WRITELOCKBITS #ifdef WRITELOCKBITS
#warning "Extension 'WriteLockBits' enabled" #warning "Extension 'WriteLockBits' enabled"
// TODO: does not work // 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== 'm') // write page
{
if (device == devtype)
{
write_page(address,(1<<PGERS) + (1<<SPMEN)); //Perform page erase
write_page((address),0x05);
write_page(address,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
}
sendchar('\r');
}
*/
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') // mt: return programmer type else if (val=='p') // return programmer type
{ {
sendchar('S'); // always serial programmer sendchar('S'); // always serial programmer
} }
/*
else if(val=='R') //Read program memory
{
write_page(0,(1<<RWWSRE) + (1<<SPMEN)); //Re-enable the RWW section
// SPMCSR = (1<<RWWSRE) | (1<<SPMEN);
// __store_program_memory();
// while((SPMCSR & 0x01));
intval=read_program_memory(address,0x00);
sendchar((char)(intval>>8)); //send MSB
sendchar((char)intval); //send LSB
address=address+2;
}
*/
/*
else if (val == 'D') // write EEPROM
{
if (device == devtype)
{
EEARL = address;
EEARH = (address >> 8);
address++;
EEDR = recchar();
EECR |= (1<<EEMWE);
EECR |= (1<<EEWE);
while (EECR & (1<<EEWE))
;
}
sendchar('\r');
}
*/
/*
else if (val == 'd') // read eeprom
{
EEARL = address;
EEARH = (address >> 8);
address++;
EECR |= (1<<EERE);
sendchar(EEDR);
}
*/
#ifdef ENABLEREADFUSELOCK #ifdef ENABLEREADFUSELOCK
#warning "Extension 'ReadFuseLock' enabled" #warning "Extension 'ReadFuseLock' enabled"
else if(val=='F') // read fuse bits else if(val=='F') // read "low" fuse bits
{ {
sendchar((unsigned char) read_program_memory(0x0000,_BV(BLBSET)|_BV(SPMEN))); // 0x09 for (1<<BLBSET)|(1<<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((unsigned char) read_program_memory(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
// TODO: does not work
{ {
sendchar((unsigned char) read_program_memory(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('?'); // TODO see ATmega128 datasheet 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/programmer type in bootloader (?) 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();
@ -440,20 +370,20 @@ int main(void)
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) // if not esc else if(val != 0x1b) /* ESC */
{ {
sendchar('?'); sendchar('?');
} }
} // end of "parser" for-loop } // end of "parser" for-loop
@ -463,9 +393,9 @@ int main(void)
unsigned char BufferLoad(unsigned int size, unsigned char mem) unsigned char BufferLoad(unsigned int size, unsigned char mem)
{ {
unsigned int data, tempaddress, cnt; unsigned int data, cnt;
unsigned char sreg; 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;
@ -478,23 +408,15 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem)
if (device == devtype) if (device == devtype)
{ {
// Disable interrupts.
sreg = SREG;
cli();
if (mem == 'F') // Flash if (mem == 'F') // Flash
{ {
do { do {
// data = recchar();
// data |= (recchar() << 8);
// fill_temp_buffer(data,(address));
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 -
@ -502,10 +424,8 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem)
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
*/ */
//write_page((tempaddress),0x05); // Program page contents
boot_page_write(tempaddress); boot_page_write(tempaddress);
boot_spm_busy_wait(); boot_spm_busy_wait();
// write_page(tempaddress,(1<<RWWSRE) + (1<<SPMEN));
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
@ -514,8 +434,7 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem)
address &= 0xFF80; address &= 0xFF80;
address += SPM_PAGESIZE; address += SPM_PAGESIZE;
} }
*/ */
} // End FLASH } // End FLASH
if (mem == 'E') // Start EEPROM if (mem == 'E') // Start EEPROM
@ -525,7 +444,6 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem)
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 = recchar(); // Load data to write
EEDR=gBuffer[cnt++]; EEDR=gBuffer[cnt++];
EECR |= (1<<EEMWE); // Write data into EEPROM EECR |= (1<<EEMWE); // Write data into EEPROM
@ -536,10 +454,7 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem)
} while(size); // Loop until all bytes written } while(size); // Loop until all bytes written
} }
// Re-enable interrupts (if they were ever enabled).
SREG = sreg;
return '\r'; // Report programming OK return '\r'; // Report programming OK
} }
@ -551,14 +466,6 @@ void BlockRead(unsigned int size, unsigned char mem)
{ {
unsigned int data; unsigned int data;
// Disable interrupts if needed
/*
unsigned char sreg;
sreg = SREG;
cli();
*/
my_eeprom_busy_wait(); my_eeprom_busy_wait();
if (mem == 'E') // Read EEPROM if (mem == 'E') // Read EEPROM
@ -576,14 +483,15 @@ void BlockRead(unsigned int size, unsigned char mem)
else // Read Flash else // Read Flash
{ {
do { do {
data = read_program_memory(address,0x00); #if defined(RAMPZ)
sendchar((char)data); //send LSB data = pgm_read_word_far(address);
sendchar((char)(data >> 8)); //send MSB #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 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
} }
// Re-enable interrupts (if they were ever enabled).
/*SREG=sreg;*/
} }

843
makefile
View File

@ -1,415 +1,452 @@
# WinAVR makefile written by Eric B. Weddington, Jörg Wunsch, et al. # Hey Emacs, this is a -*- makefile -*-
# Released to the Public Domain #
# Please read the make user manual! # WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.
# # Released to the Public Domain
# Additional material for this makefile was submitted by: # Please read the make user manual!
# Tim Henigan #
# Peter Fleury # Additional material for this makefile was submitted by:
# Reiner Patommel # Tim Henigan
# Sander Pool # Peter Fleury
# Frederik Rouleau # Reiner Patommel
# Markus Pfaff # Sander Pool
# # Frederik Rouleau
# On command line: # Markus Pfaff
# #
# make all = Make software. # On command line:
# #
# make clean = Clean out built project files. # make all = Make software.
# #
# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). # make clean = Clean out built project files.
# #
# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio # make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).
# 4.07 or greater). #
# # make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio
# make program = Download the hex file to the device, using avrdude. Please # 4.07 or greater).
# customize the avrdude settings below first! #
# # make program = Download the hex file to the device, using avrdude. Please
# make filename.s = Just compile filename.c into the assembler code only # customize the avrdude settings below first!
# #
# To rebuild project do "make clean" then "make all". # make filename.s = Just compile filename.c into the assembler code only
# #
# To rebuild project do "make clean" then "make all".
#
# MCU name
## MCU = atmega16
MCU = atmega8 # MCU name
## MCU = atmega16
################## BOOTLOADER ###################### ## MCU = atmega8
# mt: Boot loader support. So far not done with a separate section MCU = atmega32
# to get the interrupt vector into the bootloader area. ## MCU = atmega128
# Bootloader address in datasheet and stk500 is given as
# "word", gcc toolchain needs "byte"-address ################## BOOTLOADER ######################
# (see LDFLAGS further down) # mt: Boot loader support. So far not done with a separate section
# to get the interrupt vector into the bootloader area.
# 0x1C00*2=0x3800 for ATmega16 1024 words Boot Size # Bootloader address in datasheet and stk500 is given as
## MT_BOOTLOADER_ADDRESS = 3800 # "word", gcc toolchain needs "byte"-address
# 0x0C00*2=0x1800 for ATmega8 1024 words Boot Size # (see LDFLAGS further down)
MT_BOOTLOADER_ADDRESS = 1800
# 0x1C00*2=0x3800 for ATmega16 1024 words Boot Size
## MT_BOOTLOADER_ADDRESS = 3800
# Output format. (can be srec, ihex, binary)
FORMAT = ihex # 0x0C00*2=0x1800 for ATmega8 1024 words Boot Size
## MT_BOOTLOADER_ADDRESS = 1800
# Target file name (without extension).
TARGET = main # 0x3C00*2=0x7800 for ATmega32 1024 words Boot Size
MT_BOOTLOADER_ADDRESS = 7800
# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) # 0xFC00*2=0x1F800 for ATmega128 1024 words Boot Size
OPT = s ##MT_BOOTLOADER_ADDRESS = 1F800
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c # Output format. (can be srec, ihex, binary)
FORMAT = ihex
# If there is more than one source file, append them above, or modify and
# uncomment the following: # Target file name (without extension).
# mt: the file test.c can be omitted (remove #inc test.h and test() in main.c) TARGET = main
SRC += uart.c lowlevel.c
# List C source files here. (C dependencies are automatically generated.)
# You can also wrap lines by appending a backslash to the end of the line: SRC = $(TARGET).c uart.c lowlevel.c
#SRC += baz.c \
#xyzzy.c
# List Assembler source files here.
# List Assembler source files here. # Make them always end in a capital .S. Files ending in a lowercase .s
# Make them always end in a capital .S. Files ending in a lowercase .s # will not be considered source files but generated files (assembler
# will not be considered source files but generated files (assembler # output from the compiler), and will be deleted upon "make clean"!
# output from the compiler), and will be deleted upon "make clean"! # Even though the DOS/Win* filesystem matches both .s and .S the same,
# Even though the DOS/Win* filesystem matches both .s and .S the same, # it will preserve the spelling of the filenames, and gcc itself does
# it will preserve the spelling of the filenames, and gcc itself does # care about how the name is spelled on its command-line.
# care about how the name is spelled on its command-line. ASRC =
ASRC =
# List any extra directories to look for include files here. # Optimization level, can be [0, 1, 2, 3, s].
# Each directory must be seperated by a space. # 0 = turn off optimization. s = optimize for size.
EXTRAINCDIRS = # (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Optional compiler flags. # Debugging format.
# -g: generate debugging information (for GDB, or for COFF conversion) # Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# -O*: optimization level # AVR (extended) COFF requires stabs, plus an avr-objcopy run.
# -f...: tuning, see gcc manual and avr-libc documentation DEBUG = stabs
# -Wall...: warning level
# -Wa,...: tell GCC to pass this to the assembler. # List any extra directories to look for include files here.
# -ahlms: create assembler listing # Each directory must be seperated by a space.
CFLAGS = -g -O$(OPT) \ EXTRAINCDIRS =
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
-Wall -Wstrict-prototypes \
-Wa,-adhlns=$(<:.c=.lst) \ # Compiler flag to set the C Standard level.
$(patsubst %,-I%,$(EXTRAINCDIRS)) # c89 - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99 - ISO C99 standard (not yet fully implemented)
# Set a "language standard" compiler flag. # gnu99 - c99 plus GCC extensions
# Unremark just one line below to set the language standard to use. CSTANDARD = -std=gnu99
# gnu99 = C99 + GNU extensions. See GCC manual for more information.
#CFLAGS += -std=c89 # Place -D or -U options here
#CFLAGS += -std=gnu89 CDEFS =
#CFLAGS += -std=c99
CFLAGS += -std=gnu99 # Place -I options here
CINCS =
# Optional assembler flags.
# -Wa,...: tell GCC to pass this to the assembler. # Compiler flags.
# -ahlms: create listing # -g*: generate debugging information
# -gstabs: have the assembler create line number information; note that # -O*: optimization level
# for use in COFF files, additional information about filenames # -f...: tuning, see GCC manual and avr-libc documentation
# and function names needs to be present in the assembler source # -Wall...: warning level
# files -- see avr-libc docs [FIXME: not yet described there] # -Wa,...: tell GCC to pass this to the assembler.
ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs # -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
# Optional linker flags. CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
# -Wl,...: tell GCC to pass this to linker. CFLAGS += -Wall -Wstrict-prototypes
# -Map: create map file CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
# --cref: add cross reference to map file CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref CFLAGS += $(CSTANDARD)
# Additional libraries
# Minimalistic printf version # Assembler flags.
#LDFLAGS += -Wl,-u,vfprintf -lprintf_min # -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing
# Floating point printf version (requires -lm below) # -gstabs: have the assembler create line number information; note that
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt # for use in COFF files, additional information about filenames
# and function names needs to be present in the assembler source
# -lm = math library # files -- see avr-libc docs [FIXME: not yet described there]
LDFLAGS += -lm ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
################## BOOTLOADER ######################
# MT_BOOTLOADER_ADDRESS (=Start of Boot Loader section
# in bytes - not words) is defined above. #Additional libraries.
LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
# Minimalistic printf version
# Programming support using avrdude. Settings and variables. PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Programming hardware: alf avr910 avrisp bascom bsd # Floating point printf version (requires MATH_LIB = -lm below)
# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
#
# Type: avrdude -c ? PRINTF_LIB =
# to get a full listing.
# # Minimalistic scanf version
AVRDUDE_PROGRAMMER = stk500 SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
AVRDUDE_PORT = com1 # programmer connected to serial device SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
#AVRDUDE_PORT = lpt1 # programmer connected to parallel port
SCANF_LIB =
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep MATH_LIB = -lm
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) # External memory options
# Uncomment the following if you want avrdude's erase cycle counter. # 64 KB of external RAM, starting after internal RAM (ATmega128!),
# Note that this counter needs to be initialized first using -Yn, # used for variables (.data/.bss) and heap (malloc()).
# see avrdude manual. #EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
#AVRDUDE_ERASE += -y
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# Uncomment the following if you do /not/ wish a verification to be # only used for heap (malloc()).
# performed after programming the device. #EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
#AVRDUDE_FLAGS += -V
EXTMEMOPTS =
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> # Linker flags.
# to submit bug reports. # -Wl,...: tell GCC to pass this to linker.
#AVRDUDE_FLAGS += -v -v # -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
# ---------------------------------------------------------------------------
################## BOOTLOADER ######################
# Define directories, if needed. # MT_BOOTLOADER_ADDRESS (=Start of Boot Loader section
DIRAVR = c:/winavr # in bytes - not words) is defined above.
DIRAVRBIN = $(DIRAVR)/bin LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
DIRAVRUTILS = $(DIRAVR)/utils/bin
DIRINC = .
DIRLIB = $(DIRAVR)/avr/lib
# Programming support using avrdude. Settings and variables.
# Define programs and commands. # Programming hardware: alf avr910 avrisp bascom bsd
SHELL = sh # dt006 pavr picoweb pony-stk200 sp12 stk200 stk500
#
CC = avr-gcc # Type: avrdude -c ?
# to get a full listing.
OBJCOPY = avr-objcopy #
OBJDUMP = avr-objdump AVRDUDE_PROGRAMMER = stk500v2
SIZE = avr-size
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com1 # programmer connected to serial device
# Programming support using avrdude.
AVRDUDE = avrdude AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
REMOVE = rm -f
COPY = cp # Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex # see avrdude manual.
#mt - use hexadezimal output-fromat // org: ELFSIZE = $(SIZE) -A $(TARGET).elf #AVRDUDE_ERASE_COUNTER = -y
ELFSIZE = $(SIZE) -x -A $(TARGET).elf
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
# Define Messages #AVRDUDE_NO_VERIFY = -V
# English
MSG_ERRORS_NONE = Errors: none # Increase verbosity level. Please use this when submitting bug
MSG_BEGIN = -------- begin -------- # reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
MSG_END = -------- end -------- # to submit bug reports.
MSG_SIZE_BEFORE = Size before: #AVRDUDE_VERBOSE = -v -v
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF: AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
MSG_EXTENDED_COFF = Converting to AVR Extended COFF: AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
MSG_FLASH = Creating load file for Flash: AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
MSG_EEPROM = Creating load file for EEPROM: AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling: # ---------------------------------------------------------------------------
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project: # Define directories, if needed.
DIRAVR = c:/winavr
DIRAVRBIN = $(DIRAVR)/bin
DIRAVRUTILS = $(DIRAVR)/utils/bin
DIRINC = .
# Define all object files. DIRLIB = $(DIRAVR)/avr/lib
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files. # Define programs and commands.
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) SHELL = sh
CC = avr-gcc
# Combine all necessary flags and optional flags. OBJCOPY = avr-objcopy
# Add target processor to flags. OBJDUMP = avr-objdump
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) SIZE = avr-size
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
COPY = cp
# Default target.
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \
$(TARGET).lss $(TARGET).sym sizeafter finished end
# Define Messages
# Eye candy. # English
# AVR Studio 3.x does not check make's exit code but relies on MSG_ERRORS_NONE = Errors: none
# the following magic strings to be generated by the compile job. MSG_BEGIN = -------- begin --------
begin: MSG_END = -------- end --------
@echo MSG_SIZE_BEFORE = Size before:
@echo $(MSG_BEGIN) MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
finished: MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
@echo $(MSG_ERRORS_NONE) MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
end: MSG_EXTENDED_LISTING = Creating Extended Listing:
@echo $(MSG_END) MSG_SYMBOL_TABLE = Creating Symbol Table:
@echo MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
# Display size of file. MSG_CLEANING = Cleaning project:
sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi # Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files.
# Display compiler version information. LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
gccversion :
@$(CC) --version
# Compiler flags to generate dependency files.
### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
# Convert ELF to COFF for use in debugging / simulating in # Combine all necessary flags and optional flags.
# AVR Studio or VMLAB. # Add target processor to flags.
COFFCONVERT=$(OBJCOPY) --debugging \ ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
--change-section-address .data-0x800000 \ ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf # Default target.
@echo all: begin gccversion sizebefore build sizeafter finished end
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof build: elf hex eep lss sym
elf: $(TARGET).elf
extcoff: $(TARGET).elf hex: $(TARGET).hex
@echo eep: $(TARGET).eep
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof lss: $(TARGET).lss
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof sym: $(TARGET).sym
# Eye candy.
# Program the device. # AVR Studio 3.x does not check make's exit code but relies on
program: $(TARGET).hex $(TARGET).eep # the following magic strings to be generated by the compile job.
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) begin:
@echo
@echo $(MSG_BEGIN)
finished:
# Create final output files (.hex, .eep) from ELF output file. @echo $(MSG_ERRORS_NONE)
%.hex: %.elf
end:
@echo $(MSG_END)
@echo
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -x -A $(TARGET).elf
sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
# Display compiler version information.
gccversion :
@$(CC) --version
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof
extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo @echo
@echo $(MSG_FLASH) $@ @echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf %.eep: %.elf
@echo @echo
@echo $(MSG_EEPROM) $@ @echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file. # Create extended listing file from ELF output file.
%.lss: %.elf %.lss: %.elf
@echo @echo
@echo $(MSG_EXTENDED_LISTING) $@ @echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S $< > $@ $(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file. # Create a symbol table from ELF output file.
%.sym: %.elf %.sym: %.elf
@echo @echo
@echo $(MSG_SYMBOL_TABLE) $@ @echo $(MSG_SYMBOL_TABLE) $@
avr-nm -n $< > $@ $(NM) -n $< > $@
# Link: create ELF output file from object files. # Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf .SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ) .PRECIOUS : $(OBJ)
%.elf: $(OBJ) %.elf: $(OBJ)
@echo @echo
@echo $(MSG_LINKING) $@ @echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)
# Compile: create object files from C source files. # Compile: create object files from C source files.
%.o : %.c %.o : %.c
@echo @echo
@echo $(MSG_COMPILING) $< @echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@ $(CC) -c $(ALL_CFLAGS) $< -o $@
# Compile: create assembler files from C source files. # Compile: create assembler files from C source files.
%.s : %.c %.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@ $(CC) -S $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files. # Assemble: create object files from assembler source files.
%.o : %.S %.o : %.S
@echo @echo
@echo $(MSG_ASSEMBLING) $< @echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@ $(CC) -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list finished end
# Target: clean project. clean_list :
clean: begin clean_list finished end
clean_list :
@echo @echo
@echo $(MSG_CLEANING) @echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex $(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep $(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).obj $(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).cof $(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf $(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map $(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).obj $(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).a90 $(REMOVE) $(TARGET).a90
$(REMOVE) $(TARGET).sym $(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lnk $(REMOVE) $(TARGET).lnk
$(REMOVE) $(TARGET).lss $(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ) $(REMOVE) $(OBJ)
$(REMOVE) $(LST) $(REMOVE) $(LST)
$(REMOVE) $(SRC:.c=.s) $(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d) $(REMOVE) $(SRC:.c=.d)
$(REMOVE) .dep/*
# Automatically generate C source code dependencies.
# (Code originally taken from the GNU make user manual and modified
# (See README.txt Credits).) # Include the dependency files.
# -include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Note that this will work with sh (bash) and sed that is shipped with WinAVR
# (see the SHELL variable defined above).
# This may not work with other shells or other seds. # Listing of phony targets.
# .PHONY : all begin finish end sizebefore sizeafter gccversion \
%.d: %.c build elf hex eep lss sym coff extcoff \
set -e; $(CC) -MM $(ALL_CFLAGS) $< \ clean clean_list program
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \
[ -s $@ ] || rm -f $@
# Remove the '-' if you want to see the dependency files generated.
-include $(SRC:.c=.d)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \
clean clean_list program

520
myboot.h
View File

@ -1,520 +0,0 @@
/* Copyright (c) 2002, 2003, 2004 Eric B. Weddington
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
#ifndef _AVR_BOOT_H_
#define _AVR_BOOT_H_ 1
/** \defgroup avr_boot Bootloader Support Utilities
\code
#include <avr/io.h>
#include <avr/boot.h>
\endcode
The macros in this module provide a C language interface to the
bootloader support functionality of certain AVR processors. These
macros are designed to work with all sizes of flash memory.
\note Not all AVR processors provide bootloader support. See your
processor datasheet to see if it provides bootloader support.
\todo From email with Marek: On smaller devices (all except ATmega64/128),
__SPM_REG is in the I/O space, accessible with the shorter "in" and "out"
instructions - since the boot loader has a limited size, this could be an
important optimization.
\par API Usage Example
The following code shows typical usage of the boot API.
\code
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
void boot_program_page (uint32_t page, uint8_t *buf)
{
uint16_t i;
uint8_t sreg;
// Disable interrupts.
sreg = SREG;
cli();
eeprom_busy_wait ();
boot_page_erase (page);
boot_spm_busy_wait (); // Wait until the memory is erased.
for (i=0; i<SPM_PAGESIZE; i+=2)
{
// Set up little-endian word.
uint16_t w = *buf++;
w += (*buf++) << 8;
boot_page_fill (page + i, w);
}
boot_page_write (page); // Store buffer in flash page.
boot_spm_busy_wait(); // Wait until the memory is written.
// Reenable RWW-section again. We need this if we want to jump back
// to the application after bootloading.
boot_rww_enable ();
// Re-enable interrupts (if they were ever enabled).
SREG = sreg;
}\endcode */
#include <avr/eeprom.h>
#include <avr/io.h>
#include <inttypes.h>
#include <limits.h>
/* Check for SPM Control Register in processor. */
#if defined (SPMCSR)
# define __SPM_REG SPMCSR
#elif defined (SPMCR)
# define __SPM_REG SPMCR
#else
# error AVR processor does not provide bootloader support!
#endif
/** \ingroup avr_boot
\def BOOTLOADER_SECTION
Used to declare a function or variable to be placed into a
new section called .bootloader. This section and its contents
can then be relocated to any address (such as the bootloader
NRWW area) at link-time. */
#define BOOTLOADER_SECTION __attribute__ ((section (".bootloader")))
/* Create common bit definitions. */
#ifdef ASB
#define __COMMON_ASB ASB
#else
#define __COMMON_ASB RWWSB
#endif
#ifdef ASRE
#define __COMMON_ASRE ASRE
#else
#define __COMMON_ASRE RWWSRE
#endif
/* Define the bit positions of the Boot Lock Bits. */
#define BLB12 5
#define BLB11 4
#define BLB02 3
#define BLB01 2
// mthomas:
#define LB2 1
#define LB1 0
#define LOCK6 6
#define LOCK7 7
/** \ingroup avr_boot
\def boot_spm_interrupt_enable()
Enable the SPM interrupt. */
#define boot_spm_interrupt_enable() (__SPM_REG |= (uint8_t)_BV(SPMIE))
/** \ingroup avr_boot
\def boot_spm_interrupt_disable()
Disable the SPM interrupt. */
#define boot_spm_interrupt_disable() (__SPM_REG &= (uint8_t)~_BV(SPMIE))
/** \ingroup avr_boot
\def boot_is_spm_interrupt()
Check if the SPM interrupt is enabled. */
#define boot_is_spm_interrupt() (__SPM_REG & (uint8_t)_BV(SPMIE))
/** \ingroup avr_boot
\def boot_rww_busy()
Check if the RWW section is busy. */
#define boot_rww_busy() (__SPM_REG & (uint8_t)_BV(__COMMON_ASB))
/** \ingroup avr_boot
\def boot_spm_busy()
Check if the SPM instruction is busy. */
#define boot_spm_busy() (__SPM_REG & (uint8_t)_BV(SPMEN))
/** \ingroup avr_boot
\def boot_spm_busy_wait()
Wait while the SPM instruction is busy. */
#define boot_spm_busy_wait() do{}while(boot_spm_busy())
#define __BOOT_PAGE_ERASE (_BV(SPMEN) | _BV(PGERS))
#define __BOOT_PAGE_WRITE (_BV(SPMEN) | _BV(PGWRT))
#define __BOOT_PAGE_FILL _BV(SPMEN)
#define __BOOT_RWW_ENABLE (_BV(SPMEN) | _BV(__COMMON_ASRE))
#define __BOOT_LOCK_BITS_SET (_BV(SPMEN) | _BV(BLBSET))
// mthomas - should be inverted
// #define __BOOT_LOCK_BITS_MASK (_BV(BLB01) | _BV(BLB02) | _BV(BLB11) | _BV(BLB12))
#define __BOOT_LOCK_BITS_MASK (_BV(LB1) | _BV(LB2) | _BV(LOCK6) | _BV(LOCK7))
#define __boot_page_fill_normal(address, data) \
({ \
__asm__ __volatile__ \
( \
"movw r0, %3\n\t" \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
"clr r1\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_PAGE_FILL), \
"r" ((uint16_t)address), \
"r" ((uint16_t)data) \
: "r0", "r30", "r31" \
); \
})
#define __boot_page_fill_alternate(address, data)\
({ \
__asm__ __volatile__ \
( \
"movw r0, %3\n\t" \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
"clr r1\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_PAGE_FILL), \
"r" ((uint16_t)address), \
"r" ((uint16_t)data) \
: "r0", "r30", "r31" \
); \
})
#define __boot_page_fill_extended(address, data) \
({ \
__asm__ __volatile__ \
( \
"movw r0, %4\n\t" \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
"clr r1\n\t" \
: "=m" (__SPM_REG), \
"=m" (RAMPZ) \
: "r" ((uint8_t)__BOOT_PAGE_FILL), \
"r" ((uint32_t)address), \
"r" ((uint16_t)data) \
: "r0", "r30", "r31" \
); \
})
#define __boot_page_erase_normal(address) \
({ \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_PAGE_ERASE), \
"r" ((uint16_t)address) \
: "r30", "r31" \
); \
})
#define __boot_page_erase_alternate(address) \
({ \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_PAGE_ERASE), \
"r" ((uint16_t)address) \
: "r30", "r31" \
); \
})
#define __boot_page_erase_extended(address) \
({ \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG), \
"=m" (RAMPZ) \
: "r" ((uint8_t)__BOOT_PAGE_ERASE), \
"r" ((uint32_t)address) \
: "r30", "r31" \
); \
})
#define __boot_page_write_normal(address) \
({ \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_PAGE_WRITE), \
"r" ((uint16_t)address) \
: "r30", "r31" \
); \
})
#define __boot_page_write_alternate(address) \
({ \
__asm__ __volatile__ \
( \
"movw r30, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_PAGE_WRITE), \
"r" ((uint16_t)address) \
: "r30", "r31" \
); \
})
#define __boot_page_write_extended(address) \
({ \
__asm__ __volatile__ \
( \
"movw r30, %A3\n\t" \
"sts %1, %C3\n\t" \
"sts %0, %2\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG), \
"=m" (RAMPZ) \
: "r" ((uint8_t)__BOOT_PAGE_WRITE), \
"r" ((uint32_t)address) \
: "r30", "r31" \
); \
})
#define __boot_rww_enable() \
({ \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_RWW_ENABLE) \
); \
})
#define __boot_rww_enable_alternate() \
({ \
__asm__ __volatile__ \
( \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_RWW_ENABLE) \
); \
})
#define __boot_lock_bits_set(lock_bits) \
({ \
uint8_t value = (uint8_t)(lock_bits | __BOOT_LOCK_BITS_MASK); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
"ldi r31, 0\n\t" \
"mov r0, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
"r" (value) \
: "r0", "r30", "r31" \
); \
})
#define __boot_lock_bits_set_alternate(lock_bits) \
({ \
uint8_t value = (uint8_t)(lock_bits | __BOOT_LOCK_BITS_MASK); \
__asm__ __volatile__ \
( \
"ldi r30, 1\n\t" \
"ldi r31, 0\n\t" \
"mov r0, %2\n\t" \
"sts %0, %1\n\t" \
"spm\n\t" \
".word 0xffff\n\t" \
"nop\n\t" \
: "=m" (__SPM_REG) \
: "r" ((uint8_t)__BOOT_LOCK_BITS_SET), \
"r" (value) \
: "r0", "r30", "r31" \
); \
})
/** \ingroup avr_boot
\def boot_page_fill(address, data)
Fill the bootloader temporary page buffer for flash
address with data word.
\note The address is a byte address. The data is a word. The AVR
writes data to the buffer a word at a time, but addresses the buffer
per byte! So, increment your address by 2 between calls, and send 2
data bytes in a word format! The LSB of the data is written to the lower
address; the MSB of the data is written to the higher address.*/
/** \ingroup avr_boot
\def boot_page_erase(address)
Erase the flash page that contains address.
\note address is a byte address in flash, not a word address. */
/** \ingroup avr_boot
\def boot_page_write(address)
Write the bootloader temporary page buffer
to flash page that contains address.
\note address is a byte address in flash, not a word address. */
/** \ingroup avr_boot
\def boot_rww_enable()
Enable the Read-While-Write memory section. */
/** \ingroup avr_boot
\def boot_lock_bits_set(lock_bits)
Set the bootloader lock bits. */
/* Normal versions of the macros use 16-bit addresses.
Extended versions of the macros use 32-bit addresses.
Alternate versions of the macros use 16-bit addresses and require special
instruction sequences after LPM.
FLASHEND is defined in the ioXXXX.h file.
USHRT_MAX is defined in <limits.h>. */
#if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \
|| defined(__AVR_ATmega323__)
/* Alternate: ATmega161/163/323 and 16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_alternate(address, data)
#define boot_page_erase(address) __boot_page_erase_alternate(address)
#define boot_page_write(address) __boot_page_write_alternate(address)
#define boot_rww_enable() __boot_rww_enable_alternate()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits)
#elif (FLASHEND > USHRT_MAX) && !defined(__USING_MINT8)
/* Extended: >16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_extended(address, data)
#define boot_page_erase(address) __boot_page_erase_extended(address)
#define boot_page_write(address) __boot_page_write_extended(address)
#define boot_rww_enable() __boot_rww_enable()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set(lock_bits)
#else
/* Normal: 16 bit address */
#define boot_page_fill(address, data) __boot_page_fill_normal(address, data)
#define boot_page_erase(address) __boot_page_erase_normal(address)
#define boot_page_write(address) __boot_page_write_normal(address)
#define boot_rww_enable() __boot_rww_enable()
#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set(lock_bits)
#endif
#define __boot_eeprom_spm_safe(func, address, data) \
do { \
boot_spm_busy_wait(); \
eeprom_busy_wait(); \
func (address, data); \
} while (0)
/** \ingroup avr_boot
Same as boot_page_fill() except it waits for eeprom and spm operations to
complete before filling the page. */
#define boot_page_fill_safe(address, data) \
__boot_eeprom_spm_safe (boot_page_fill, address, data)
/** \ingroup avr_boot
Same as boot_page_erase() except it waits for eeprom and spm operations to
complete before erasing the page. */
#define boot_page_erase_safe(address, data) \
__boot_eeprom_spm_safe (boot_page_erase, address, data)
/** \ingroup avr_boot
Same as boot_page_write() except it waits for eeprom and spm operations to
complete before writing the page. */
#define boot_page_write_safe(address, data) \
__boot_eeprom_spm_safe (boot_page_wrte, address, data)
/** \ingroup avr_boot
Same as boot_rww_enable() except waits for eeprom and spm operations to
complete before enabling the RWW mameory. */
#define boot_rww_enable_safe(address, data) \
__boot_eeprom_spm_safe (boot_rww_enable, address, data)
/** \ingroup avr_boot
Same as boot_lock_bits_set() except waits for eeprom and spm operations to
complete before setting the lock bits. */
#define boot_lock_bits_set_safe(address, data) \
__boot_eeprom_spm_safe (boot_lock_bits_set, address, data)
#endif /* _AVR_BOOT_H_ */

View File

@ -8,13 +8,17 @@
mthomas@rhrk.uni-kl.de mthomas@rhrk.uni-kl.de
eversmith@heizung-thomas.de eversmith@heizung-thomas.de
This is an adapted version which has been tested http://www.siwawi.arubi.uni-kl.de/avr_projects
with the ATmega16 but should work with the ATmega8,
ATmega169 and ATmega32. The bootloader uses block/
page write for flash and is fast.
====================================================== ======================================================
23. Feb. 2005 - Version 0.7
* (Version 0.6 has never been available on the web-page)
* ATmega128 support
* code cleanup
* Tested with ATmega8, ATmega32 and ATmega128
7. Apr. 2004 - Version 0.5 7. Apr. 2004 - Version 0.5
* added different startup-methods * added different startup-methods