2 AVRUSBBoot - USB bootloader for Atmel AVR controllers
4 Thomas Fischl <tfischl@gmx.de>
7 The project is built with AVR USB driver by Objective Development, which is
8 published under a proprietary Open Source license. To conform with this
9 license, USBasp is distributed under the same license conditions. See
12 Target.........: ATMega8 at 12 MHz
13 Creation Date..: 2006-03-18
14 Last change....: 2006-06-25
16 To adapt the bootloader to your hardware, you have to modify the following files:
18 Define the condition when the bootloader should be started
20 Define the used data line pins. You have to adapt USB_CFG_IOPORT, USB_CFG_DMINUS_BIT and
21 USB_CFG_DPLUS_BIT to your hardware. The rest should be left unchanged.
25 #include <avr/signal.h>
26 #include <avr/interrupt.h>
27 #include <avr/pgmspace.h>
32 #include "bootloaderconfig.h"
34 #define USBBOOT_FUNC_WRITE_PAGE 2
35 #define USBBOOT_FUNC_LEAVE_BOOT 1
36 q#define USBBOOT_FUNC_GET_PAGESIZE 3
39 #define STATE_WRITE_PAGE 1
41 static uchar replyBuffer[8];
42 static uchar state = STATE_IDLE;
43 static unsigned int page_address;
44 static unsigned int page_offset;
46 void (*jump_to_app)(void) = 0x0000;
48 void leaveBootloader() {
51 GICR = (1 << IVCE); /* enable change of interrupt vectors */
52 GICR = (0 << IVSEL); /* move interrupts to application flash section */
56 uchar usbFunctionSetup(uchar data[8])
60 if (data[1] == USBBOOT_FUNC_LEAVE_BOOT) {
62 } else if (data[1] == USBBOOT_FUNC_WRITE_PAGE) {
64 state = STATE_WRITE_PAGE;
66 page_address = (data[3] << 8) | data[2]; /* page address */
71 boot_page_erase(page_address); /* erase page */
73 boot_spm_busy_wait(); /* wait until page is erased */
75 len = 0xff; /* multiple out */
77 } else if (data[1] == USBBOOT_FUNC_GET_PAGESIZE) {
79 replyBuffer[0] = SPM_PAGESIZE >> 8;
80 replyBuffer[1] = SPM_PAGESIZE & 0xff;
85 usbMsgPtr = replyBuffer;
91 uchar usbFunctionWrite(uchar *data, uchar len)
96 /* check if we are in correct state */
97 if (state != STATE_WRITE_PAGE)
100 for (i = 0; i < len; i+=2) {
103 boot_page_fill(page_address + page_offset, data[i] | (data[i + 1] << 8));
107 /* check if we are at the end of a page */
108 if (page_offset >= SPM_PAGESIZE) {
112 boot_page_write(page_address);
114 boot_spm_busy_wait();
127 /* initialize hardware */
130 /* jump to application if jumper is set */
131 if (!BOOTLOADER_CONDITION) {
135 GICR = (1 << IVCE); /* enable change of interrupt vectors */
136 GICR = (1 << IVSEL); /* move interrupts to boot flash section */
140 for(;;){ /* main event loop */