Skip to content

Commit 1b17232

Browse files
committed
Adding support for the Arduino Mega (ATmega1280) to the core and bootloader.
1 parent 7c105e9 commit 1b17232

File tree

13 files changed

+1093
-91
lines changed

13 files changed

+1093
-91
lines changed

hardware/boards.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,3 +177,23 @@ atmega328.bootloader.lock_bits=0x0F
177177
atmega328.build.mcu=atmega328p
178178
atmega328.build.f_cpu=16000000L
179179
atmega328.build.core=arduino
180+
181+
##############################################################
182+
183+
mega.name=Arduino Mega
184+
185+
mega.upload.protocol=stk500
186+
mega.upload.maximum_size=126976
187+
mega.upload.speed=57600
188+
189+
mega.bootloader.low_fuses=0xFF
190+
mega.bootloader.high_fuses=0xDA
191+
mega.bootloader.extended_fuses=0xF5
192+
mega.bootloader.path=atmega
193+
mega.bootloader.file=ATmegaBOOT_168_atmega1280.hex
194+
mega.bootloader.unlock_bits=0x3F
195+
mega.bootloader.lock_bits=0x0F
196+
197+
mega.build.mcu=atmega1280
198+
mega.build.f_cpu=16000000L
199+
mega.build.core=arduino

hardware/bootloaders/atmega/ATmegaBOOT_168.c

Lines changed: 96 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
/* */
77
/* ATmegaBOOT.c */
88
/* */
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 */
915
/* 20070626: hacked for Arduino Diecimila (which auto- */
1016
/* resets when a USB connection is made to it) */
1117
/* by D. Mellis */
@@ -101,13 +107,16 @@
101107

102108
/* Adjust to suit whatever pin your hardware uses to enter the bootloader */
103109
/* 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 */
104111
/* BL0... means UART0, BL1... means UART1 */
105112
#ifdef __AVR_ATmega128__
106113
#define BL_DDR DDRF
107114
#define BL_PORT PORTF
108115
#define BL_PIN PINF
109116
#define BL0 PINF7
110117
#define BL1 PINF6
118+
#elif defined __AVR_ATmega1280__
119+
/* we just don't do anything for the MEGA and enter bootloader on reset anyway*/
111120
#else
112121
/* other ATmegas have only one UART, so only one pin is defined to enter bootloader */
113122
#define BL_DDR DDRD
@@ -119,34 +128,43 @@
119128

120129
/* onboard LED is used to indicate, that the bootloader was entered (3x flashing) */
121130
/* if monitor functions are included, LED goes on after monitor was entered */
122-
#ifdef __AVR_ATmega128__
123-
/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128) */
131+
#if defined __AVR_ATmega128__ || defined __AVR_ATmega1280__
132+
/* Onboard LED is connected to pin PB7 (e.g. Crumb128, PROBOmega128, Savvy128, Arduino Mega) */
124133
#define LED_DDR DDRB
125134
#define LED_PORT PORTB
126135
#define LED_PIN PINB
127136
#define LED PINB7
128137
#else
129-
/* Onboard LED is connected to pin PB2 (e.g. Crumb8, Crumb168) */
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 */
130140
#define LED_DDR DDRB
131141
#define LED_PORT PORTB
132142
#define LED_PIN PINB
133-
/* 20060803: hacked by DojoCorp, LED pin is B5 in Arduino */
134-
/* #define LED PINB2 */
135143
#define LED PINB5
136144
#endif
137145

138146

139147
/* monitor functions will only be compiled when using ATmega128, due to bootblock size constraints */
140-
#ifdef __AVR_ATmega128__
141-
#define MONITOR
148+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
149+
#define MONITOR 1
142150
#endif
143151

144152

145153
/* define various device id's */
146154
/* manufacturer byte is always the same */
147155
#define SIG1 0x1E // Yep, Atmel is the only manufacturer of AVR micros. Single source :(
148156

