Project

General

Profile

Statistics
| Branch: | Revision:

root / arduino-1.0 / hardware / arduino / bootloaders / atmega / ATmegaBOOT_168.c @ 58d82c77

History | View | Annotate | Download (29.2 KB)

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

    
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
#else
121
/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */
122
#define BL_DDR  DDRD
123
#define BL_PORT PORTD
124
#define BL_PIN  PIND
125
#define BL      PIND6
126
#endif
127

    
128

    
129
/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */
130
/* if monitor functions are included, LED goes on after monitor was entered */
131
#if defined __AVR_ATmega128__ || defined __AVR_ATmega1280__
132
/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128, Arduino Mega) */
133
#define LED_DDR  DDRB
134
#define LED_PORT PORTB
135
#define LED_PIN  PINB
136
#define LED      PINB7
137
#else
138
/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duomilanuove */ 
139
/* other boards like e.g. Crumb8, Crumb168 are using PB2 */
140
#define LED_DDR  DDRB
141
#define LED_PORT PORTB
142
#define LED_PIN  PINB
143
#define LED      PINB5
144
#endif
145

    
146

    
147
/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */
148
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
149
#define MONITOR 1
150
#endif
151

    
152

    
153
/* define various device id's */
154
/* manufacturer byte is always the same */
155
#define SIG1        0x1E        // Yep, Atmel is the only manufacturer of AVR micros.  Single source :(
156

    
157
#if defined __AVR_ATmega1280__
158
#define SIG2        0x97
159
#define SIG3        0x03
160
#define PAGE_SIZE        0x80U        //128 words
161

    
162
#elif defined __AVR_ATmega1281__
163
#define SIG2        0x97
164
#define SIG3        0x04
165
#define PAGE_SIZE        0x80U        //128 words
166

    
167
#elif defined __AVR_ATmega128__
168
#define SIG2        0x97
169
#define SIG3        0x02
170
#define PAGE_SIZE        0x80U        //128 words
171

    
172
#elif defined __AVR_ATmega64__
173
#define SIG2        0x96
174
#define SIG3        0x02
175
#define PAGE_SIZE        0x80U        //128 words
176

    
177
#elif defined __AVR_ATmega32__
178
#define SIG2        0x95
179
#define SIG3        0x02
180
#define PAGE_SIZE        0x40U        //64 words
181

    
182
#elif defined __AVR_ATmega16__
183
#define SIG2        0x94
184
#define SIG3        0x03
185
#define PAGE_SIZE        0x40U        //64 words
186

    
187
#elif defined __AVR_ATmega8__
188
#define SIG2        0x93
189
#define SIG3        0x07
190
#define PAGE_SIZE        0x20U        //32 words
191

    
192
#elif defined __AVR_ATmega88__
193
#define SIG2        0x93
194
#define SIG3        0x0a
195
#define PAGE_SIZE        0x20U        //32 words
196

    
197
#elif defined __AVR_ATmega168__
198
#define SIG2        0x94
199
#define SIG3        0x06
200
#define PAGE_SIZE        0x40U        //64 words
201

    
202
#elif defined __AVR_ATmega328P__
203
#define SIG2        0x95
204
#define SIG3        0x0F
205
#define PAGE_SIZE        0x40U        //64 words
206

    
207
#elif defined __AVR_ATmega162__
208
#define SIG2        0x94
209
#define SIG3        0x04
210
#define PAGE_SIZE        0x40U        //64 words
211

    
212
#elif defined __AVR_ATmega163__
213
#define SIG2        0x94
214
#define SIG3        0x02
215
#define PAGE_SIZE        0x40U        //64 words
216

    
217
#elif defined __AVR_ATmega169__
218
#define SIG2        0x94
219
#define SIG3        0x05
220
#define PAGE_SIZE        0x40U        //64 words
221

    
222
#elif defined __AVR_ATmega8515__
223
#define SIG2        0x93
224
#define SIG3        0x06
225
#define PAGE_SIZE        0x20U        //32 words
226

    
227
#elif defined __AVR_ATmega8535__
228
#define SIG2        0x93
229
#define SIG3        0x08
230
#define PAGE_SIZE        0x20U        //32 words
231
#endif
232

    
233

    
234
/* function prototypes */
235
void putch(char);
236
char getch(void);
237
void getNch(uint8_t);
238
void byte_response(uint8_t);
239
void nothing_response(void);
240
char gethex(void);
241
void puthex(char);
242
void flash_led(uint8_t);
243

    
244
/* some variables */
245
union address_union {
246
        uint16_t word;
247
        uint8_t  byte[2];
248
} address;
249

    
250
union length_union {
251
        uint16_t word;
252
        uint8_t  byte[2];
253
} length;
254

    
255
struct flags_struct {
256
        unsigned eeprom : 1;
257
        unsigned rampz  : 1;
258
} flags;
259

    
260
uint8_t buff[256];
261
uint8_t address_high;
262

    
263
uint8_t pagesz=0x80;
264

    
265
uint8_t i;
266
uint8_t bootuart = 0;
267

    
268
uint8_t error_count = 0;
269

    
270
void (*app_start)(void) = 0x0000;
271

    
272

    
273
/* main program starts here */
274
int main(void)
275
{
276
        uint8_t ch,ch2;
277
        uint16_t w;
278

    
279
#ifdef WATCHDOG_MODS
280
        ch = MCUSR;
281
        MCUSR = 0;
282

    
283
        WDTCSR |= _BV(WDCE) | _BV(WDE);
284
        WDTCSR = 0;
285

    
286
        // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot.
287
        if (! (ch &  _BV(EXTRF))) // if its a not an external reset...
288
                app_start();  // skip bootloader
289
#else
290
        asm volatile("nop\n\t");
291
#endif
292

    
293
        /* set pin direction for bootloader pin and enable pullup */
294
        /* for ATmega128, two pins need to be initialized */
295
#ifdef __AVR_ATmega128__
296
        BL_DDR &= ~_BV(BL0);
297
        BL_DDR &= ~_BV(BL1);
298
        BL_PORT |= _BV(BL0);
299
        BL_PORT |= _BV(BL1);
300
#else
301
        /* We run the bootloader regardless of the state of this pin.  Thus, don't
302
        put it in a different state than the other pins.  --DAM, 070709
303
        This also applies to Arduino Mega -- DC, 080930
304
        BL_DDR &= ~_BV(BL);
305
        BL_PORT |= _BV(BL);
306
        */
307
#endif
308

    
309

    
310
#ifdef __AVR_ATmega128__
311
        /* check which UART should be used for booting */
312
        if(bit_is_clear(BL_PIN, BL0)) {
313
                bootuart = 1;
314
        }
315
        else if(bit_is_clear(BL_PIN, BL1)) {
316
                bootuart = 2;
317
        }
318
#endif
319

    
320
#if defined __AVR_ATmega1280__
321
        /* the mega1280 chip has four serial ports ... we could eventually use any of them, or not? */
322
        /* however, we don't wanna confuse people, to avoid making a mess, we will stick to RXD0, TXD0 */
323
        bootuart = 1;
324
#endif
325

    
326
        /* check if flash is programmed already, if not start bootloader anyway */
327
        if(pgm_read_byte_near(0x0000) != 0xFF) {
328

    
329
#ifdef __AVR_ATmega128__
330
        /* no UART was selected, start application */
331
        if(!bootuart) {
332
                app_start();
333
        }
334
#else
335
        /* check if bootloader pin is set low */
336
        /* we don't start this part neither for the m8, nor m168 */
337
        //if(bit_is_set(BL_PIN, BL)) {
338
        //      app_start();
339
        //    }
340
#endif
341
        }
342

    
343
#ifdef __AVR_ATmega128__    
344
        /* no bootuart was selected, default to uart 0 */
345
        if(!bootuart) {
346
                bootuart = 1;
347
        }
348
#endif
349

    
350

    
351
        /* initialize UART(s) depending on CPU defined */
352
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
353
        if(bootuart == 1) {
354
                UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
355
                UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
356
                UCSR0A = 0x00;
357
                UCSR0C = 0x06;
358
                UCSR0B = _BV(TXEN0)|_BV(RXEN0);
359
        }
360
        if(bootuart == 2) {
361
                UBRR1L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
362
                UBRR1H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
363
                UCSR1A = 0x00;
364
                UCSR1C = 0x06;
365
                UCSR1B = _BV(TXEN1)|_BV(RXEN1);
366
        }
367
#elif defined __AVR_ATmega163__
368
        UBRR = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
369
        UBRRHI = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
370
        UCSRA = 0x00;
371
        UCSRB = _BV(TXEN)|_BV(RXEN);        
372
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
373

    
374
#ifdef DOUBLE_SPEED
375
        UCSR0A = (1<<U2X0); //Double speed mode USART0
376
        UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*8L)-1);
