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

334
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,174 +267,101 @@ 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
{ {
@ -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,8 +393,8 @@ 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();
@ -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
@ -515,7 +435,6 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem)
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
@ -537,9 +455,6 @@ unsigned char BufferLoad(unsigned int size, unsigned char mem)
} }
// 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;*/
} }

247
makefile
View File

@ -1,4 +1,6 @@
# WinAVR makefile written by Eric B. Weddington, Jörg Wunsch, et al. # Hey Emacs, this is a -*- makefile -*-
#
# WinAVR Sample makefile written by Eric B. Weddington, Jörg Wunsch, et al.
# Released to the Public Domain # Released to the Public Domain
# Please read the make user manual! # Please read the make user manual!
# #
@ -32,7 +34,9 @@
# MCU name # MCU name
## MCU = atmega16 ## MCU = atmega16
MCU = atmega8 ## MCU = atmega8
MCU = atmega32
## MCU = atmega128
################## 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
@ -43,8 +47,15 @@ MCU = atmega8
# 0x1C00*2=0x3800 for ATmega16 1024 words Boot Size # 0x1C00*2=0x3800 for ATmega16 1024 words Boot Size
## MT_BOOTLOADER_ADDRESS = 3800 ## MT_BOOTLOADER_ADDRESS = 3800
# 0x0C00*2=0x1800 for ATmega8 1024 words Boot Size # 0x0C00*2=0x1800 for ATmega8 1024 words Boot Size
MT_BOOTLOADER_ADDRESS = 1800 ## MT_BOOTLOADER_ADDRESS = 1800
# 0x3C00*2=0x7800 for ATmega32 1024 words Boot Size
MT_BOOTLOADER_ADDRESS = 7800
# 0xFC00*2=0x1F800 for ATmega128 1024 words Boot Size
##MT_BOOTLOADER_ADDRESS = 1F800
# Output format. (can be srec, ihex, binary) # Output format. (can be srec, ihex, binary)
@ -53,22 +64,10 @@ FORMAT = ihex
# Target file name (without extension). # Target file name (without extension).
TARGET = main TARGET = main
# 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.)
OPT = s
# List C source files here. (C dependencies are automatically generated.) # List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c SRC = $(TARGET).c uart.c lowlevel.c
# If there is more than one source file, append them above, or modify and
# uncomment the following:
# mt: the file test.c can be omitted (remove #inc test.h and test() in main.c)
SRC += uart.c lowlevel.c
# You can also wrap lines by appending a backslash to the end of the line:
#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
@ -80,35 +79,55 @@ SRC += uart.c lowlevel.c
ASRC = ASRC =
# Optimization level, can be [0, 1, 2, 3, s].
# 0 = turn off optimization. s = optimize for size.
# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s
# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
DEBUG = stabs
# List any extra directories to look for include files here. # List any extra directories to look for include files here.
# Each directory must be seperated by a space. # Each directory must be seperated by a space.
EXTRAINCDIRS = EXTRAINCDIRS =
# Optional compiler flags. # Compiler flag to set the C Standard level.
# -g: generate debugging information (for GDB, or for COFF conversion) # c89 - "ANSI" C
# -O*: optimization level # gnu89 - c89 plus GCC extensions
# -f...: tuning, see gcc manual and avr-libc documentation # c99 - ISO C99 standard (not yet fully implemented)
# -Wall...: warning level # gnu99 - c99 plus GCC extensions
# -Wa,...: tell GCC to pass this to the assembler. CSTANDARD = -std=gnu99
# -ahlms: create assembler listing
CFLAGS = -g -O$(OPT) \ # Place -D or -U options here
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ CDEFS =
-Wall -Wstrict-prototypes \
-Wa,-adhlns=$(<:.c=.lst) \ # Place -I options here
$(patsubst %,-I%,$(EXTRAINCDIRS)) CINCS =
# Set a "language standard" compiler flag. # Compiler flags.
# Unremark just one line below to set the language standard to use. # -g*: generate debugging information
# gnu99 = C99 + GNU extensions. See GCC manual for more information. # -O*: optimization level
#CFLAGS += -std=c89 # -f...: tuning, see GCC manual and avr-libc documentation
#CFLAGS += -std=gnu89 # -Wall...: warning level
#CFLAGS += -std=c99 # -Wa,...: tell GCC to pass this to the assembler.
CFLAGS += -std=gnu99 # -adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS) $(CINCS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -Wall -Wstrict-prototypes
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)
# Optional assembler flags.
# Assembler flags.
# -Wa,...: tell GCC to pass this to the assembler. # -Wa,...: tell GCC to pass this to the assembler.
# -ahlms: create listing # -ahlms: create listing
# -gstabs: have the assembler create line number information; note that # -gstabs: have the assembler create line number information; note that
@ -119,28 +138,53 @@ ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
# Optional linker flags. #Additional libraries.
# -Wl,...: tell GCC to pass this to linker.
# -Map: create map file
# --cref: add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
# Additional libraries
# Minimalistic printf version # Minimalistic printf version
#LDFLAGS += -Wl,-u,vfprintf -lprintf_min PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires -lm below) # Floating point printf version (requires MATH_LIB = -lm below)
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# -lm = math library PRINTF_LIB =
LDFLAGS += -lm
# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
SCANF_LIB =
MATH_LIB = -lm
# External memory options
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =
# Linker flags.
# -Wl,...: tell GCC to pass this to linker.
# -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 ###################### ################## BOOTLOADER ######################
# MT_BOOTLOADER_ADDRESS (=Start of Boot Loader section # MT_BOOTLOADER_ADDRESS (=Start of Boot Loader section
# in bytes - not words) is defined above. # in bytes - not words) is defined above.
LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS) LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
# Programming support using avrdude. Settings and variables. # Programming support using avrdude. Settings and variables.
# Programming hardware: alf avr910 avrisp bascom bsd # Programming hardware: alf avr910 avrisp bascom bsd
@ -149,31 +193,33 @@ LDFLAGS += -Wl,--section-start=.text=$(MT_BOOTLOADER_ADDRESS)
# Type: avrdude -c ? # Type: avrdude -c ?
# to get a full listing. # to get a full listing.
# #
AVRDUDE_PROGRAMMER = stk500 AVRDUDE_PROGRAMMER = stk500v2
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = com1 # programmer connected to serial device AVRDUDE_PORT = com1 # programmer connected to serial device
#AVRDUDE_PORT = lpt1 # programmer connected to parallel port
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
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
# Uncomment the following if you want avrdude's erase cycle counter. # Uncomment the following if you want avrdude's erase cycle counter.
# Note that this counter needs to be initialized first using -Yn, # Note that this counter needs to be initialized first using -Yn,
# see avrdude manual. # see avrdude manual.
#AVRDUDE_ERASE += -y #AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be # Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device. # performed after programming the device.
#AVRDUDE_FLAGS += -V #AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug # Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> # reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports. # to submit bug reports.
#AVRDUDE_FLAGS += -v -v #AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
@ -189,24 +235,16 @@ DIRLIB = $(DIRAVR)/avr/lib
# Define programs and commands. # Define programs and commands.
SHELL = sh SHELL = sh
CC = avr-gcc CC = avr-gcc
OBJCOPY = avr-objcopy OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump OBJDUMP = avr-objdump
SIZE = avr-size SIZE = avr-size
NM = avr-nm
# Programming support using avrdude.
AVRDUDE = avrdude AVRDUDE = avrdude
REMOVE = rm -f REMOVE = rm -f
COPY = cp COPY = cp
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
#mt - use hexadezimal output-fromat // org: ELFSIZE = $(SIZE) -A $(TARGET).elf
ELFSIZE = $(SIZE) -x -A $(TARGET).elf
# Define Messages # Define Messages
@ -236,16 +274,31 @@ OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)
# Define all listing files. # Define all listing files.
LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)
# Compiler flags to generate dependency files.
### GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
# Combine all necessary flags and optional flags. # Combine all necessary flags and optional flags.
# Add target processor to flags. # Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
# Default target. # Default target.
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ all: begin gccversion sizebefore build sizeafter finished end
$(TARGET).lss $(TARGET).sym sizeafter finished end
build: elf hex eep lss sym
elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
# Eye candy. # Eye candy.
@ -264,6 +317,8 @@ end:
# Display size of file. # Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) -x -A $(TARGET).elf
sizebefore: sizebefore:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi
@ -278,14 +333,19 @@ gccversion :
# 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.
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \ COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \ --change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \ --change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \ --change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000 --change-section-address .eeprom-0x810000
coff: $(TARGET).elf coff: $(TARGET).elf
@ -301,14 +361,6 @@ extcoff: $(TARGET).elf
# Program the device.
program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
# Create final output files (.hex, .eep) from ELF output file. # Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf %.hex: %.elf
@echo @echo
@ -331,7 +383,7 @@ program: $(TARGET).hex $(TARGET).eep
%.sym: %.elf %.sym: %.elf
@echo @echo
@echo $(MSG_SYMBOL_TABLE) $@ @echo $(MSG_SYMBOL_TABLE) $@
avr-nm -n $< > $@ $(NM) -n $< > $@
@ -364,9 +416,6 @@ program: $(TARGET).hex $(TARGET).eep
# Target: clean project. # Target: clean project.
clean: begin clean_list finished end clean: begin clean_list finished end
@ -388,28 +437,16 @@ clean_list :
$(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).)
#
# 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.
#
%.d: %.c
set -e; $(CC) -MM $(ALL_CFLAGS) $< \
| 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)
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets. # Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ .PHONY : all begin finish end sizebefore sizeafter gccversion \
clean clean_list program build elf hex eep lss sym 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