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