377
        UBRR0H = (F_CPU/(BAUD_RATE*8L)-1) >> 8;
378
#else
379
        UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
380
        UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
381
#endif
382

    
383
        UCSR0B = (1<<RXEN0) | (1<<TXEN0);
384
        UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);
385

    
386
        /* Enable internal pull-up resistor on pin D0 (RX), in order
387
        to supress line noise that prevents the bootloader from
388
        timing out (DAM: 20070509) */
389
        DDRD &= ~_BV(PIND0);
390
        PORTD |= _BV(PIND0);
391
#elif defined __AVR_ATmega8__
392
        /* m8 */
393
        UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8;         // set baud rate
394
        UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
395
        UCSRB = (1<<RXEN)|(1<<TXEN);  // enable Rx & Tx
396
        UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // config USART; 8N1
397
#else
398
        /* m16,m32,m169,m8515,m8535 */
399
        UBRRL = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
400
        UBRRH = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
401
        UCSRA = 0x00;
402
        UCSRC = 0x06;
403
        UCSRB = _BV(TXEN)|_BV(RXEN);
404
#endif
405

    
406
#if defined __AVR_ATmega1280__
407
        /* Enable internal pull-up resistor on pin D0 (RX), in order
408
        to supress line noise that prevents the bootloader from
409
        timing out (DAM: 20070509) */
