~ubuntu-branches/ubuntu/precise/arduino/precise

« back to all changes in this revision

Viewing changes to hardware/arduino/bootloaders/lilypad/src/ATmegaBOOT.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Howard
  • Date: 2010-04-13 22:32:24 UTC
  • Revision ID: james.westby@ubuntu.com-20100413223224-jduxnd0xxnkkda02
Tags: upstream-0018+dfsg
ImportĀ upstreamĀ versionĀ 0018+dfsg

Show diffs side-by-side

added added

removed removed

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