1 /* Name: spminterface.h
2 * Project: USBaspLoader
3 * Author: Stephan Baerwolf
4 * Creation Date: 2012-08-01
5 * Copyright: (c) 2012 by Stephan Baerwolf
6 * License: GNU GPL v2 (see License.txt)
9 #ifndef SPMINTERFACE_H_f70ba6adf7624275947e859bdbff0599
10 #define SPMINTERFACE_H_f70ba6adf7624275947e859bdbff0599
13 * spminterface.h offers a lightweight interface by inserting
14 * an small machine-subroutine into the bootsection. (right
15 * after the interrupt-vector-table)
16 * This subroutine can be called by normal code in order to
17 * enable it to program the flash (and depending on BLB11-lockbit
18 * also the bootsection itself). Since SPM-calls from RWW-sections
19 * will fail to work. The Routine will be called "bootloader__do_spm".
20 * Its principle assembler-code is depicted below (real code is a
21 * little machinedependen).
22 * Interfaces will be the 8-bit registers r10..r13, for details
23 * also see below. As also the pageaddress-registes (Z and rampZ)
24 * are interfaced via different registers, it is possible to call
25 * this routine via indirect call (icall).
26 * Traditionally it is also possible to rcall, therefore you can
27 * define "bootloader__do_spm" for your normal code via defsym at
29 * Example for an atmega8: "-Wl,--defsym=transfer_point=0x1826"
30 * (since BOOTLOADER_ADDRESS is 0x1800 and there are
31 * 2x19 = 38 = 0x26 byte for interrupts)
35 ;disable interrupts (if enabled) before calling!
36 ;you may also want to disable wdt, since this routine may busy-loop
37 ;==================================================================
39 ;spmcr (spmcrval determines SPM action) will be register: r10
40 ;MCU dependend RA(MPZ should be transfered within register: r11
41 ;lo8(Z) should be transfered within register: r12
42 ;hi8(Z) should be transfered within register: r13
45 ;temp0 will be register: r11
46 ;temp1 will be register: r12
47 ;temp2 will be register: r13
48 ;Z (r31:r30) wil be changed during operation
51 ;==================================================================
53 ;load pageaddress (Z) from r13:12 since it may was used for icall
58 wait: ;check for previous SPM complete
63 out SPMCR, spmcrval ;SPM timed sequence
72 #include <avr/pgmspace.h>
74 #ifndef BOOTLOADER_ADDRESS
75 // this header is the interface for user-code
80 #else /*ifndef BOOTLOADER_ADDRESS*/
81 // this header is used directly within bootloader_do_spm
82 #include "bootloaderconfig.h"
84 #if HAVE_SPMINTEREFACE
88 * insert architecture dependend "bootloader_do_spm"-code
90 * try to make this array as big as possible
91 * (so bootloader always uses 2kbytes flash)
93 #if defined (__AVR_ATmega8__) || defined (__AVR_ATmega8HVA__)
94 //assume SPMCR==0x37, SPMEN==0x00
95 const uint16_t bootloader__do_spm
[22] PROGMEM
= {0x0000, 0x2dec, 0x2dfd, 0xb6c7, 0xfcc0, 0xcffd, 0xbea7, 0x95e8, 0x9508,
96 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
97 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
99 #error "bootloader__do_spm has to be adapted, since there is no architecture code, yet"
104 #endif /*ifdef BOOTLOADER_ADDRESS*/