410
        /* feature added to the Arduino Mega --DC: 080930 */
411
        DDRE &= ~_BV(PINE0);
412
        PORTE |= _BV(PINE0);
413
#endif
414

    
415

    
416
        /* set LED pin as output */
417
        LED_DDR |= _BV(LED);
418

    
419

    
420
        /* flash onboard LED to signal entering of bootloader */
421
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
422
        // 4x for UART0, 5x for UART1
423
        flash_led(NUM_LED_FLASHES + bootuart);
424
#else
425
        flash_led(NUM_LED_FLASHES);
426
#endif
427

    
428
        /* 20050803: by DojoCorp, this is one of the parts provoking the
429
                 system to stop listening, cancelled from the original */
430
        //putch('\0');
431

    
432
        /* forever loop */
433
        for (;;) {
434

    
435
        /* get character from UART */
436
        ch = getch();
437

    
438
        /* A bunch of if...else if... gives smaller code than switch...case ! */
439

    
440
        /* Hello is anyone home ? */ 
441
        if(ch=='0') {
442
                nothing_response();
443
        }
444

    
445

    
446
        /* Request programmer ID */
447
        /* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry  */
448
        /* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares.  */
449
        else if(ch=='1') {
450
                if (getch() == ' ') {
451
                        putch(0x14);
452
                        putch('A');
453
                        putch('V');
454
                        putch('R');
455
                        putch(' ');
456
                        putch('I');
457
                        putch('S');
458
                        putch('P');
459
                        putch(0x10);
460
                } else {
461
                        if (++error_count == MAX_ERROR_COUNT)
462
                                app_start();
463
                }
464
        }
465

    
466

    
467
        /* AVR ISP/STK500 board commands  DON'T CARE so default nothing_response */
468
        else if(ch=='@') {
469
                ch2 = getch();
470
                if (ch2>0x85) getch();
471
                nothing_response();
472
        }
473

    
474

    
475
        /* AVR ISP/STK500 board requests */
476
        else if(ch=='A') {
477
                ch2 = getch();
478
                if(ch2==0x80) byte_response(HW_VER);                // Hardware version
479
                else if(ch2==0x81) byte_response(SW_MAJOR);        // Software major version
480
                else if(ch2==0x82) byte_response(SW_MINOR);        // Software minor version
481
                else if(ch2==0x98) byte_response(0x03);                // Unknown but seems to be required by avr studio 3.56
482
                else byte_response(0x00);                                // Covers various unnecessary responses we don't care about
483
        }
484

    
485

    
486
        /* Device Parameters  DON'T CARE, DEVICE IS FIXED  */
487
        else if(ch=='B') {
488
                getNch(20);
489
                nothing_response();
490
        }
491

    
492

    
493
        /* Parallel programming stuff  DON'T CARE  */
494
        else if(ch=='E') {
495
                getNch(5);
496
                nothing_response();
497
        }
498

    
499

    
500
        /* P: Enter programming mode  */
501
        /* R: Erase device, don't care as we will erase one page at a time anyway.  */
502
        else if(ch=='P' || ch=='R') {
503
                nothing_response();
504
        }
505

    
506

    
507
        /* Leave programming mode  */
508
        else if(ch=='Q') {
509
                nothing_response();
510
#ifdef WATCHDOG_MODS
511
                // autoreset via watchdog (sneaky!)
512
                WDTCSR = _BV(WDE);
513
                while (1); // 16 ms
514
#endif
515
        }
516

    
517

    
518
        /* Set address, little endian. EEPROM in bytes, FLASH in words  */
519
        /* Perhaps extra address bytes may be added in future to support > 128kB FLASH.  */
520
        /* This might explain why little endian was used here, big endian used everywhere else.  */
521
        else if(ch=='U') {
522
                address.byte[0] = getch();
523
                address.byte[1] = getch();
524
                nothing_response();
525
        }
526

    
527

    
528
        /* Universal SPI programming command, disabled.  Would be used for fuses and lock bits.  */
529
        else if(ch=='V') {
530
                if (getch() == 0x30) {
531
                        getch();
532
                        ch = getch();
533
                        getch();
534
                        if (ch == 0) {
535
                                byte_response(SIG1);
536
                        } else if (ch == 1) {
537
                                byte_response(SIG2); 
538
                        } else {
539
                                byte_response(SIG3);
540
                        } 
541
                } else {
542
                        getNch(3);
543
                        byte_response(0x00);
544
                }
545
        }
546

    
547

    
548
        /* Write memory, length is big endian and is in bytes  */
549
        else if(ch=='d') {
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
                        buff[w] = getch();                                // Store data in buffer, can't keep up with serial data stream whilst programming pages
556
                }
557
                if (getch() == ' ') {
558
                        if (flags.eeprom) {                                //Write to EEPROM one byte at a time
559
                                address.word <<= 1;
560
                                for(w=0;w<length.word;w++) {
561
#if defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__)
562
                                        while(EECR & (1<<EEPE));
563
                                        EEAR = (uint16_t)(void *)address.word;
564
                                        EEDR = buff[w];
565
                                        EECR |= (1<<EEMPE);
566
                                        EECR |= (1<<EEPE);
567
#else
568
                                        eeprom_write_byte((void *)address.word,buff[w]);
569
#endif
570
                                        address.word++;
571
                                }                        
572
                        }
573
                        else {                                                //Write to FLASH one page at a time
574
                                if (address.byte[1]>127) address_high = 0x01;        //Only possible with m128, m256 will need 3rd address byte. FIXME
575
                                else address_high = 0x00;
576
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
577
                                RAMPZ = address_high;
578
#endif
579
                                address.word = address.word << 1;                //address * 2 -> byte location
580
                                /* if ((length.byte[0] & 0x01) == 0x01) length.word++;        //Even up an odd number of bytes */
581
                                if ((length.byte[0] & 0x01)) length.word++;        //Even up an odd number of bytes
582
                                cli();                                        //Disable interrupts, just to be sure
583
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
584
                                while(bit_is_set(EECR,EEPE));                        //Wait for previous EEPROM writes to complete
585
#else
586
                                while(bit_is_set(EECR,EEWE));                        //Wait for previous EEPROM writes to complete
587
#endif
588
                                asm volatile(
589
                                         "clr        r17                \n\t"        //page_word_count
590
                                         "lds        r30,address        \n\t"        //Address of FLASH location (in bytes)
591
                                         "lds        r31,address+1        \n\t"
592
                                         "ldi        r28,lo8(buff)        \n\t"        //Start of buffer array in RAM
593
                                         "ldi        r29,hi8(buff)        \n\t"
594
                                         "lds        r24,length        \n\t"        //Length of data to be written (in bytes)
595
                                         "lds        r25,length+1        \n\t"
596
                                         "length_loop:                \n\t"        //Main loop, repeat for number of words in block                                                                                                                  
597
                                         "cpi        r17,0x00        \n\t"        //If page_word_count=0 then erase page
598
                                         "brne        no_page_erase        \n\t"                                                 
599
                                         "wait_spm1:                \n\t"
600
                                         "lds        r16,%0                \n\t"        //Wait for previous spm to complete
601
                                         "andi        r16,1           \n\t"
602
                                         "cpi        r16,1           \n\t"
603
                                         "breq        wait_spm1       \n\t"
604
                                         "ldi        r16,0x03        \n\t"        //Erase page pointed to by Z
605
                                         "sts        %0,r16                \n\t"
606
                                         "spm                        \n\t"                                                         
607
#ifdef __AVR_ATmega163__
608
                                         ".word 0xFFFF                \n\t"
609
                                         "nop                        \n\t"
610
#endif
611
                                         "wait_spm2:                \n\t"
612
                                         "lds        r16,%0                \n\t"        //Wait for previous spm to complete
613
                                         "andi        r16,1           \n\t"
614
                                         "cpi        r16,1           \n\t"
615
                                         "breq        wait_spm2       \n\t"                                                                         
616

    
617
                                         "ldi        r16,0x11        \n\t"        //Re-enable RWW section
618
                                         "sts        %0,r16                \n\t"                                                                          
619
                                         "spm                        \n\t"
620
#ifdef __AVR_ATmega163__
621
                                         ".word 0xFFFF                \n\t"
622
                                         "nop                        \n\t"
623
#endif
624
                                         "no_page_erase:                \n\t"                                                         
625
                                         "ld        r0,Y+                \n\t"        //Write 2 bytes into page buffer
626
                                         "ld        r1,Y+                \n\t"                                                         
627
                                                                 
628
                                         "wait_spm3:                \n\t"
629
                                         "lds        r16,%0                \n\t"        //Wait for previous spm to complete
630
                                         "andi        r16,1           \n\t"
631
                                         "cpi        r16,1           \n\t"
632
                                         "breq        wait_spm3       \n\t"
633
                                         "ldi        r16,0x01        \n\t"        //Load r0,r1 into FLASH page buffer
634
                                         "sts        %0,r16                \n\t"
635
                                         "spm                        \n\t"
636
                                                                 
637
                                         "inc        r17                \n\t"        //page_word_count++
638
                                         "cpi r17,%1                \n\t"
639
                                         "brlo        same_page        \n\t"        //Still same page in FLASH
640
                                         "write_page:                \n\t"
641
                                         "clr        r17                \n\t"        //New page, write current one first
642
                                         "wait_spm4:                \n\t"
643
                                         "lds        r16,%0                \n\t"        //Wait for previous spm to complete
644
                                         "andi        r16,1           \n\t"
645
                                         "cpi        r16,1           \n\t"
646
                                         "breq        wait_spm4       \n\t"
647
#ifdef __AVR_ATmega163__
648
                                         "andi        r30,0x80        \n\t"        // m163 requires Z6:Z1 to be zero during page write
649
#endif                                                                                                                  
650
                                         "ldi        r16,0x05        \n\t"        //Write page pointed to by Z
651
                                         "sts        %0,r16                \n\t"
652
                                         "spm                        \n\t"
653
#ifdef __AVR_ATmega163__
654
                                         ".word 0xFFFF                \n\t"
655
                                         "nop                        \n\t"
656
                                         "ori        r30,0x7E        \n\t"        // recover Z6:Z1 state after page write (had to be zero during write)
657
#endif
658
                                         "wait_spm5:                \n\t"
659
                                         "lds        r16,%0                \n\t"        //Wait for previous spm to complete
660
                                         "andi        r16,1           \n\t"
661
                                         "cpi        r16,1           \n\t"
662
                                         "breq        wait_spm5       \n\t"                                                                         
663
                                         "ldi        r16,0x11        \n\t"        //Re-enable RWW section
664
                                         "sts        %0,r16                \n\t"                                                                          
665
                                         "spm                        \n\t"                                                          
666
#ifdef __AVR_ATmega163__
667
                                         ".word 0xFFFF                \n\t"
668
                                         "nop                        \n\t"
669
#endif
670
                                         "same_page:                \n\t"                                                         
671
                                         "adiw        r30,2                \n\t"        //Next word in FLASH
672
                                         "sbiw        r24,2                \n\t"        //length-2
673
                                         "breq        final_write        \n\t"        //Finished
674
                                         "rjmp        length_loop        \n\t"
675
                                         "final_write:                \n\t"
676
                                         "cpi        r17,0                \n\t"
677
                                         "breq        block_done        \n\t"
678
                                         "adiw        r24,2                \n\t"        //length+2, fool above check on length after short page write
679
                                         "rjmp        write_page        \n\t"
680
                                         "block_done:                \n\t"
681
                                         "clr        __zero_reg__        \n\t"        //restore zero register
682
#if defined __AVR_ATmega168__  || __AVR_ATmega328P__ || __AVR_ATmega128__ || __AVR_ATmega1280__ || __AVR_ATmega1281__ 
683
                                         : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
684
#else
685
                                         : "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
686
#endif
687
                                         );
688
                                /* Should really add a wait for RWW section to be enabled, don't actually need it since we never */
689
                                /* exit the bootloader without a power cycle anyhow */
690
                        }
691
                        putch(0x14);
692
                        putch(0x10);
693
                } else {
694
                        if (++error_count == MAX_ERROR_COUNT)
695
                                app_start();
696
                }                
697
        }
