Version 0.7 (20050226)
This commit is contained in:
parent
f32c7e3131
commit
f2c227f428
1
avrprog_boot.pnproj
Normal file
1
avrprog_boot.pnproj
Normal 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>
|
93
bin/avrprog_boot_mega32_3_6MHz.hex
Normal file
93
bin/avrprog_boot_mega32_3_6MHz.hex
Normal 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
|
37
chipdef.h
37
chipdef.h
@ -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
|
||||||
|
|
||||||
|
37
lowlevel.c
37
lowlevel.c
@ -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;
|
||||||
|
@ -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
|
||||||
|
214
main.c
214
main.c
@ -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,13 +151,15 @@ 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
|
||||||
|
|
||||||
@ -174,14 +173,15 @@ 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
|
||||||
@ -190,7 +190,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
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
|
||||||
{
|
{
|
||||||
@ -206,11 +206,13 @@ int main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#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
|
||||||
@ -218,6 +220,7 @@ int main(void)
|
|||||||
|
|
||||||
#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
|
||||||
@ -236,7 +239,7 @@ int main(void)
|
|||||||
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');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,51 +267,33 @@ 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); // Perform page erase
|
||||||
boot_page_erase(address);
|
|
||||||
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)
|
||||||
@ -321,19 +306,6 @@ int main(void)
|
|||||||
}
|
}
|
||||||
#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');
|
||||||
@ -344,73 +316,31 @@ int main(void)
|
|||||||
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
|
||||||
@ -427,7 +357,7 @@ int main(void)
|
|||||||
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');
|
||||||
@ -451,7 +381,7 @@ int main(void)
|
|||||||
sendchar(sig_byte3);
|
sendchar(sig_byte3);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(val!=0x1b) // if not esc
|
else if(val != 0x1b) /* ESC */
|
||||||
{
|
{
|
||||||
sendchar('?');
|
sendchar('?');
|
||||||
}
|
}
|
||||||
@ -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;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
231
makefile
231
makefile
@ -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
|
||||||
|
# gnu89 - c89 plus GCC extensions
|
||||||
|
# c99 - ISO C99 standard (not yet fully implemented)
|
||||||
|
# gnu99 - c99 plus GCC extensions
|
||||||
|
CSTANDARD = -std=gnu99
|
||||||
|
|
||||||
|
# Place -D or -U options here
|
||||||
|
CDEFS =
|
||||||
|
|
||||||
|
# Place -I options here
|
||||||
|
CINCS =
|
||||||
|
|
||||||
|
|
||||||
|
# Compiler flags.
|
||||||
|
# -g*: generate debugging information
|
||||||
# -O*: optimization level
|
# -O*: optimization level
|
||||||
# -f...: tuning, see gcc manual and avr-libc documentation
|
# -f...: tuning, see GCC manual and avr-libc documentation
|
||||||
# -Wall...: warning level
|
# -Wall...: warning level
|
||||||
# -Wa,...: tell GCC to pass this to the assembler.
|
# -Wa,...: tell GCC to pass this to the assembler.
|
||||||
# -ahlms: create assembler listing
|
# -adhlns...: create assembler listing
|
||||||
CFLAGS = -g -O$(OPT) \
|
CFLAGS = -g$(DEBUG)
|
||||||
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \
|
CFLAGS += $(CDEFS) $(CINCS)
|
||||||
-Wall -Wstrict-prototypes \
|
CFLAGS += -O$(OPT)
|
||||||
-Wa,-adhlns=$(<:.c=.lst) \
|
CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
|
||||||
$(patsubst %,-I%,$(EXTRAINCDIRS))
|
CFLAGS += -Wall -Wstrict-prototypes
|
||||||
|
CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
|
||||||
|
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||||
|
CFLAGS += $(CSTANDARD)
|
||||||
|
|
||||||
|
|
||||||
# Set a "language standard" compiler flag.
|
|
||||||
# Unremark just one line below to set the language standard to use.
|
|
||||||
# gnu99 = C99 + GNU extensions. See GCC manual for more information.
|
|
||||||
#CFLAGS += -std=c89
|
|
||||||
#CFLAGS += -std=gnu89
|
|
||||||
#CFLAGS += -std=c99
|
|
||||||
CFLAGS += -std=gnu99
|
|
||||||
|
|
||||||
|
# Assembler flags.
|
||||||
# Optional 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.
|
||||||
|
|
||||||
|
# Minimalistic printf version
|
||||||
|
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
|
||||||
|
|
||||||
|
# Floating point printf version (requires MATH_LIB = -lm below)
|
||||||
|
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
|
||||||
|
|
||||||
|
PRINTF_LIB =
|
||||||
|
|
||||||
|
# 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.
|
# -Wl,...: tell GCC to pass this to linker.
|
||||||
# -Map: create map file
|
# -Map: create map file
|
||||||
# --cref: add cross reference to map file
|
# --cref: add cross reference to map file
|
||||||
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
|
||||||
|
LDFLAGS += $(EXTMEMOPTS)
|
||||||
# Additional libraries
|
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
|
||||||
|
|
||||||
# Minimalistic printf version
|
|
||||||
#LDFLAGS += -Wl,-u,vfprintf -lprintf_min
|
|
||||||
|
|
||||||
# Floating point printf version (requires -lm below)
|
|
||||||
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt
|
|
||||||
|
|
||||||
# -lm = math library
|
|
||||||
LDFLAGS += -lm
|
|
||||||
|
|
||||||
################## 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,9 +333,14 @@ 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 \
|
||||||
@ -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 \
|
||||||
|
build elf hex eep lss sym coff extcoff \
|
||||||
clean clean_list program
|
clean clean_list program
|
||||||
|
|
||||||
|
520
myboot.h
520
myboot.h
@ -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_ */
|
|
12
readme.txt
12
readme.txt
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user