|
1 /**********************************************************/ |
|
2 /* Serial Bootloader for Atmel megaAVR Controllers */ |
|
3 /* */ |
|
4 /* tested with ATmega8, ATmega128 and ATmega168 */ |
|
5 /* should work with other mega's, see code for details */ |
|
6 /* */ |
|
7 /* ATmegaBOOT.c */ |
|
8 /* */ |
|
9 /* */ |
|
10 /* 20090308: integrated Mega changes into main bootloader */ |
|
11 /* source by D. Mellis */ |
|
12 /* 20080930: hacked for Arduino Mega (with the 1280 */ |
|
13 /* processor, backwards compatible) */ |
|
14 /* by D. Cuartielles */ |
|
15 /* 20070626: hacked for Arduino Diecimila (which auto- */ |
|
16 /* resets when a USB connection is made to it) */ |
|
17 /* by D. Mellis */ |
|
18 /* 20060802: hacked for Arduino by D. Cuartielles */ |
|
19 /* based on a previous hack by D. Mellis */ |
|
20 /* and D. Cuartielles */ |
|
21 /* */ |
|
22 /* Monitor and debug functions were added to the original */ |
|
23 /* code by Dr. Erik Lins, chip45.com. (See below) */ |
|
24 /* */ |
|
25 /* Thanks to Karl Pitrich for fixing a bootloader pin */ |
|
26 /* problem and more informative LED blinking! */ |
|
27 /* */ |
|
28 /* For the latest version see: */ |
|
29 /* http://www.chip45.com/ */ |
|
30 /* */ |
|
31 /* ------------------------------------------------------ */ |
|
32 /* */ |
|
33 /* based on stk500boot.c */ |
|
34 /* Copyright (c) 2003, Jason P. Kyle */ |
|
35 /* All rights reserved. */ |
|
36 /* see avr1.org for original file and information */ |
|
37 /* */ |
|
38 /* This program is free software; you can redistribute it */ |
|
39 /* and/or modify it under the terms of the GNU General */ |
|
40 /* Public License as published by the Free Software */ |
|
41 /* Foundation; either version 2 of the License, or */ |
|
42 /* (at your option) any later version. */ |
|
43 /* */ |
|
44 /* This program is distributed in the hope that it will */ |
|
45 /* be useful, but WITHOUT ANY WARRANTY; without even the */ |
|
46 /* implied warranty of MERCHANTABILITY or FITNESS FOR A */ |
|
47 /* PARTICULAR PURPOSE. See the GNU General Public */ |
|
48 /* License for more details. */ |
|
49 /* */ |
|
50 /* You should have received a copy of the GNU General */ |
|
51 /* Public License along with this program; if not, write */ |
|
52 /* to the Free Software Foundation, Inc., */ |
|
53 /* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
|
54 /* */ |
|
55 /* Licence can be viewed at */ |
|
56 /* http://www.fsf.org/licenses/gpl.txt */ |
|
57 /* */ |
|
58 /* Target = Atmel AVR m128,m64,m32,m16,m8,m162,m163,m169, */ |
|
59 /* m8515,m8535. ATmega161 has a very small boot block so */ |
|
60 /* isn't supported. */ |
|
61 /* */ |
|
62 /* Tested with m168 */ |
|
63 /**********************************************************/ |
|
64 |
|
65 /* $Id$ */ |
|
66 |
|
67 |
|
68 /* some includes */ |
|
69 #include <inttypes.h> |
|
70 #include <avr/io.h> |
|
71 #include <avr/pgmspace.h> |
|
72 #include <avr/interrupt.h> |
|
73 #include <avr/wdt.h> |
|
74 #include <util/delay.h> |
|
75 |
|
76 /* the current avr-libc eeprom functions do not support the ATmega168 */ |
|
77 /* own eeprom write/read functions are used instead */ |
|
78 #if !defined(__AVR_ATmega168__) || !defined(__AVR_ATmega328P__) |
|
79 #include <avr/eeprom.h> |
|
80 #endif |
|
81 |
|
82 /* Use the F_CPU defined in Makefile */ |
|
83 |
|
84 /* 20060803: hacked by DojoCorp */ |
|
85 /* 20070626: hacked by David A. Mellis to decrease waiting time for auto-reset */ |
|
86 /* set the waiting time for the bootloader */ |
|
87 /* get this from the Makefile instead */ |
|
88 /* #define MAX_TIME_COUNT (F_CPU>>4) */ |
|
89 |
|
90 /* 20070707: hacked by David A. Mellis - after this many errors give up and launch application */ |
|
91 #define MAX_ERROR_COUNT 5 |
|
92 #define NUM_LED_FLASHES 3 |
|
93 /* set the UART baud rate */ |
|
94 /* 20060803: hacked by DojoCorp */ |
|
95 //#define BAUD_RATE 115200 |
|
96 #ifndef BAUD_RATE |
|
97 #define BAUD_RATE 19200 |
|
98 #endif |
|
99 |
|
100 |
|
101 /* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */ |
|
102 /* never allow AVR Studio to do an update !!!! */ |
|
103 #define HW_VER 0x02 |
|
104 #define SW_MAJOR 0x01 |
|
105 #define SW_MINOR 0x10 |
|
106 |
|
107 |
|
108 /* Adjust to suit whatever pin your hardware uses to enter the bootloader */ |
|
109 /* ATmega128 has two UARTS so two pins are used to enter bootloader and select UART */ |
|
110 /* ATmega1280 has four UARTS, but for Arduino Mega, we will only use RXD0 to get code */ |
|
111 /* BL0... means UART0, BL1... means UART1 */ |
|
112 #ifdef __AVR_ATmega128__ |
|
113 #define BL_DDR DDRF |
|
114 #define BL_PORT PORTF |
|
115 #define BL_PIN PINF |
|
116 #define BL0 PINF7 |
|
117 #define BL1 PINF6 |
|
118 #elif defined __AVR_ATmega1280__ |
|
119 /* we just don't do anything for the MEGA and enter bootloader on reset anyway*/ |
|
120 #elif defined __AVR_ATmega1284P__ |
|
121 |
|
122 #else |
|
123 /* other ATmegas have only one UART, so only one pin is defined to enter bootloader */ |
|
124 #define BL_DDR DDRD |
|
125 #define BL_PORT PORTD |
|
126 #define BL_PIN PIND |
|
127 #define BL PIND6 |
|
128 #endif |
|
129 |
|
130 |
|
131 /* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */ |
|
132 /* if monitor functions are included, LED goes on after monitor was entered */ |
|
133 #if defined __AVR_ATmega128__ || defined __AVR_ATmega1280__ |
|
134 /* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128, Arduino Mega) */ |
|
135 #define LED_DDR DDRB |
|
136 #define LED_PORT PORTB |
|
137 #define LED_PIN PINB |
|
138 #define LED PINB7 |
|
139 #elif defined __AVR_ATmega1284P__ |
|
140 #define LED_DDR DDRB |
|
141 #define LED_PORT PORTB |
|
142 #define LED_PIN PINB |
|
143 #define LED PINB0 |
|
144 #else |
|
145 /* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duomilanuove */ |
|
146 /* other boards like e.g. Crumb8, Crumb168 are using PB2 */ |
|
147 #define LED_DDR DDRB |
|
148 #define LED_PORT PORTB |
|
149 #define LED_PIN PINB |
|
150 #define LED PINB5 |
|
151 #endif |
|
152 |
|
153 |
|
154 /* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */ |
|
155 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) |
|
156 #define MONITOR 1 |
|
157 #endif |
|
158 |
|
159 |
|
160 /* define various device id's */ |
|
161 /* manufacturer byte is always the same */ |
|
162 #define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :( |
|
163 |
|
164 #if defined __AVR_ATmega1280__ |
|
165 #define SIG2 0x97 |
|
166 #define SIG3 0x03 |
|
167 #define PAGE_SIZE 0x80U //128 words |
|
168 |
|
169 #elif defined __AVR_ATmega1284P__ |
|
170 #define SIG2 0x97 |
|
171 #define SIG3 0x05 |
|
172 #define PAGE_SIZE 0x080U //128 words |
|
173 |
|
174 #elif defined __AVR_ATmega1281__ |
|
175 #define SIG2 0x97 |
|
176 #define SIG3 0x04 |
|
177 #define PAGE_SIZE 0x80U //128 words |
|
178 |
|
179 #elif defined __AVR_ATmega128__ |
|
180 #define SIG2 0x97 |
|
181 #define SIG3 0x02 |
|
182 #define PAGE_SIZE 0x80U //128 words |
|
183 |
|
184 #elif defined __AVR_ATmega64__ |
|
185 #define SIG2 0x96 |
|
186 #define SIG3 0x02 |
|
187 #define PAGE_SIZE 0x80U //128 words |
|
188 |
|
189 #elif defined __AVR_ATmega32__ |
|
190 #define SIG2 0x95 |
|
191 #define SIG3 0x02 |
|
192 #define PAGE_SIZE 0x40U //64 words |
|
193 |
|
194 #elif defined __AVR_ATmega16__ |
|
195 #define SIG2 0x94 |
|
196 #define SIG3 0x03 |
|
197 #define PAGE_SIZE 0x40U //64 words |
|
198 |
|
199 #elif defined __AVR_ATmega8__ |
|
200 #define SIG2 0x93 |
|
201 #define SIG3 0x07 |
|
202 #define PAGE_SIZE 0x20U //32 words |
|
203 |
|
204 #elif defined __AVR_ATmega88__ |
|
205 #define SIG2 0x93 |
|
206 #define SIG3 0x0a |
|
207 #define PAGE_SIZE 0x20U //32 words |
|
208 |
|
209 #elif defined __AVR_ATmega168__ |
|
210 #define SIG2 0x94 |
|
211 #define SIG3 0x06 |
|
212 #define PAGE_SIZE 0x40U //64 words |
|
213 |
|
214 #elif defined __AVR_ATmega328P__ |
|
215 #define SIG2 0x95 |
|
216 #define SIG3 0x0F |
|
217 #define PAGE_SIZE 0x40U //64 words |
|
218 |
|
219 #elif defined __AVR_ATmega162__ |
|
220 #define SIG2 0x94 |
|
221 #define SIG3 0x04 |
|
222 #define PAGE_SIZE 0x40U //64 words |
|
223 |
|
224 #elif defined __AVR_ATmega163__ |
|
225 #define SIG2 0x94 |
|
226 #define SIG3 0x02 |
|
227 #define PAGE_SIZE 0x40U //64 words |
|
228 |
|
229 #elif defined __AVR_ATmega169__ |
|
230 #define SIG2 0x94 |
|
231 #define SIG3 0x05 |
|
232 #define PAGE_SIZE 0x40U //64 words |
|
233 |
|
234 #elif defined __AVR_ATmega8515__ |
|
235 #define SIG2 0x93 |
|
236 #define SIG3 0x06 |
|
237 #define PAGE_SIZE 0x20U //32 words |
|
238 |
|
239 #elif defined __AVR_ATmega8535__ |
|
240 #define SIG2 0x93 |
|
241 #define SIG3 0x08 |
|
242 #define PAGE_SIZE 0x20U //32 words |
|
243 #endif |
|
244 |
|
245 |
|
246 /* function prototypes */ |
|
247 void putch(char); |
|
248 char getch(void); |
|
249 void getNch(uint8_t); |
|
250 void byte_response(uint8_t); |
|
251 void nothing_response(void); |
|
252 char gethex(void); |
|
253 void puthex(char); |
|
254 void flash_led(uint8_t); |
|
255 |
|
256 /* some variables */ |
|
257 union address_union |
|
258 { |
|
259 uint16_t word; |
|
260 uint8_t byte[2]; |
|
261 } address; |
|
262 |
|
263 union length_union |
|
264 { |
|
265 uint16_t word; |
|
266 uint8_t byte[2]; |
|
267 } length; |
|
268 |
|
269 struct flags_struct |
|
270 { |
|
271 unsigned eeprom : 1; |
|
272 unsigned rampz : 1; |
|
273 } flags; |
|
274 |
|
275 uint8_t buff[256]; |
|
276 uint8_t address_high; |
|
277 |
|
278 uint8_t pagesz=0x80; |
|
279 |
|
280 uint8_t i; |
|
281 uint8_t bootuart = 0; |
|
282 |
|
283 uint8_t error_count = 0; |
|
284 |
|
285 void (*app_start)(void) = 0x0000; |
|
286 |
|
287 |
|
288 /* main program starts here */ |
|
289 int main(void) |
|
290 { |
|
291 uint8_t ch,ch2; |
|
292 uint16_t w; |
|
293 #ifdef WATCHDOG_MODS |
|
294 ch = MCUSR; |
|
295 MCUSR = 0; |
|
296 WDTCSR |= _BV(WDCE) | _BV(WDE); |
|
297 WDTCSR = 0; |
|
298 // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot. |
|
299 if (! (ch & _BV(EXTRF))) // if its a not an external reset... |
|
300 app_start(); // skip bootloader |
|
301 #else |
|
302 asm volatile("nop\n\t"); |
|
303 #endif |
|
304 /* set pin direction for bootloader pin and enable pullup */ |
|
305 /* for ATmega128, two pins need to be initialized */ |
|
306 #ifdef __AVR_ATmega128__ |
|
307 BL_DDR &= ~_BV(BL0); |
|
308 BL_DDR &= ~_BV(BL1); |
|
309 BL_PORT |= _BV(BL0); |
|
310 BL_PORT |= _BV(BL1); |
|
311 #else |
|
312 /* We run the bootloader regardless of the state of this pin. Thus, don't |
|
313 put it in a different state than the other pins. --DAM, 070709 |
|
314 This also applies to Arduino Mega -- DC, 080930 |
|
315 BL_DDR &= ~_BV(BL); |
|
316 BL_PORT |= _BV(BL); |
|
317 */ |
|
318 #endif |
|
319 #ifdef __AVR_ATmega128__ |
|
320 /* check which UART should be used for booting */ |
|
321 if(bit_is_clear(BL_PIN, BL0)) |
|
322 { |
|
323 bootuart = 1; |
|
324 } |
|
325 else if(bit_is_clear(BL_PIN, BL1)) |
|
326 { |
|
327 bootuart = 2; |
|
328 } |
|
329 #endif |
|
330 #if defined __AVR_ATmega1280__ || defined __AVR_ATmega1284P__ |
|
331 /* the mega1280 chip has four serial ports ... we could eventually use any of them, or not? */ |
|
332 /* however, we don't wanna confuse people, to avoid making a mess, we will stick to RXD0, TXD0 */ |
|
333 bootuart = 1; |
|
334 #endif |
|
335 /* check if flash is programmed already, if not start bootloader anyway */ |
|
336 if(pgm_read_byte_near(0x0000) != 0xFF) |
|
337 { |
|
338 #ifdef __AVR_ATmega128__ |
|
339 /* no UART was selected, start application */ |
|
340 if(!bootuart) |
|
341 { |
|
342 app_start(); |
|
343 } |
|
344 #else |
|
345 /* check if bootloader pin is set low */ |
|
346 /* we don't start this part neither for the m8, nor m168 */ |
|
347 //if(bit_is_set(BL_PIN, BL)) { |
|
348 // app_start(); |
|
349 // } |
|
350 #endif |
|
351 } |
|
352 #ifdef __AVR_ATmega128__ |
|
353 /* no bootuart was selected, default to uart 0 */ |
|
354 if(!bootuart) |
|
355 { |
|
356 bootuart = 1; |
|
357 } |
|
358 #endif |
|
359 /* initialize UART(s) depending on CPU defined */ |
|
360 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1284P__) |
|
361 if(bootuart == 1) |
|
362 { |
|
363 UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); |
|
364 UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; |
|
365 UCSR0A = 0x00; |
|
366 UCSR0C = 0x06; |
|
367 UCSR0B = _BV(TXEN0)|_BV(RXEN0); |
|
368 } |
|
369 if(bootuart == 2) |
|
370 { |
|
371 UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); |
|
372 UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; |
|
373 UCSR1A = 0x00; |
|
374 UCSR1C = 0x06; |
|
375 UCSR1B = _BV(TXEN1)|_BV(RXEN1); |
|
376 } |
|
377 #elif defined __AVR_ATmega163__ |
|
378 UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); |
|
379 UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8; |
|
380 UCSRA = 0x00; |
|
381 UCSRB = _BV(TXEN)|_BV(RXEN); |
|
382 #elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) |
|
383 #ifdef DOUBLE_SPEED |
|
384 UCSR0A = (1<<U2X0); //Double speed mode USART0 |
|
385 UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*8L)-1); |
|
386 UBRR0H = (F_CPU/(BAUD_RATE*8L)-1) >> 8; |
|
387 #else |
|
388 UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); |
|
389 UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8; |
|
390 #endif |
|
391 UCSR0B = (1<<RXEN0) | (1<<TXEN0); |
|
392 UCSR0C = (1<<UCSZ00) | (1<<UCSZ01); |
|
393 /* Enable internal pull-up resistor on pin D0 (RX), in order |
|
394 to supress line noise that prevents the bootloader from |
|
395 timing out (DAM: 20070509) */ |
|
396 DDRD &= ~_BV(PIND0); |
|
397 PORTD |= _BV(PIND0); |
|
398 #elif defined __AVR_ATmega8__ |
|
399 /* m8 */ |
|
400 UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8; // set baud rate |
|
401 UBRRL = (((F_CPU/BAUD_RATE)/16)-1); |
|
402 UCSRB = (1<<RXEN)|(1<<TXEN); // enable Rx & Tx |
|
403 UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // config USART; 8N1 |
|
404 #else |
|
405 /* m16,m32,m169,m8515,m8535 */ |
|
406 UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1); |
|
407 UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8; |
|
408 UCSRA = 0x00; |
|
409 UCSRC = 0x06; |
|
410 UCSRB = _BV(TXEN)|_BV(RXEN); |
|
411 #endif |
|
412 #if defined __AVR_ATmega1280__ |
|
413 /* Enable internal pull-up resistor on pin D0 (RX), in order |
|
414 to supress line noise that prevents the bootloader from |
|
415 timing out (DAM: 20070509) */ |
|
416 /* feature added to the Arduino Mega --DC: 080930 */ |
|
417 DDRE &= ~_BV(PINE0); |
|
418 PORTE |= _BV(PINE0); |
|
419 #endif |
|
420 /* set LED pin as output */ |
|
421 LED_DDR |= _BV(LED); |
|
422 /* flash onboard LED to signal entering of bootloader */ |
|
423 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1284P__) |
|
424 // 4x for UART0, 5x for UART1 |
|
425 flash_led(NUM_LED_FLASHES + bootuart); |
|
426 #else |
|
427 flash_led(NUM_LED_FLASHES); |
|
428 #endif |
|
429 /* 20050803: by DojoCorp, this is one of the parts provoking the |
|
430 system to stop listening, cancelled from the original */ |
|
431 //putch('\0'); |
|
432 /* forever loop */ |
|
433 for (;;) |
|
434 { |
|
435 /* get character from UART */ |
|
436 ch = getch(); |
|
437 /* A bunch of if...else if... gives smaller code than switch...case ! */ |
|
438 /* Hello is anyone home ? */ |
|
439 if(ch=='0') |
|
440 { |
|
441 nothing_response(); |
|
442 } |
|
443 /* Request programmer ID */ |
|
444 /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry */ |
|
445 /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares. */ |
|
446 else if(ch=='1') |
|
447 { |
|
448 if (getch() == ' ') |
|
449 { |
|
450 putch(0x14); |
|
451 putch('A'); |
|
452 putch('V'); |
|
453 putch('R'); |
|
454 putch(' '); |
|
455 putch('I'); |
|
456 putch('S'); |
|
457 putch('P'); |
|
458 putch(0x10); |
|
459 } |
|
460 else |
|
461 { |
|
462 if (++error_count == MAX_ERROR_COUNT) |
|
463 app_start(); |
|
464 } |
|
465 } |
|
466 /* AVR ISP/STK500 board commands DON'T CARE so default nothing_response */ |
|
467 else if(ch=='@') |
|
468 { |
|
469 ch2 = getch(); |
|
470 if (ch2>0x85) getch(); |
|
471 nothing_response(); |
|
472 } |
|
473 /* AVR ISP/STK500 board requests */ |
|
474 else if(ch=='A') |
|
475 { |
|
476 ch2 = getch(); |
|
477 if(ch2==0x80) byte_response(HW_VER); // Hardware version |
|
478 else if(ch2==0x81) byte_response(SW_MAJOR); // Software major version |
|
479 else if(ch2==0x82) byte_response(SW_MINOR); // Software minor version |
|
480 else if(ch2==0x98) byte_response(0x03); // Unknown but seems to be required by avr studio 3.56 |
|
481 else byte_response(0x00); // Covers various unnecessary responses we don't care about |
|
482 } |
|
483 /* Device Parameters DON'T CARE, DEVICE IS FIXED */ |
|
484 else if(ch=='B') |
|
485 { |
|
486 getNch(20); |
|
487 nothing_response(); |
|
488 } |
|
489 /* Parallel programming stuff DON'T CARE */ |
|
490 else if(ch=='E') |
|
491 { |
|
492 getNch(5); |
|
493 nothing_response(); |
|
494 } |
|
495 /* P: Enter programming mode */ |
|
496 /* R: Erase device, don't care as we will erase one page at a time anyway. */ |
|
497 else if(ch=='P' || ch=='R') |
|
498 { |
|
499 nothing_response(); |
|
500 } |
|
501 /* Leave programming mode */ |
|
502 else if(ch=='Q') |
|
503 { |
|
504 nothing_response(); |
|
505 #ifdef WATCHDOG_MODS |
|
506 // autoreset via watchdog (sneaky!) |
|
507 WDTCSR = _BV(WDE); |
|
508 while (1); // 16 ms |
|
509 #endif |
|
510 } |
|
511 /* Set address, little endian. EEPROM in bytes, FLASH in words */ |
|
512 /* Perhaps extra address bytes may be added in future to support > 128kB FLASH. */ |
|
513 /* This might explain why little endian was used here, big endian used everywhere else. */ |
|
514 else if(ch=='U') |
|
515 { |
|
516 address.byte[0] = getch(); |
|
517 address.byte[1] = getch(); |
|
518 nothing_response(); |
|
519 } |
|
520 /* Universal SPI programming command, disabled. Would be used for fuses and lock bits. */ |
|
521 else if(ch=='V') |
|
522 { |
|
523 if (getch() == 0x30) |
|
524 { |
|
525 getch(); |
|
526 ch = getch(); |
|
527 getch(); |
|
528 if (ch == 0) |
|
529 { |
|
530 byte_response(SIG1); |
|
531 } |
|
532 else if (ch == 1) |
|
533 { |
|
534 byte_response(SIG2); |
|
535 } |
|
536 else |
|
537 { |
|
538 byte_response(SIG3); |
|
539 } |
|
540 } |
|
541 else |
|
542 { |
|
543 getNch(3); |
|
544 byte_response(0x00); |
|
545 } |
|
546 } |
|
547 /* Write memory, length is big endian and is in bytes */ |
|
548 else if(ch=='d') |
|
549 { |
|
550 length.byte[1] = getch(); |
|
551 length.byte[0] = getch(); |
|
552 flags.eeprom = 0; |
|
553 if (getch() == 'E') flags.eeprom = 1; |
|
554 for (w=0; w<length.word; w++) |
|
555 { |
|
556 buff[w] = getch(); // Store data in buffer, can't keep up with serial data stream whilst programming pages |
|
557 } |
|
558 if (getch() == ' ') |
|
559 { |
|
560 if (flags.eeprom) //Write to EEPROM one byte at a time |
|
561 { |
|
562 address.word <<= 1; |
|
563 for(w=0; w<length.word; w++) |
|
564 { |
|
565 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) |
|
566 while(EECR & (1<<EEPE)); |
|
567 EEAR = (uint16_t)(void *)address.word; |
|
568 EEDR = buff[w]; |
|
569 EECR |= (1<<EEMPE); |
|
570 EECR |= (1<<EEPE); |
|
571 #else |
|
572 eeprom_write_byte((void *)address.word,buff[w]); |
|
573 #endif |
|
574 address.word++; |
|
575 } |
|
576 } |
|
577 else //Write to FLASH one page at a time |
|
578 { |
|
579 if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME |
|
580 else address_high = 0x00; |
|
581 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__) |
|
582 RAMPZ = address_high; |
|
583 #endif |
|
584 address.word = address.word << 1; //address * 2 -> byte location |
|
585 /* if ((length.byte[0] & 0x01) == 0x01) length.word++; //Even up an odd number of bytes */ |
|
586 if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes |
|
587 cli(); //Disable interrupts, just to be sure |
|
588 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284P__) |
|
589 while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete |
|
590 #else |
|
591 while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete |
|
592 #endif |
|
593 asm volatile( |
|
594 "clr r17 \n\t" //page_word_count |
|
595 "lds r30,address \n\t" //Address of FLASH location (in bytes) |
|
596 "lds r31,address+1 \n\t" |
|
597 "ldi r28,lo8(buff) \n\t" //Start of buffer array in RAM |
|
598 "ldi r29,hi8(buff) \n\t" |
|
599 "lds r24,length \n\t" //Length of data to be written (in bytes) |
|
600 "lds r25,length+1 \n\t" |
|
601 "length_loop: \n\t" //Main loop, repeat for number of words in block |
|
602 "cpi r17,0x00 \n\t" //If page_word_count=0 then erase page |
|
603 "brne no_page_erase \n\t" |
|
604 "wait_spm1: \n\t" |
|
605 "lds r16,%0 \n\t" //Wait for previous spm to complete |
|
606 "andi r16,1 \n\t" |
|
607 "cpi r16,1 \n\t" |
|
608 "breq wait_spm1 \n\t" |
|
609 "ldi r16,0x03 \n\t" //Erase page pointed to by Z |
|
610 "sts %0,r16 \n\t" |
|
611 "spm \n\t" |
|
612 #ifdef __AVR_ATmega163__ |
|
613 ".word 0xFFFF \n\t" |
|
614 "nop \n\t" |
|
615 #endif |
|
616 "wait_spm2: \n\t" |
|
617 "lds r16,%0 \n\t" //Wait for previous spm to complete |
|
618 "andi r16,1 \n\t" |
|
619 "cpi r16,1 \n\t" |
|
620 "breq wait_spm2 \n\t" |
|
621 "ldi r16,0x11 \n\t" //Re-enable RWW section |
|
622 "sts %0,r16 \n\t" |
|
623 "spm \n\t" |
|
624 #ifdef __AVR_ATmega163__ |
|
625 ".word 0xFFFF \n\t" |
|
626 "nop \n\t" |
|
627 #endif |
|
628 "no_page_erase: \n\t" |
|
629 "ld r0,Y+ \n\t" //Write 2 bytes into page buffer |
|
630 "ld r1,Y+ \n\t" |
|
631 "wait_spm3: \n\t" |
|
632 "lds r16,%0 \n\t" //Wait for previous spm to complete |
|
633 "andi r16,1 \n\t" |
|
634 "cpi r16,1 \n\t" |
|
635 "breq wait_spm3 \n\t" |
|
636 "ldi r16,0x01 \n\t" //Load r0,r1 into FLASH page buffer |
|
637 "sts %0,r16 \n\t" |
|
638 "spm \n\t" |
|
639 "inc r17 \n\t" //page_word_count++ |
|
640 "cpi r17,%1 \n\t" |
|
641 "brlo same_page \n\t" //Still same page in FLASH |
|
642 "write_page: \n\t" |
|
643 "clr r17 \n\t" //New page, write current one first |
|
644 "wait_spm4: \n\t" |
|
645 "lds r16,%0 \n\t" //Wait for previous spm to complete |
|
646 "andi r16,1 \n\t" |
|
647 "cpi r16,1 \n\t" |
|
648 "breq wait_spm4 \n\t" |
|
649 #ifdef __AVR_ATmega163__ |
|
650 "andi r30,0x80 \n\t" // m163 requires Z6:Z1 to be zero during page write |
|
651 #endif |
|
652 "ldi r16,0x05 \n\t" //Write page pointed to by Z |
|
653 "sts %0,r16 \n\t" |
|
654 "spm \n\t" |
|
655 #ifdef __AVR_ATmega163__ |
|
656 ".word 0xFFFF \n\t" |
|
657 "nop \n\t" |
|
658 "ori r30,0x7E \n\t" // recover Z6:Z1 state after page write (had to be zero during write) |
|
659 #endif |
|
660 "wait_spm5: \n\t" |
|
661 "lds r16,%0 \n\t" //Wait for previous spm to complete |
|
662 "andi r16,1 \n\t" |
|
663 "cpi r16,1 \n\t" |
|
664 "breq wait_spm5 \n\t" |
|
665 "ldi r16,0x11 \n\t" //Re-enable RWW section |
|
666 "sts %0,r16 \n\t" |
|
667 "spm \n\t" |
|
668 #ifdef __AVR_ATmega163__ |
|
669 ".word 0xFFFF \n\t" |
|
670 "nop \n\t" |
|
671 #endif |
|
672 "same_page: \n\t" |
|
673 "adiw r30,2 \n\t" //Next word in FLASH |
|
674 "sbiw r24,2 \n\t" //length-2 |
|
675 "breq final_write \n\t" //Finished |
|
676 "rjmp length_loop \n\t" |
|
677 "final_write: \n\t" |
|
678 "cpi r17,0 \n\t" |
|
679 "breq block_done \n\t" |
|
680 "adiw r24,2 \n\t" //length+2, fool above check on length after short page write |
|
681 "rjmp write_page \n\t" |
|
682 "block_done: \n\t" |
|
683 "clr __zero_reg__ \n\t" //restore zero register |
|
684 #if defined __AVR_ATmega168__ || __AVR_ATmega328P__ || __AVR_ATmega128__ || __AVR_ATmega1280__ || __AVR_ATmega1281__ || __AVR_ATmega1284P__ |
|
685 : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31" |
|
686 #else |
|
687 : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31" |
|
688 #endif |
|
689 ); |
|
690 /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */ |
|
691 /* exit the bootloader without a power cycle anyhow */ |
|
692 } |
|
693 putch(0x14); |
|
694 putch(0x10); |
|
695 } |
|
696 else |
|
697 { |
|
698 if (++error_count == MAX_ERROR_COUNT) |
|
699 app_start(); |
|
700 } |
|
701 } |
|
702 /* Read memory block mode, length is big endian. */ |
|
703 else if(ch=='t') |
|
704 { |
|
705 length.byte[1] = getch(); |
|
706 length.byte[0] = getch(); |
|
707 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1284P__) |
|
708 if (address.word>0x7FFF) flags.rampz = 1; // No go with m256, FIXME |
|
709 else flags.rampz = 0; |
|
710 #endif |
|
711 address.word = address.word << 1; // address * 2 -> byte location |
|
712 if (getch() == 'E') flags.eeprom = 1; |
|
713 else flags.eeprom = 0; |
|
714 if (getch() == ' ') // Command terminator |
|
715 { |
|
716 putch(0x14); |
|
717 for (w=0; w < length.word; w++) // Can handle odd and even lengths okay |
|
718 { |
|
719 if (flags.eeprom) // Byte access EEPROM read |
|
720 { |
|
721 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) |
|
722 while(EECR & (1<<EEPE)); |
|
723 EEAR = (uint16_t)(void *)address.word; |
|
724 EECR |= (1<<EERE); |
|
725 putch(EEDR); |
|
726 #else |
|
727 putch(eeprom_read_byte((void *)address.word)); |
|
728 #endif |
|
729 address.word++; |
|
730 } |
|
731 else |
|
732 { |
|
733 if (!flags.rampz) putch(pgm_read_byte_near(address.word)); |
|
734 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1284P__) |
|
735 else putch(pgm_read_byte_far(address.word + 0x10000)); |
|
736 // Hmmmm, yuck FIXME when m256 arrvies |
|
737 #endif |
|
738 address.word++; |
|
739 } |
|
740 } |
|
741 putch(0x10); |
|
742 } |
|
743 } |
|
744 /* Get device signature bytes */ |
|
745 else if(ch=='u') |
|
746 { |
|
747 if (getch() == ' ') |
|
748 { |
|
749 putch(0x14); |
|
750 putch(SIG1); |
|
751 putch(SIG2); |
|
752 putch(SIG3); |
|
753 putch(0x10); |
|
754 } |
|
755 else |
|
756 { |
|
757 if (++error_count == MAX_ERROR_COUNT) |
|
758 app_start(); |
|
759 } |
|
760 } |
|
761 /* Read oscillator calibration byte */ |
|
762 else if(ch=='v') |
|
763 { |
|
764 byte_response(0x00); |
|
765 } |
|
766 #if defined MONITOR |
|
767 /* here come the extended monitor commands by Erik Lins */ |
|
768 /* check for three times exclamation mark pressed */ |
|
769 else if(ch=='!') |
|
770 { |
|
771 ch = getch(); |
|
772 if(ch=='!') |
|
773 { |
|
774 ch = getch(); |
|
775 if(ch=='!') |
|
776 { |
|
777 PGM_P welcome = ""; |
|
778 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) |
|
779 uint16_t extaddr; |
|
780 #endif |
|
781 uint8_t addrl, addrh; |
|
782 #ifdef CRUMB128 |
|
783 welcome = "ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r"; |
|
784 #elif defined PROBOMEGA128 |
|
785 welcome = "ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r"; |
|
786 #elif defined SAVVY128 |
|
787 welcome = "ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r"; |
|
788 #elif defined __AVR_ATmega1280__ |
|
789 welcome = "ATmegaBOOT / Arduino Mega - (C) Arduino LLC - 090930\n\r"; |
|
790 #endif |
|
791 /* turn on LED */ |
|
792 LED_DDR |= _BV(LED); |
|
793 LED_PORT &= ~_BV(LED); |
|
794 /* print a welcome message and command overview */ |
|
795 for(i=0; welcome[i] != '\0'; ++i) |
|
796 { |
|
797 putch(welcome[i]); |
|
798 } |
|
799 /* test for valid commands */ |
|
800 for(;;) |
|
801 { |
|
802 putch('\n'); |
|
803 putch('\r'); |
|
804 putch(':'); |
|
805 putch(' '); |
|
806 ch = getch(); |
|
807 putch(ch); |
|
808 /* toggle LED */ |
|
809 if(ch == 't') |
|
810 { |
|
811 if(bit_is_set(LED_PIN,LED)) |
|
812 { |
|
813 LED_PORT &= ~_BV(LED); |
|
814 putch('1'); |
|
815 } |
|
816 else |
|
817 { |
|
818 LED_PORT |= _BV(LED); |
|
819 putch('0'); |
|
820 } |
|
821 } |
|
822 /* read byte from address */ |
|
823 else if(ch == 'r') |
|
824 { |
|
825 ch = getch(); |
|
826 putch(ch); |
|
827 addrh = gethex(); |
|
828 addrl = gethex(); |
|
829 putch('='); |
|
830 ch = *(uint8_t *)((addrh << 8) + addrl); |
|
831 puthex(ch); |
|
832 } |
|
833 /* write a byte to address */ |
|
834 else if(ch == 'w') |
|
835 { |
|
836 ch = getch(); |
|
837 putch(ch); |
|
838 addrh = gethex(); |
|
839 addrl = gethex(); |
|
840 ch = getch(); |
|
841 putch(ch); |
|
842 ch = gethex(); |
|
843 *(uint8_t *)((addrh << 8) + addrl) = ch; |
|
844 } |
|
845 /* read from uart and echo back */ |
|
846 else if(ch == 'u') |
|
847 { |
|
848 for(;;) |
|
849 { |
|
850 putch(getch()); |
|
851 } |
|
852 } |
|
853 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) |
|
854 /* external bus loop */ |
|
855 else if(ch == 'b') |
|
856 { |
|
857 putch('b'); |
|
858 putch('u'); |
|
859 putch('s'); |
|
860 MCUCR = 0x80; |
|
861 XMCRA = 0; |
|
862 XMCRB = 0; |
|
863 extaddr = 0x1100; |
|
864 for(;;) |
|
865 { |
|
866 ch = *(volatile uint8_t *)extaddr; |
|
867 if(++extaddr == 0) |
|
868 { |
|
869 extaddr = 0x1100; |
|
870 } |
|
871 } |
|
872 } |
|
873 #endif |
|
874 else if(ch == 'j') |
|
875 { |
|
876 app_start(); |
|
877 } |
|
878 } /* end of monitor functions */ |
|
879 } |
|
880 } |
|
881 } |
|
882 /* end of monitor */ |
|
883 #endif |
|
884 else if (++error_count == MAX_ERROR_COUNT) |
|
885 { |
|
886 app_start(); |
|
887 } |
|
888 } /* end of forever loop */ |
|
889 } |
|
890 |
|
891 |
|
892 char gethexnib(void) |
|
893 { |
|
894 char a; |
|
895 a = getch(); |
|
896 putch(a); |
|
897 if(a >= 'a') |
|
898 { |
|
899 return (a - 'a' + 0x0a); |
|
900 } |
|
901 else if(a >= '0') |
|
902 { |
|
903 return(a - '0'); |
|
904 } |
|
905 return a; |
|
906 } |
|
907 |
|
908 |
|
909 char gethex(void) |
|
910 { |
|
911 return (gethexnib() << 4) + gethexnib(); |
|
912 } |
|
913 |
|
914 |
|
915 void puthex(char ch) |
|
916 { |
|
917 char ah; |
|
918 ah = ch >> 4; |
|
919 if(ah >= 0x0a) |
|
920 { |
|
921 ah = ah - 0x0a + 'a'; |
|
922 } |
|
923 else |
|
924 { |
|
925 ah += '0'; |
|
926 } |
|
927 ch &= 0x0f; |
|
928 if(ch >= 0x0a) |
|
929 { |
|
930 ch = ch - 0x0a + 'a'; |
|
931 } |
|
932 else |
|
933 { |
|
934 ch += '0'; |
|
935 } |
|
936 putch(ah); |
|
937 putch(ch); |
|
938 } |
|
939 |
|
940 |
|
941 void putch(char ch) |
|
942 { |
|
943 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1284P__) |
|
944 if(bootuart == 1) |
|
945 { |
|
946 while (!(UCSR0A & _BV(UDRE0))); |
|
947 UDR0 = ch; |
|
948 } |
|
949 else if (bootuart == 2) |
|
950 { |
|
951 while (!(UCSR1A & _BV(UDRE1))); |
|
952 UDR1 = ch; |
|
953 } |
|
954 #elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) |
|
955 while (!(UCSR0A & _BV(UDRE0))); |
|
956 UDR0 = ch; |
|
957 #else |
|
958 /* m8,16,32,169,8515,8535,163 */ |
|
959 while (!(UCSRA & _BV(UDRE))); |
|
960 UDR = ch; |
|
961 #endif |
|
962 } |
|
963 |
|
964 |
|
965 char getch(void) |
|
966 { |
|
967 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1284P__) |
|
968 uint32_t count = 0; |
|
969 if(bootuart == 1) |
|
970 { |
|
971 while(!(UCSR0A & _BV(RXC0))) |
|
972 { |
|
973 /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ |
|
974 /* HACKME:: here is a good place to count times*/ |
|
975 count++; |
|
976 if (count > MAX_TIME_COUNT) |
|
977 app_start(); |
|
978 } |
|
979 return UDR0; |
|
980 } |
|
981 else if(bootuart == 2) |
|
982 { |
|
983 while(!(UCSR1A & _BV(RXC1))) |
|
984 { |
|
985 /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ |
|
986 /* HACKME:: here is a good place to count times*/ |
|
987 count++; |
|
988 if (count > MAX_TIME_COUNT) |
|
989 app_start(); |
|
990 } |
|
991 return UDR1; |
|
992 } |
|
993 return 0; |
|
994 #elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) |
|
995 uint32_t count = 0; |
|
996 while(!(UCSR0A & _BV(RXC0))) |
|
997 { |
|
998 /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ |
|
999 /* HACKME:: here is a good place to count times*/ |
|
1000 count++; |
|
1001 if (count > MAX_TIME_COUNT) |
|
1002 app_start(); |
|
1003 } |
|
1004 return UDR0; |
|
1005 #else |
|
1006 /* m8,16,32,169,8515,8535,163 */ |
|
1007 uint32_t count = 0; |
|
1008 while(!(UCSRA & _BV(RXC))) |
|
1009 { |
|
1010 /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ |
|
1011 /* HACKME:: here is a good place to count times*/ |
|
1012 count++; |
|
1013 if (count > MAX_TIME_COUNT) |
|
1014 app_start(); |
|
1015 } |
|
1016 return UDR; |
|
1017 #endif |
|
1018 } |
|
1019 |
|
1020 |
|
1021 void getNch(uint8_t count) |
|
1022 { |
|
1023 while(count--) |
|
1024 { |
|
1025 #if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1284P__) |
|
1026 if(bootuart == 1) |
|
1027 { |
|
1028 while(!(UCSR0A & _BV(RXC0))); |
|
1029 UDR0; |
|
1030 } |
|
1031 else if(bootuart == 2) |
|
1032 { |
|
1033 while(!(UCSR1A & _BV(RXC1))); |
|
1034 UDR1; |
|
1035 } |
|
1036 #elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) |
|
1037 getch(); |
|
1038 #else |
|
1039 /* m8,16,32,169,8515,8535,163 */ |
|
1040 /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/ |
|
1041 //while(!(UCSRA & _BV(RXC))); |
|
1042 //UDR; |
|
1043 getch(); // need to handle time out |
|
1044 #endif |
|
1045 } |
|
1046 } |
|
1047 |
|
1048 |
|
1049 void byte_response(uint8_t val) |
|
1050 { |
|
1051 if (getch() == ' ') |
|
1052 { |
|
1053 putch(0x14); |
|
1054 putch(val); |
|
1055 putch(0x10); |
|
1056 } |
|
1057 else |
|
1058 { |
|
1059 if (++error_count == MAX_ERROR_COUNT) |
|
1060 app_start(); |
|
1061 } |
|
1062 } |
|
1063 |
|
1064 |
|
1065 void nothing_response(void) |
|
1066 { |
|
1067 if (getch() == ' ') |
|
1068 { |
|
1069 putch(0x14); |
|
1070 putch(0x10); |
|
1071 } |
|
1072 else |
|
1073 { |
|
1074 if (++error_count == MAX_ERROR_COUNT) |
|
1075 app_start(); |
|
1076 } |
|
1077 } |
|
1078 |
|
1079 void flash_led(uint8_t count) |
|
1080 { |
|
1081 while (count--) |
|
1082 { |
|
1083 LED_PORT |= _BV(LED); |
|
1084 _delay_ms(100); |
|
1085 LED_PORT &= ~_BV(LED); |
|
1086 _delay_ms(100); |
|
1087 } |
|
1088 } |
|
1089 |
|
1090 |
|
1091 /* end of file ATmegaBOOT.c */ |