Merge branch 'master' of ssh://repo.or.cz/srv/git/ctl24
[ctl24.git] / avrusbboot.2006-06-25 / firmware / #main.c#
blob1f24af50f90f30917d659ef37886339af5ea9c3f
1 /*
2   AVRUSBBoot - USB bootloader for Atmel AVR controllers
4   Thomas Fischl <tfischl@gmx.de>
6   License:
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
10   documentation.
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:
17   - bootloaderconfig.h:
18     Define the condition when the bootloader should be started
19   - usbconfig.h:
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.
24 #include <avr/io.h>
25 #include <avr/signal.h>
26 #include <avr/interrupt.h>
27 #include <avr/pgmspace.h>
28 #include <avr/wdt.h>
29 #include <avr/boot.h>
31 #include "usbdrv.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
38 #define STATE_IDLE 0
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() {
49       cli();
50       boot_rww_enable();
51       GICR = (1 << IVCE);  /* enable change of interrupt vectors */
52       GICR = (0 << IVSEL); /* move interrupts to application flash section */
53       jump_to_app();
56 uchar   usbFunctionSetup(uchar data[8])
58     uchar len = 0;
59     
60     if (data[1] == USBBOOT_FUNC_LEAVE_BOOT) {
61       leaveBootloader();
62     } else if (data[1] == USBBOOT_FUNC_WRITE_PAGE) {
64       state = STATE_WRITE_PAGE;
66       page_address = (data[3] << 8) | data[2]; /* page address */
67       page_offset = 0;
69       eeprom_busy_wait();
70       cli();
71       boot_page_erase(page_address); /* erase page */
72       sei();
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;
81       len = 2;
83     }
85     usbMsgPtr = replyBuffer;
87     return len;
91 uchar usbFunctionWrite(uchar *data, uchar len)
94   uchar i;
96   /* check if we are in correct state */
97   if (state != STATE_WRITE_PAGE)
98     return 0xff;
99   
100   for (i = 0; i < len; i+=2) {
102     cli();    
103     boot_page_fill(page_address + page_offset, data[i] | (data[i + 1] << 8));
104     sei();
105     page_offset += 2;
107     /* check if we are at the end of a page */
108     if (page_offset >= SPM_PAGESIZE) {
109       
110       /* write page */
111       cli();
112       boot_page_write(page_address);
113       sei();
114       boot_spm_busy_wait();
116       state = STATE_IDLE;
117       return 1;
118     }
120   }
121   
122   return 0;
125 int main(void)
127     /* initialize hardware */
128     BOOTLOADER_INIT;
130     /* jump to application if jumper is set */
131     if (!BOOTLOADER_CONDITION) {
132       leaveBootloader();
133     }
135     GICR = (1 << IVCE);  /* enable change of interrupt vectors */
136     GICR = (1 << IVSEL); /* move interrupts to boot flash section */
138     usbInit();
139     sei();
140     for(;;){    /* main event loop */
141         usbPoll();
142     }
143     return 0;