149-
#if defined __AVR_ATmega128__
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__
150168
#define SIG2 0x97
151169
#define SIG3 0x02
152170
#define PAGE_SIZE 0x80U //128 words
@@ -282,6 +300,7 @@ int main(void)
282300
#else
283301
/* We run the bootloader regardless of the state of this pin. Thus, don't
284302
put it in a different state than the other pins. --DAM, 070709
303+
This also applies to Arduino Mega -- DC, 080930
285304
BL_DDR &= ~_BV(BL);
286305
BL_PORT |= _BV(BL);
287306
*/
@@ -298,24 +317,30 @@ int main(void)
298317
}
299318
#endif
300319

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+
301326
/* check if flash is programmed already, if not start bootloader anyway */
302327
if(pgm_read_byte_near(0x0000) != 0xFF) {
303328

304329
#ifdef __AVR_ATmega128__
305-
/* no UART was selected, start application */
306-
if(!bootuart) {
307-
app_start();
308-
}
330+
/* no UART was selected, start application */
331+
if(!bootuart) {
332+
app_start();
333+
}
309334
#else
310-
/* check if bootloader pin is set low */
311-
/* we don't start this part neither for the m8, nor m168 */
312-
//if(bit_is_set(BL_PIN, BL)) {
313-
// app_start();
314-
//}
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+
// }
315340
#endif
316341
}
317342