698

    
699

    
700
        /* Read memory block mode, length is big endian.  */
701
        else if(ch=='t') {
702
                length.byte[1] = getch();
703
                length.byte[0] = getch();
704
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
705
                if (address.word>0x7FFF) flags.rampz = 1;                // No go with m256, FIXME
706
                else flags.rampz = 0;
707
#endif
708
                address.word = address.word << 1;                // address * 2 -> byte location
709
                if (getch() == 'E') flags.eeprom = 1;
710
                else flags.eeprom = 0;
711
                if (getch() == ' ') {                                // Command terminator
712
                        putch(0x14);
713
                        for (w=0;w < length.word;w++) {                        // Can handle odd and even lengths okay
714
                                if (flags.eeprom) {                                // Byte access EEPROM read
715
#if defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__)
716
                                        while(EECR & (1<<EEPE));
717
                                        EEAR = (uint16_t)(void *)address.word;
718
                                        EECR |= (1<<EERE);
719
                                        putch(EEDR);
720
#else
721
                                        putch(eeprom_read_byte((void *)address.word));
722
#endif
723
                                        address.word++;
724
                                }
725
                                else {
726

    
727
                                        if (!flags.rampz) putch(pgm_read_byte_near(address.word));
728
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
729
                                        else putch(pgm_read_byte_far(address.word + 0x10000));
730
                                        // Hmmmm, yuck  FIXME when m256 arrvies
731
#endif
732
                                        address.word++;
733
                                }
734
                        }
735
                        putch(0x10);
736
                }
737
        }
