source: arduino-1-6-7/trunk/fuentes/arduino-ide-amd64/hardware/arduino/avr/bootloaders/lilypad/src/ATmegaBOOT.c @ 46

Last change on this file since 46 was 46, checked in by jrpelegrina, 4 years ago

First release to Xenial

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