318-
#ifdef __AVR_ATmega128__
343+
#ifdef __AVR_ATmega128__
319344
/* no bootuart was selected, default to uart 0 */
320345
if(!bootuart) {
321346
bootuart = 1;
@@ -324,7 +349,7 @@ int main(void)
324349

325350

326351
/* initialize UART(s) depending on CPU defined */
327-
#ifdef __AVR_ATmega128__
352+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
328353
if(bootuart == 1) {
329354
UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
330355
UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
@@ -370,23 +395,32 @@ int main(void)
370395
UCSRB = _BV(TXEN)|_BV(RXEN);
371396
#endif
372397

398+
#if defined __AVR_ATmega1280__
399+
/* Enable internal pull-up resistor on pin D0 (RX), in order
400+
to supress line noise that prevents the bootloader from
401+
timing out (DAM: 20070509) */
402+
/* feature added to the Arduino Mega --DC: 080930 */
403+
DDRE &= ~_BV(PINE0);
404+
PORTE |= _BV(PINE0);
405+
#endif
406+
407+
373408
/* set LED pin as output */
374409
LED_DDR |= _BV(LED);
375410

376411

377412
/* flash onboard LED to signal entering of bootloader */
378-
#ifdef __AVR_ATmega128__
413+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
379414
// 4x for UART0, 5x for UART1
380415
flash_led(NUM_LED_FLASHES + bootuart);
381416
#else
382417
flash_led(NUM_LED_FLASHES);
383418
#endif
384419

385420
/* 20050803: by DojoCorp, this is one of the parts provoking the
386-
system to stop listening, cancelled from the original */
421+
system to stop listening, cancelled from the original */
387422
//putch('\0');
388423

389-
390424
/* forever loop */
391425
for (;;) {
392426

@@ -531,15 +565,18 @@ int main(void)
531565
else { //Write to FLASH one page at a time
532566
if (address.byte[1]>127) address_high = 0x01; //Only possible with m128, m256 will need 3rd address byte. FIXME
533567
else address_high = 0x00;
534-
#ifdef __AVR_ATmega128__
568+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
535569
RAMPZ = address_high;
536570
#endif
537571
address.word = address.word << 1; //address * 2 -> byte location
538572
/* if ((length.byte[0] & 0x01) == 0x01) length.word++; //Even up an odd number of bytes */
539573
if ((length.byte[0] & 0x01)) length.word++; //Even up an odd number of bytes
540574
cli(); //Disable interrupts, just to be sure
541-
// HACKME: EEPE used to be EEWE
575+
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
542576
while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete
577+
#else
578+
while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete
579+
#endif
543580
asm volatile(
544581
"clr r17 \n\t" //page_word_count
545582
"lds r30,address \n\t" //Address of FLASH location (in bytes)
@@ -634,7 +671,7 @@ int main(void)
634671
"rjmp write_page \n\t"
635672
"block_done: \n\t"
636673
"clr __zero_reg__ \n\t" //restore zero register
637-
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
674+
#if defined __AVR_ATmega168__ || __AVR_ATmega328P__ || __AVR_ATmega128__ || __AVR_ATmega1280__ || __AVR_ATmega1281__
638675
: "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
639676
#else
640677
: "=m" (SPMCR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
@@ -656,7 +693,7 @@ int main(void)
656693
else if(ch=='t') {
657694
length.byte[1] = getch();
658695
length.byte[0] = getch();
659-
#if defined __AVR_ATmega128__
696+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
660697
if (address.word>0x7FFF) flags.rampz = 1; // No go with m256, FIXME
661698
else flags.rampz = 0;
662699
#endif
@@ -680,7 +717,7 @@ int main(void)
680717
else {
681718

682719
if (!flags.rampz) putch(pgm_read_byte_near(address.word));
683-
#if defined __AVR_ATmega128__
720+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
684721
else putch(pgm_read_byte_far(address.word + 0x10000));
685722
// Hmmmm, yuck FIXME when m256 arrvies
686723
#endif
@@ -702,7 +739,7 @@ int main(void)
702739
putch(0x10);
703740
} else {
704741
if (++error_count == MAX_ERROR_COUNT)
705-
app_start();
742+
app_start();
706743
}
707744
}
708745

@@ -713,7 +750,7 @@ int main(void)
713750
}
714751

715752

716-
#ifdef MONITOR
753+
#if defined MONITOR
717754

718755
/* here come the extended monitor commands by Erik Lins */
719756

@@ -723,18 +760,20 @@ int main(void)
723760
if(ch=='!') {
724761
ch = getch();
725762
if(ch=='!') {
726-
727-
#ifdef __AVR_ATmega128__
763+
PGM_P welcome = "";
764+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
728765
uint16_t extaddr;
729766
#endif
730767
uint8_t addrl, addrh;
731768

732769
#ifdef CRUMB128
733-
PGM_P welcome = {"ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
770+
welcome = "ATmegaBOOT / Crumb128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
734771
#elif defined PROBOMEGA128
735-
PGM_P welcome = {"ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
772+
welcome = "ATmegaBOOT / PROBOmega128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
736773
#elif defined SAVVY128
737-
PGM_P welcome = {"ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r"};
774+
welcome = "ATmegaBOOT / Savvy128 - (C) J.P.Kyle, E.Lins - 050815\n\r";
775+
#elif defined __AVR_ATmega1280__
776+
welcome = "ATmegaBOOT / Arduino Mega - (C) Arduino LLC - 090930\n\r";
738777
#endif
739778

740779
/* turn on LED */
@@ -793,7 +832,7 @@ int main(void)
793832
putch(getch());
794833
}
795834
}
796-
#ifdef __AVR_ATmega128__
835+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
797836
/* external bus loop */
798837
else if(ch == 'b') {
799838
putch('b');
@@ -872,7 +911,7 @@ void puthex(char ch) {
872911

873912
void putch(char ch)
874913
{
875-
#ifdef __AVR_ATmega128__
914+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
876915
if(bootuart == 1) {
877916
while (!(UCSR0A & _BV(UDRE0)));
878917
UDR0 = ch;
@@ -894,13 +933,28 @@ void putch(char ch)
894933

895934
char getch(void)
896935
{
897-
#ifdef __AVR_ATmega128__
936+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
937+
uint32_t count = 0;
898938
if(bootuart == 1) {
899-
while(!(UCSR0A & _BV(RXC0)));
900-
return UDR0;
901-
}
939+
while(!(UCSR0A & _BV(RXC0))) {
940+
/* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
941+
/* HACKME:: here is a good place to count times*/
942+
count++;
943+
if (count > MAX_TIME_COUNT)
944+
app_start();
945+
}
946+
947+
return UDR0;
948+
}
902949
else if(bootuart == 2) {
903-
while(!(UCSR1A & _BV(RXC1)));
950+
while(!(UCSR1A & _BV(RXC1))) {
951+
/* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/
952+
/* HACKME:: here is a good place to count times*/
953+
count++;
954+
if (count > MAX_TIME_COUNT)
955+
app_start();
956+
}
957+
904958
return UDR1;
905959
}
906960
return 0;
@@ -932,7 +986,7 @@ char getch(void)
932986
void getNch(uint8_t count)
933987
{
934988
while(count--) {
935-
#ifdef __AVR_ATmega128__
989+
#if defined(__AVR_ATmega128__) || defined(__AVR_ATmega1280__)
936990
if(bootuart == 1) {
937991
while(!(UCSR0A & _BV(RXC0)));
938992
UDR0;

0 commit comments

Comments
 (0)