738

    
739

    
740
        /* Get device signature bytes  */
741
        else if(ch=='u') {
742
                if (getch() == ' ') {
743
                        putch(0x14);
744
                        putch(SIG1);
745
                        putch(SIG2);
746
                        putch(SIG3);
747
                        putch(0x10);
748
                } else {
749
                        if (++error_count == MAX_ERROR_COUNT)
750
                                app_start();
751
                }
752
        }
753

    
754

    
755
        /* Read oscillator calibration byte */
756
        else if(ch=='v') {
757
                byte_response(0x00);
758
        }
759

    
760

    
761
#if defined MONITOR 
762

    
763
        /* here come the extended monitor commands by Erik Lins */
764

    
765
        /* check for three times exclamation mark pressed */
766
        else if(ch=='!') {
767
                ch = getch();
768
                if(ch=='!') {
769
                ch = getch();
770
                if(ch=='!') {
771
                        PGM_P welcome = "";
772
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
773
                        uint16_t extaddr;
774
#endif
775
                        uint8_t addrl, addrh;
776

    
777
#ifdef CRUMB128
778
                        welcome = "ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
779
#elif defined PROBOMEGA128
780
                        welcome = "ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
781
#elif defined SAVVY128
782
                        welcome = "ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
783
#elif defined __AVR_ATmega1280__ 
784
                        welcome = "ATmegaBOOT / Arduino Mega - (C) Arduino LLC - 090930\n\r";
785
#endif
786

    
787
                        /* turn on LED */
788
                        LED_DDR |= _BV(LED);
789
                        LED_PORT &= ~_BV(LED);
790

    
791
                        /* print a welcome message and command overview */
792
                        for(i=0; welcome[i] != '\0'; ++i) {
793
                                putch(welcome[i]);
794
                        }
795

    
796
                        /* test for valid commands */
797
                        for(;;) {
798
                                putch('\n');
799
                                putch('\r');
800
                                putch(':');
801
                                putch(' ');
802

    
803
                                ch = getch();
804
                                putch(ch);
805

    
806
                                /* toggle LED */
807
                                if(ch == 't') {
808
                                        if(bit_is_set(LED_PIN,LED)) {
809
                                                LED_PORT &= ~_BV(LED);
810
                                                putch('1');
811
                                        } else {
812
                                                LED_PORT |= _BV(LED);
813
                                                putch('0');
814
                                        }
815
                                } 
816

    
817
                                /* read byte from address */
818
                                else if(ch == 'r') {
819
                                        ch = getch(); putch(ch);
820
                                        addrh = gethex();
821
                                        addrl = gethex();
822
                                        putch('=');
823
                                        ch = *(uint8_t *)((addrh << 8) + addrl);
824
                                        puthex(ch);
825
                                }
826

    
827
                                /* write a byte to address  */
828
                                else if(ch == 'w') {
829
                                        ch = getch(); putch(ch);
830
                                        addrh = gethex();
831
                                        addrl = gethex();
832
                                        ch = getch(); putch(ch);
833
                                        ch = gethex();
834
                                        *(uint8_t *)((addrh << 8) + addrl) = ch;
835
                                }
836

    
837
                                /* read from uart and echo back */
838
                                else if(ch == 'u') {
839
                                        for(;;) {
840
                                                putch(getch());
841
                                        }
842
                                }
843
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
844
                                /* external bus loop  */
845
                                else if(ch == 'b') {
846
                                        putch('b');
847
                                        putch('u');
848
                                        putch('s');
849
                                        MCUCR = 0x80;
850
                                        XMCRA = 0;
851
                                        XMCRB = 0;
852
                                        extaddr = 0x1100;
853
                                        for(;;) {
854
                                                ch = *(volatile uint8_t *)extaddr;
855
                                                if(++extaddr == 0) {
856
                                                        extaddr = 0x1100;
857
                                                }
858
                                        }
859
                                }
860
#endif
861

    
862
                                else if(ch == 'j') {
863
                                        app_start();
864
                                }
865

    
866
                        } /* end of monitor functions */
867

    
868
                }
869
                }
870
        }
871
        /* end of monitor */
872
#endif
873
        else if (++error_count == MAX_ERROR_COUNT) {
874
                app_start();
875
        }
876
        } /* end of forever loop */
877

    
878
}
879

    
880

    
881
char gethexnib(void) {
882
        char a;
883
        a = getch(); putch(a);
884
        if(a >= 'a') {
885
                return (a - 'a' + 0x0a);
886
        } else if(a >= '0') {
887
                return(a - '0');
888
        }
889
        return a;
890
}
891

    
892

    
893
char gethex(void) {
894
        return (gethexnib() << 4) + gethexnib();
895
}
896

    
897

    
898
void puthex(char ch) {
899
        char ah;
900

    
901
        ah = ch >> 4;
902
        if(ah >= 0x0a) {
903
                ah = ah - 0x0a + 'a';
904
        } else {
905
                ah += '0';
906
        }
907
        
908
        ch &= 0x0f;
909
        if(ch >= 0x0a) {
910
                ch = ch - 0x0a + 'a';
911
        } else {
912
                ch += '0';
913
        }
914
        
915
        putch(ah);
916
        putch(ch);
917
}
918

    
919

    
920
void putch(char ch)
921
{
922
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
923
        if(bootuart == 1) {
924
                while (!(UCSR0A & _BV(UDRE0)));
925
                UDR0 = ch;
926
        }
927
        else if (bootuart == 2) {
928
                while (!(UCSR1A & _BV(UDRE1)));
929
                UDR1 = ch;
930
        }
931
#elif defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__)
932
        while (!(UCSR0A & _BV(UDRE0)));
933
        UDR0 = ch;
934
#else
935
        /* m8,16,32,169,8515,8535,163 */
936
        while (!(UCSRA & _BV(UDRE)));
937
        UDR = ch;
938
#endif
939
}
940

    
941

    
942
char getch(void)
943
{
944
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
945
        uint32_t count = 0;
946
        if(bootuart == 1) {
947
                while(!(UCSR0A & _BV(RXC0))) {
948
                        /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
949
                        /* HACKME:: here is a good place to count times*/
950
                        count++;
951
                        if (count > MAX_TIME_COUNT)
952
                                app_start();
953
                        }
954

    
955
                        return UDR0;
956
                }
957
        else if(bootuart == 2) {
958
                while(!(UCSR1A & _BV(RXC1))) {
959
                        /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
960
                        /* HACKME:: here is a good place to count times*/
961
                        count++;
962
                        if (count > MAX_TIME_COUNT)
963
                                app_start();
964
                }
965

    
966
                return UDR1;
967
        }
968
        return 0;
969
#elif defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__)
970
        uint32_t count = 0;
971
        while(!(UCSR0A & _BV(RXC0))){
972
                /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
973
                /* HACKME:: here is a good place to count times*/
974
                count++;
975
                if (count > MAX_TIME_COUNT)
976
                        app_start();
977
        }
978
        return UDR0;
979
#else
980
        /* m8,16,32,169,8515,8535,163 */
981
        uint32_t count = 0;
982
        while(!(UCSRA & _BV(RXC))){
983
                /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
984
                /* HACKME:: here is a good place to count times*/
985
                count++;
986
                if (count > MAX_TIME_COUNT)
987
                        app_start();
988
        }
989
        return UDR;
990
#endif
991
}
992

    
993

    
994
void getNch(uint8_t count)
995
{
996
        while(count--) {
997
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
998
                if(bootuart == 1) {
999
                        while(!(UCSR0A & _BV(RXC0)));
1000
                        UDR0;
1001
                } 
1002
                else if(bootuart == 2) {
1003
                        while(!(UCSR1A & _BV(RXC1)));
1004
                        UDR1;
1005
                }
1006
#elif defined(__AVR_ATmega168__)  || defined(__AVR_ATmega328P__)
1007
                getch();
1008
#else
1009
                /* m8,16,32,169,8515,8535,163 */
1010
                /* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
1011
                //while(!(UCSRA & _BV(RXC)));
1012
                //UDR;
1013
                getch(); // need to handle time out
1014
#endif                
1015
        }
1016
}
1017

    
1018

    
1019
void byte_response(uint8_t val)
1020
{
1021
        if (getch() == ' ') {
1022
                putch(0x14);
1023
                putch(val);
1024
                putch(0x10);
1025
        } else {
1026
                if (++error_count == MAX_ERROR_COUNT)
1027
                        app_start();
1028
        }
1029
}
1030

    
1031

    
1032
void nothing_response(void)
1033
{
1034
        if (getch() == ' ') {
1035
                putch(0x14);
1036
                putch(0x10);
1037
        } else {
1038
                if (++error_count == MAX_ERROR_COUNT)
1039
                        app_start();
1040
        }
1041
}
1042

    
1043
void flash_led(uint8_t count)
1044
{
1045
        while (count--) {
1046
                LED_PORT |= _BV(LED);
1047
                _delay_ms(100);
1048
                LED_PORT &= ~_BV(LED);
1049
                _delay_ms(100);
1050
        }
1051
}
1052

    
1053

    
1054
/* end of file ATmegaBOOT.c */