-
Notifications
You must be signed in to change notification settings - Fork 0
/
optiboot_miniwireless.lst
1464 lines (1338 loc) · 51.3 KB
/
optiboot_miniwireless.lst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
optiboot_miniwireless.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000004fa 00007800 00007800 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .version 00000002 00007ffe 00007ffe 0000056e 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .debug_aranges 00000028 00000000 00000000 00000570 2**0
CONTENTS, READONLY, DEBUGGING
3 .debug_pubnames 000000cd 00000000 00000000 00000598 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_info 0000082b 00000000 00000000 00000665 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_abbrev 0000027e 00000000 00000000 00000e90 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_line 0000091b 00000000 00000000 0000110e 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_frame 000000d0 00000000 00000000 00001a2c 2**2
CONTENTS, READONLY, DEBUGGING
8 .debug_str 0000022f 00000000 00000000 00001afc 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_loc 0000054f 00000000 00000000 00001d2b 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_ranges 00000158 00000000 00000000 0000227a 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00007800 <main>:
}
/******************* END SPI FLASH Code ****************************/
/* main program starts here */
int main(void) {
7800: 11 24 eor r1, r1
* modified Adaboot no-wait mod.
* Pass the reset reason to app. Also, it appears that an Uno poweron
* can leave multiple reset flags set; we only want the bootloader to
* run on an 'external reset only' status
*/
ch = MCUSR;
7802: 14 b7 in r17, 0x34 ; 52
MCUSR = 0;
7804: 14 be out 0x34, r1 ; 52
//ORIG.OPTIBOOT if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
//ORIG.OPTIBOOT appStart(ch);
if (!(ch & _BV(EXTRF))) //if not external reset
7806: 11 fd sbrc r17, 1
7808: 07 c0 rjmp .+14 ; 0x7818 <main+0x18>
{
if (ch & _BV(WDRF)) //if reset by watchdog
780a: 13 ff sbrs r17, 3
780c: 01 c0 rjmp .+2 ; 0x7810 <main+0x10>
CheckFlashImage();
780e: 67 d1 rcall .+718 ; 0x7ade <CheckFlashImage>
#ifdef DEBUG_ON
putch('A');
7810: 81 e4 ldi r24, 0x41 ; 65
7812: 3b d1 rcall .+630 ; 0x7a8a <putch>
#endif
appStart(ch);
7814: 81 2f mov r24, r17
7816: 6b d2 rcall .+1238 ; 0x7cee <appStart>
}
#if LED_START_FLASHES > 0
// Set up Timer 1 for timeout counter
TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
7818: 85 e0 ldi r24, 0x05 ; 5
781a: 80 93 81 00 sts 0x0081, r24
UCSRA = _BV(U2X); //Double speed mode USART
UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
#else
UART_SRA = _BV(U2X0); //Double speed mode USART0
781e: 82 e0 ldi r24, 0x02 ; 2
7820: 80 93 c0 00 sts 0x00C0, r24
UART_SRB = _BV(RXEN0) | _BV(TXEN0);
7824: 88 e1 ldi r24, 0x18 ; 24
7826: 80 93 c1 00 sts 0x00C1, r24
UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
782a: 86 e0 ldi r24, 0x06 ; 6
782c: 80 93 c2 00 sts 0x00C2, r24
UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
7830: 80 e1 ldi r24, 0x10 ; 16
7832: 80 93 c4 00 sts 0x00C4, r24
#endif
#endif
// Set up watchdog to trigger after 500ms
watchdogConfig(WATCHDOG_1S);
7836: 8e e0 ldi r24, 0x0E ; 14
7838: 3c d1 rcall .+632 ; 0x7ab2 <watchdogConfig>
#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
/* Set LED pin as output */
LED_DDR |= _BV(LED);
783a: 21 9a sbi 0x04, 1 ; 4
783c: 86 e0 ldi r24, 0x06 ; 6
}
#if LED_START_FLASHES > 0
void flash_led(uint8_t count) {
do {
TCNT1 = -(F_CPU/(1024*16));
783e: 20 e3 ldi r18, 0x30 ; 48
7840: 3c ef ldi r19, 0xFC ; 252
TIFR1 = _BV(TOV1);
7842: 91 e0 ldi r25, 0x01 ; 1
}
#if LED_START_FLASHES > 0
void flash_led(uint8_t count) {
do {
TCNT1 = -(F_CPU/(1024*16));
7844: 30 93 85 00 sts 0x0085, r19
7848: 20 93 84 00 sts 0x0084, r18
TIFR1 = _BV(TOV1);
784c: 96 bb out 0x16, r25 ; 22
while(!(TIFR1 & _BV(TOV1)));
784e: b0 9b sbis 0x16, 0 ; 22
7850: fe cf rjmp .-4 ; 0x784e <main+0x4e>
#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
LED_PORT ^= _BV(LED);
#else
LED_PIN |= _BV(LED);
7852: 19 9a sbi 0x03, 1 ; 3
}
#endif
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
7854: a8 95 wdr
LED_PORT ^= _BV(LED);
#else
LED_PIN |= _BV(LED);
#endif
watchdogReset();
} while (--count);
7856: 81 50 subi r24, 0x01 ; 1
7858: a9 f7 brne .-22 ; 0x7844 <main+0x44>
785a: ee 24 eor r14, r14
785c: ff 24 eor r15, r15
* Start the page erase and wait for it to finish. There
* used to be code to do this while receiving the data over
* the serial link, but the performance improvement was slight,
* and we needed the space back.
*/
__boot_page_erase_short((uint16_t)(void*)address);
785e: 83 e0 ldi r24, 0x03 ; 3
7860: b8 2e mov r11, r24
*/
do {
uint16_t a;
a = *bufPtr++;
a |= (*bufPtr++) << 8;
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
7862: aa 24 eor r10, r10
7864: a3 94 inc r10
} while (len -= 2);
/*
* Actually Write the buffer to flash (and wait for it to finish.)
*/
__boot_page_write_short((uint16_t)(void*)address);
7866: 05 e0 ldi r16, 0x05 ; 5
7868: d0 2e mov r13, r16
boot_spm_busy_wait();
#if defined(RWWSRE)
// Reenable read access to flash
boot_rww_enable();
786a: 11 e1 ldi r17, 0x11 ; 17
786c: c1 2e mov r12, r17
#endif
/* Forever loop: exits by causing WDT reset */
for (;;) {
/* get character from UART */
ch = getch();
786e: 15 d1 rcall .+554 ; 0x7a9a <getch>
if(ch == STK_GET_PARAMETER) {
7870: 81 34 cpi r24, 0x41 ; 65
7872: 71 f4 brne .+28 ; 0x7890 <main+0x90>
unsigned char which = getch();
7874: 12 d1 rcall .+548 ; 0x7a9a <getch>
7876: 18 2f mov r17, r24
verifySpace();
7878: 22 d1 rcall .+580 ; 0x7abe <verifySpace>
/*
* Send optiboot version as "SW version"
* Note that the references to memory are optimized away.
*/
if (which == 0x82) {
787a: 12 38 cpi r17, 0x82 ; 130
787c: 11 f4 brne .+4 ; 0x7882 <main+0x82>
putch(optiboot_version & 0xFF);
787e: 82 e0 ldi r24, 0x02 ; 2
7880: 05 c0 rjmp .+10 ; 0x788c <main+0x8c>
} else if (which == 0x81) {
7882: 11 38 cpi r17, 0x81 ; 129
7884: 11 f4 brne .+4 ; 0x788a <main+0x8a>
putch(optiboot_version >> 8);
7886: 8a e1 ldi r24, 0x1A ; 26
7888: 01 c0 rjmp .+2 ; 0x788c <main+0x8c>
} else {
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
788a: 83 e0 ldi r24, 0x03 ; 3
788c: fe d0 rcall .+508 ; 0x7a8a <putch>
788e: 9c c0 rjmp .+312 ; 0x79c8 <main+0x1c8>
}
}
else if(ch == STK_SET_DEVICE) {
7890: 82 34 cpi r24, 0x42 ; 66
7892: 11 f4 brne .+4 ; 0x7898 <main+0x98>
// SET DEVICE is ignored
getNch(20);
7894: 84 e1 ldi r24, 0x14 ; 20
7896: 03 c0 rjmp .+6 ; 0x789e <main+0x9e>
}
else if(ch == STK_SET_DEVICE_EXT) {
7898: 85 34 cpi r24, 0x45 ; 69
789a: 19 f4 brne .+6 ; 0x78a2 <main+0xa2>
// SET DEVICE EXT is ignored
getNch(5);
789c: 85 e0 ldi r24, 0x05 ; 5
789e: 17 d1 rcall .+558 ; 0x7ace <getNch>
78a0: 93 c0 rjmp .+294 ; 0x79c8 <main+0x1c8>
}
else if(ch == STK_LOAD_ADDRESS) {
78a2: 85 35 cpi r24, 0x55 ; 85
78a4: 79 f4 brne .+30 ; 0x78c4 <main+0xc4>
// LOAD ADDRESS
uint16_t newAddress;
newAddress = getch();
78a6: f9 d0 rcall .+498 ; 0x7a9a <getch>
newAddress = (newAddress & 0xff) | (getch() << 8);
78a8: e8 2e mov r14, r24
78aa: ff 24 eor r15, r15
78ac: f6 d0 rcall .+492 ; 0x7a9a <getch>
78ae: 08 2f mov r16, r24
78b0: 10 e0 ldi r17, 0x00 ; 0
78b2: 10 2f mov r17, r16
78b4: 00 27 eor r16, r16
78b6: 0e 29 or r16, r14
78b8: 1f 29 or r17, r15
#ifdef RAMPZ
// Transfer top bit to RAMPZ
RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif
newAddress += newAddress; // Convert from word address to byte address
78ba: 00 0f add r16, r16
78bc: 11 1f adc r17, r17
address = newAddress;
verifySpace();
78be: ff d0 rcall .+510 ; 0x7abe <verifySpace>
78c0: 78 01 movw r14, r16
78c2: 82 c0 rjmp .+260 ; 0x79c8 <main+0x1c8>
}
else if(ch == STK_UNIVERSAL) {
78c4: 86 35 cpi r24, 0x56 ; 86
78c6: 21 f4 brne .+8 ; 0x78d0 <main+0xd0>
// UNIVERSAL command is ignored
getNch(4);
78c8: 84 e0 ldi r24, 0x04 ; 4
78ca: 01 d1 rcall .+514 ; 0x7ace <getNch>
putch(0x00);
78cc: 80 e0 ldi r24, 0x00 ; 0
78ce: de cf rjmp .-68 ; 0x788c <main+0x8c>
}
/* Write memory, length is big endian and is in bytes */
else if(ch == STK_PROG_PAGE) {
78d0: 84 36 cpi r24, 0x64 ; 100
78d2: 09 f0 breq .+2 ; 0x78d6 <main+0xd6>
78d4: 4b c0 rjmp .+150 ; 0x796c <main+0x16c>
// PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t desttype;
uint8_t *bufPtr;
pagelen_t savelength;
GETLENGTH(length);
78d6: e1 d0 rcall .+450 ; 0x7a9a <getch>
78d8: e0 d0 rcall .+448 ; 0x7a9a <getch>
78da: 08 2f mov r16, r24
savelength = length;
desttype = getch();
78dc: de d0 rcall .+444 ; 0x7a9a <getch>
78de: 18 2f mov r17, r24
78e0: c0 e0 ldi r28, 0x00 ; 0
78e2: d1 e0 ldi r29, 0x01 ; 1
// read a page worth of contents
bufPtr = buff;
do *bufPtr++ = getch();
78e4: da d0 rcall .+436 ; 0x7a9a <getch>
78e6: 89 93 st Y+, r24
while (--length);
78e8: 0c 17 cp r16, r28
78ea: e1 f7 brne .-8 ; 0x78e4 <main+0xe4>
// Read command terminator, start reply
verifySpace();
78ec: e8 d0 rcall .+464 ; 0x7abe <verifySpace>
* void writebuffer(memtype, buffer, address, length)
*/
static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
uint16_t address, pagelen_t len)
{
switch (memtype) {
78ee: 15 34 cpi r17, 0x45 ; 69
78f0: b9 f4 brne .+46 ; 0x7920 <main+0x120>
78f2: 97 01 movw r18, r14
78f4: e0 e0 ldi r30, 0x00 ; 0
78f6: f1 e0 ldi r31, 0x01 ; 1
78f8: 10 c0 rjmp .+32 ; 0x791a <main+0x11a>
case 'E': // EEPROM
#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
while(len--) {
eeprom_write_byte((uint8_t *)(address++), *mybuff++);
78fa: 40 81 ld r20, Z
/** \ingroup avr_eeprom
Write a byte \a __value to EEPROM address \a __p.
*/
static __inline__ void eeprom_write_byte (uint8_t *__p, uint8_t __value)
{
do {} while (!eeprom_is_ready ());
78fc: f9 99 sbic 0x1f, 1 ; 31
78fe: fe cf rjmp .-4 ; 0x78fc <main+0xfc>
7900: c9 01 movw r24, r18
7902: 01 96 adiw r24, 0x01 ; 1
7904: 31 96 adiw r30, 0x01 ; 1
#if defined(EEPM0) && defined(EEPM1)
EECR = 0; /* Set programming mode: erase and write. */
7906: 1f ba out 0x1f, r1 ; 31
#endif
#if E2END <= 0xFF
EEARL = (unsigned)__p;
#else
EEAR = (unsigned)__p;
7908: 32 bd out 0x22, r19 ; 34
790a: 21 bd out 0x21, r18 ; 33
#endif
EEDR = __value;
790c: 40 bd out 0x20, r20 ; 32
__asm__ __volatile__ (
790e: 0f b6 in r0, 0x3f ; 63
7910: f8 94 cli
7912: fa 9a sbi 0x1f, 2 ; 31
7914: f9 9a sbi 0x1f, 1 ; 31
7916: 0f be out 0x3f, r0 ; 63
7918: 9c 01 movw r18, r24
uint16_t address, pagelen_t len)
{
switch (memtype) {
case 'E': // EEPROM
#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
while(len--) {
791a: 0e 17 cp r16, r30
791c: 71 f7 brne .-36 ; 0x78fa <main+0xfa>
791e: 54 c0 rjmp .+168 ; 0x79c8 <main+0x1c8>
* Start the page erase and wait for it to finish. There
* used to be code to do this while receiving the data over
* the serial link, but the performance improvement was slight,
* and we needed the space back.
*/
__boot_page_erase_short((uint16_t)(void*)address);
7920: f7 01 movw r30, r14
7922: b7 be out 0x37, r11 ; 55
7924: e8 95 spm
boot_spm_busy_wait();
7926: 07 b6 in r0, 0x37 ; 55
7928: 00 fc sbrc r0, 0
792a: fd cf rjmp .-6 ; 0x7926 <main+0x126>
792c: a7 01 movw r20, r14
792e: a0 e0 ldi r26, 0x00 ; 0
7930: b1 e0 ldi r27, 0x01 ; 1
/*
* Copy data from the buffer into the flash write buffer.
*/
do {
uint16_t a;
a = *bufPtr++;
7932: 2c 91 ld r18, X
7934: 30 e0 ldi r19, 0x00 ; 0
a |= (*bufPtr++) << 8;
7936: 11 96 adiw r26, 0x01 ; 1
7938: 8c 91 ld r24, X
793a: 11 97 sbiw r26, 0x01 ; 1
793c: 90 e0 ldi r25, 0x00 ; 0
793e: 98 2f mov r25, r24
7940: 88 27 eor r24, r24
7942: 82 2b or r24, r18
7944: 93 2b or r25, r19
}
/******************* END SPI FLASH Code ****************************/
/* main program starts here */
int main(void) {
7946: 12 96 adiw r26, 0x02 ; 2
*/
do {
uint16_t a;
a = *bufPtr++;
a |= (*bufPtr++) << 8;
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
7948: fa 01 movw r30, r20
794a: 0c 01 movw r0, r24
794c: a7 be out 0x37, r10 ; 55
794e: e8 95 spm
7950: 11 24 eor r1, r1
addrPtr += 2;
7952: 4e 5f subi r20, 0xFE ; 254
7954: 5f 4f sbci r21, 0xFF ; 255
} while (len -= 2);
7956: 0a 17 cp r16, r26
7958: 61 f7 brne .-40 ; 0x7932 <main+0x132>
/*
* Actually Write the buffer to flash (and wait for it to finish.)
*/
__boot_page_write_short((uint16_t)(void*)address);
795a: f7 01 movw r30, r14
795c: d7 be out 0x37, r13 ; 55
795e: e8 95 spm
boot_spm_busy_wait();
7960: 07 b6 in r0, 0x37 ; 55
7962: 00 fc sbrc r0, 0
7964: fd cf rjmp .-6 ; 0x7960 <main+0x160>
#if defined(RWWSRE)
// Reenable read access to flash
boot_rww_enable();
7966: c7 be out 0x37, r12 ; 55
7968: e8 95 spm
796a: 2e c0 rjmp .+92 ; 0x79c8 <main+0x1c8>
writebuffer(desttype, buff, address, savelength);
}
/* Read memory block mode, length is big endian. */
else if(ch == STK_READ_PAGE) {
796c: 84 37 cpi r24, 0x74 ; 116
796e: f1 f4 brne .+60 ; 0x79ac <main+0x1ac>
uint8_t desttype;
GETLENGTH(length);
7970: 94 d0 rcall .+296 ; 0x7a9a <getch>
7972: 93 d0 rcall .+294 ; 0x7a9a <getch>
7974: 08 2f mov r16, r24
desttype = getch();
7976: 91 d0 rcall .+290 ; 0x7a9a <getch>
7978: 18 2f mov r17, r24
verifySpace();
797a: a1 d0 rcall .+322 ; 0x7abe <verifySpace>
static inline void read_mem(uint8_t memtype, uint16_t address, pagelen_t length)
{
uint8_t ch;
switch (memtype) {
797c: 15 34 cpi r17, 0x45 ; 69
797e: 71 f4 brne .+28 ; 0x799c <main+0x19c>
7980: c7 01 movw r24, r14
#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
case 'E': // EEPROM
do {
putch(eeprom_read_byte((uint8_t *)(address++)));
7982: ec 01 movw r28, r24
7984: 21 96 adiw r28, 0x01 ; 1
/** \ingroup avr_eeprom
Read one byte from EEPROM address \a __p.
*/
__ATTR_PURE__ static __inline__ uint8_t eeprom_read_byte (const uint8_t *__p)
{
do {} while (!eeprom_is_ready ());
7986: f9 99 sbic 0x1f, 1 ; 31
7988: fe cf rjmp .-4 ; 0x7986 <main+0x186>
#if E2END <= 0xFF
EEARL = (uint8_t)(uint16_t)__p;
#else
EEAR = (uint16_t)__p;
798a: 92 bd out 0x22, r25 ; 34
798c: 81 bd out 0x21, r24 ; 33
/* Use inline assembly below as some AVRs have problems with accessing
EECR with STS instructions. For example, see errata for ATmega64.
The code below also assumes that EECR and EEDR are in the I/O space.
*/
uint8_t __result;
__asm__ __volatile__
798e: f8 9a sbi 0x1f, 0 ; 31
7990: 80 b5 in r24, 0x20 ; 32
7992: 7b d0 rcall .+246 ; 0x7a8a <putch>
} while (--length);
7994: 01 50 subi r16, 0x01 ; 1
7996: c1 f0 breq .+48 ; 0x79c8 <main+0x1c8>
7998: ce 01 movw r24, r28
799a: f3 cf rjmp .-26 ; 0x7982 <main+0x182>
799c: e7 01 movw r28, r14
__asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
#else
// read a Flash byte and increment the address
__asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
#endif
putch(ch);
799e: fe 01 movw r30, r28
79a0: 85 91 lpm r24, Z+
79a2: ef 01 movw r28, r30
79a4: 72 d0 rcall .+228 ; 0x7a8a <putch>
} while (--length);
79a6: 01 50 subi r16, 0x01 ; 1
79a8: d1 f7 brne .-12 ; 0x799e <main+0x19e>
79aa: 0e c0 rjmp .+28 ; 0x79c8 <main+0x1c8>
read_mem(desttype, address, length);
}
/* Get device signature bytes */
else if(ch == STK_READ_SIGN) {
79ac: 85 37 cpi r24, 0x75 ; 117
79ae: 39 f4 brne .+14 ; 0x79be <main+0x1be>
// READ SIGN - return what Avrdude wants to hear
verifySpace();
79b0: 86 d0 rcall .+268 ; 0x7abe <verifySpace>
putch(SIGNATURE_0);
79b2: 8e e1 ldi r24, 0x1E ; 30
79b4: 6a d0 rcall .+212 ; 0x7a8a <putch>
putch(SIGNATURE_1);
79b6: 85 e9 ldi r24, 0x95 ; 149
79b8: 68 d0 rcall .+208 ; 0x7a8a <putch>
putch(SIGNATURE_2);
79ba: 8f e0 ldi r24, 0x0F ; 15
79bc: 67 cf rjmp .-306 ; 0x788c <main+0x8c>
}
else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
79be: 81 35 cpi r24, 0x51 ; 81
79c0: 11 f4 brne .+4 ; 0x79c6 <main+0x1c6>
// Adaboot no-wait mod
watchdogConfig(WATCHDOG_16MS);
79c2: 88 e0 ldi r24, 0x08 ; 8
79c4: 76 d0 rcall .+236 ; 0x7ab2 <watchdogConfig>
verifySpace();
}
else {
// This covers the response to commands like STK_ENTER_PROGMODE
verifySpace();
79c6: 7b d0 rcall .+246 ; 0x7abe <verifySpace>
}
putch(STK_OK);
79c8: 80 e1 ldi r24, 0x10 ; 16
79ca: 5f d0 rcall .+190 ; 0x7a8a <putch>
79cc: 50 cf rjmp .-352 ; 0x786e <main+0x6e>
000079ce <SPI_transfer>:
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
79ce: 8e bd out 0x2e, r24 ; 46
while (!(SPSR & _BV(SPIF)));
79d0: 0d b4 in r0, 0x2d ; 45
79d2: 07 fe sbrs r0, 7
79d4: fd cf rjmp .-6 ; 0x79d0 <SPI_transfer+0x2>
return SPDR;
79d6: 8e b5 in r24, 0x2e ; 46
}
79d8: 08 95 ret
000079da <FLASH_busy>:
uint8_t FLASH_busy()
{
FLASH_SELECT;
79da: 5d 98 cbi 0x0b, 5 ; 11
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
79dc: 85 e0 ldi r24, 0x05 ; 5
79de: 8e bd out 0x2e, r24 ; 46
while (!(SPSR & _BV(SPIF)));
79e0: 0d b4 in r0, 0x2d ; 45
79e2: 07 fe sbrs r0, 7
79e4: fd cf rjmp .-6 ; 0x79e0 <FLASH_busy+0x6>
return SPDR;
79e6: 8e b5 in r24, 0x2e ; 46
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
79e8: 1e bc out 0x2e, r1 ; 46
while (!(SPSR & _BV(SPIF)));
79ea: 0d b4 in r0, 0x2d ; 45
79ec: 07 fe sbrs r0, 7
79ee: fd cf rjmp .-6 ; 0x79ea <FLASH_busy+0x10>
return SPDR;
79f0: 8e b5 in r24, 0x2e ; 46
uint8_t FLASH_busy()
{
FLASH_SELECT;
SPI_transfer(SPIFLASH_STATUSREAD);
uint8_t status = SPI_transfer(0);
FLASH_UNSELECT;
79f2: 5d 9a sbi 0x0b, 5 ; 11
return status & 1;
}
79f4: 81 70 andi r24, 0x01 ; 1
79f6: 08 95 ret
000079f8 <FLASH_command>:
void FLASH_command(uint8_t cmd, uint8_t isWrite){
79f8: 1f 93 push r17
79fa: 18 2f mov r17, r24
if (isWrite)
79fc: 66 23 and r22, r22
79fe: 21 f0 breq .+8 ; 0x7a08 <FLASH_command+0x10>
{
FLASH_command(SPIFLASH_WRITEENABLE, 0); // Write Enable
7a00: 86 e0 ldi r24, 0x06 ; 6
7a02: 60 e0 ldi r22, 0x00 ; 0
7a04: f9 df rcall .-14 ; 0x79f8 <FLASH_command>
FLASH_UNSELECT;
7a06: 5d 9a sbi 0x0b, 5 ; 11
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7a08: 95 e0 ldi r25, 0x05 ; 5
return SPDR;
}
uint8_t FLASH_busy()
{
FLASH_SELECT;
7a0a: 5d 98 cbi 0x0b, 5 ; 11
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7a0c: 9e bd out 0x2e, r25 ; 46
while (!(SPSR & _BV(SPIF)));
7a0e: 0d b4 in r0, 0x2d ; 45
7a10: 07 fe sbrs r0, 7
7a12: fd cf rjmp .-6 ; 0x7a0e <FLASH_command+0x16>
return SPDR;
7a14: 8e b5 in r24, 0x2e ; 46
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7a16: 1e bc out 0x2e, r1 ; 46
while (!(SPSR & _BV(SPIF)));
7a18: 0d b4 in r0, 0x2d ; 45
7a1a: 07 fe sbrs r0, 7
7a1c: fd cf rjmp .-6 ; 0x7a18 <FLASH_command+0x20>
return SPDR;
7a1e: 8e b5 in r24, 0x2e ; 46
uint8_t FLASH_busy()
{
FLASH_SELECT;
SPI_transfer(SPIFLASH_STATUSREAD);
uint8_t status = SPI_transfer(0);
FLASH_UNSELECT;
7a20: 5d 9a sbi 0x0b, 5 ; 11
if (isWrite)
{
FLASH_command(SPIFLASH_WRITEENABLE, 0); // Write Enable
FLASH_UNSELECT;
}
while(FLASH_busy()); //wait for chip to become available
7a22: 80 fd sbrc r24, 0
7a24: f2 cf rjmp .-28 ; 0x7a0a <FLASH_command+0x12>
FLASH_SELECT;
7a26: 5d 98 cbi 0x0b, 5 ; 11
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7a28: 1e bd out 0x2e, r17 ; 46
while (!(SPSR & _BV(SPIF)));
7a2a: 0d b4 in r0, 0x2d ; 45
7a2c: 07 fe sbrs r0, 7
7a2e: fd cf rjmp .-6 ; 0x7a2a <FLASH_command+0x32>
return SPDR;
7a30: 8e b5 in r24, 0x2e ; 46
FLASH_UNSELECT;
}
while(FLASH_busy()); //wait for chip to become available
FLASH_SELECT;
SPI_transfer(cmd);
}
7a32: 1f 91 pop r17
7a34: 08 95 ret
00007a36 <FLASH_readByte>:
uint8_t FLASH_readByte(uint32_t addr) {
7a36: ef 92 push r14
7a38: ff 92 push r15
7a3a: 0f 93 push r16
7a3c: 1f 93 push r17
7a3e: 7b 01 movw r14, r22
7a40: 8c 01 movw r16, r24
FLASH_command(SPIFLASH_ARRAYREADLOWFREQ, 0);
7a42: 83 e0 ldi r24, 0x03 ; 3
7a44: 60 e0 ldi r22, 0x00 ; 0
7a46: d8 df rcall .-80 ; 0x79f8 <FLASH_command>
SPI_transfer(addr >> 16);
7a48: c8 01 movw r24, r16
7a4a: aa 27 eor r26, r26
7a4c: bb 27 eor r27, r27
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7a4e: 8e bd out 0x2e, r24 ; 46
while (!(SPSR & _BV(SPIF)));
7a50: 0d b4 in r0, 0x2d ; 45
7a52: 07 fe sbrs r0, 7
7a54: fd cf rjmp .-6 ; 0x7a50 <FLASH_readByte+0x1a>
return SPDR;
7a56: 8e b5 in r24, 0x2e ; 46
}
uint8_t FLASH_readByte(uint32_t addr) {
FLASH_command(SPIFLASH_ARRAYREADLOWFREQ, 0);
SPI_transfer(addr >> 16);
SPI_transfer(addr >> 8);
7a58: bb 27 eor r27, r27
7a5a: a1 2f mov r26, r17
7a5c: 90 2f mov r25, r16
7a5e: 8f 2d mov r24, r15
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7a60: 8e bd out 0x2e, r24 ; 46
while (!(SPSR & _BV(SPIF)));
7a62: 0d b4 in r0, 0x2d ; 45
7a64: 07 fe sbrs r0, 7
7a66: fd cf rjmp .-6 ; 0x7a62 <FLASH_readByte+0x2c>
return SPDR;
7a68: 8e b5 in r24, 0x2e ; 46
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7a6a: ee bc out 0x2e, r14 ; 46
while (!(SPSR & _BV(SPIF)));
7a6c: 0d b4 in r0, 0x2d ; 45
7a6e: 07 fe sbrs r0, 7
7a70: fd cf rjmp .-6 ; 0x7a6c <FLASH_readByte+0x36>
return SPDR;
7a72: 8e b5 in r24, 0x2e ; 46
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7a74: 1e bc out 0x2e, r1 ; 46
while (!(SPSR & _BV(SPIF)));
7a76: 0d b4 in r0, 0x2d ; 45
7a78: 07 fe sbrs r0, 7
7a7a: fd cf rjmp .-6 ; 0x7a76 <FLASH_readByte+0x40>
return SPDR;
7a7c: 8e b5 in r24, 0x2e ; 46
SPI_transfer(addr >> 16);
SPI_transfer(addr >> 8);
SPI_transfer(addr);
//SPI.transfer(0); //"dont care", needed with SPIFLASH_ARRAYREAD command only
uint8_t result = SPI_transfer(0);
FLASH_UNSELECT;
7a7e: 5d 9a sbi 0x0b, 5 ; 11
return result;
}
7a80: 1f 91 pop r17
7a82: 0f 91 pop r16
7a84: ff 90 pop r15
7a86: ef 90 pop r14
7a88: 08 95 ret
00007a8a <putch>:
}
putch(STK_OK);
}
}
void putch(char ch) {
7a8a: 98 2f mov r25, r24
#ifndef SOFT_UART
while (!(UART_SRA & _BV(UDRE0)));
7a8c: 80 91 c0 00 lds r24, 0x00C0
7a90: 85 ff sbrs r24, 5
7a92: fc cf rjmp .-8 ; 0x7a8c <putch+0x2>
UART_UDR = ch;
7a94: 90 93 c6 00 sts 0x00C6, r25
[uartBit] "I" (UART_TX_BIT)
:
"r25"
);
#endif
}
7a98: 08 95 ret
00007a9a <getch>:
[uartBit] "I" (UART_RX_BIT)
:
"r25"
);
#else
while(!(UART_SRA & _BV(RXC0)))
7a9a: 80 91 c0 00 lds r24, 0x00C0
7a9e: 87 ff sbrs r24, 7
7aa0: fc cf rjmp .-8 ; 0x7a9a <getch>
;
if (!(UART_SRA & _BV(FE0))) {
7aa2: 80 91 c0 00 lds r24, 0x00C0
7aa6: 84 fd sbrc r24, 4
7aa8: 01 c0 rjmp .+2 ; 0x7aac <getch+0x12>
}
#endif
// Watchdog functions. These are only safe with interrupts turned off.
void watchdogReset() {
__asm__ __volatile__ (
7aaa: a8 95 wdr
* don't care that an invalid char is returned...)
*/
watchdogReset();
}
ch = UART_UDR;
7aac: 80 91 c6 00 lds r24, 0x00C6
LED_PIN |= _BV(LED);
#endif
#endif
return ch;
}
7ab0: 08 95 ret
00007ab2 <watchdogConfig>:
"wdr\n"
);
}
void watchdogConfig(uint8_t x) {
WDTCSR = _BV(WDCE) | _BV(WDE);
7ab2: e0 e6 ldi r30, 0x60 ; 96
7ab4: f0 e0 ldi r31, 0x00 ; 0
7ab6: 98 e1 ldi r25, 0x18 ; 24
7ab8: 90 83 st Z, r25
WDTCSR = x;
7aba: 80 83 st Z, r24
}
7abc: 08 95 ret
00007abe <verifySpace>:
do getch(); while (--count);
verifySpace();
}
void verifySpace() {
if (getch() != CRC_EOP) {
7abe: ed df rcall .-38 ; 0x7a9a <getch>
7ac0: 80 32 cpi r24, 0x20 ; 32
7ac2: 19 f0 breq .+6 ; 0x7aca <verifySpace+0xc>
watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
7ac4: 88 e0 ldi r24, 0x08 ; 8
7ac6: f5 df rcall .-22 ; 0x7ab2 <watchdogConfig>
7ac8: ff cf rjmp .-2 ; 0x7ac8 <verifySpace+0xa>
while (1) // and busy-loop so that WD causes
; // a reset and app start.
}
putch(STK_INSYNC);
7aca: 84 e1 ldi r24, 0x14 ; 20
}
7acc: de cf rjmp .-68 ; 0x7a8a <putch>
00007ace <getNch>:
::[count] "M" (UART_B_VALUE)
);
}
#endif
void getNch(uint8_t count) {
7ace: 1f 93 push r17
7ad0: 18 2f mov r17, r24
do getch(); while (--count);
7ad2: e3 df rcall .-58 ; 0x7a9a <getch>
7ad4: 11 50 subi r17, 0x01 ; 1
7ad6: e9 f7 brne .-6 ; 0x7ad2 <getNch+0x4>
verifySpace();
7ad8: f2 df rcall .-28 ; 0x7abe <verifySpace>
}
7ada: 1f 91 pop r17
7adc: 08 95 ret
00007ade <CheckFlashImage>:
uint8_t result = SPI_transfer(0);
FLASH_UNSELECT;
return result;
}
void CheckFlashImage() {
7ade: 9f 92 push r9
7ae0: af 92 push r10
7ae2: bf 92 push r11
7ae4: cf 92 push r12
7ae6: df 92 push r13
7ae8: ef 92 push r14
7aea: ff 92 push r15
7aec: 0f 93 push r16
7aee: 1f 93 push r17
7af0: cf 93 push r28
7af2: df 93 push r29
#ifdef DEBUG_ON
putch('F');
7af4: 86 e4 ldi r24, 0x46 ; 70
7af6: c9 df rcall .-110 ; 0x7a8a <putch>
#endif
watchdogConfig(WATCHDOG_OFF);
7af8: 80 e0 ldi r24, 0x00 ; 0
7afa: db df rcall .-74 ; 0x7ab2 <watchdogConfig>
#ifdef ANARDUINO
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
DDRB |= _BV(SS) | _BV(PINB3) | _BV(PINB5); //OUTPUTS for SS, MOSI, SCK
7afc: 84 b1 in r24, 0x04 ; 4
7afe: 8c 62 ori r24, 0x2C ; 44
7b00: 84 b9 out 0x04, r24 ; 4
DDRD |= _BV(FLASHSS); //OUTPUTS for FLASH_SS
7b02: 55 9a sbi 0x0a, 5 ; 10
FLASH_UNSELECT; //unselect FLASH chip
7b04: 5d 9a sbi 0x0b, 5 ; 11
PORTB |= _BV(SS); //set SS HIGH
7b06: 2a 9a sbi 0x05, 2 ; 5
//SPCR = (SPCR & ~SPI_MODE_MASK) | SPI_MODE0 ; //SPI MODE 0
//SPCR = (SPCR & ~SPI_CLOCK_MASK) | (SPI_CLOCK_DIV2 & SPI_CLOCK_MASK); //clock divider = 2
//SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((SPI_CLOCK_DIV2 >> 2) & SPI_2XCLOCK_MASK);
// Warning: if the SS pin ever becomes a LOW INPUT then SPI automatically switches to Slave, so the data direction of the SS pin MUST be kept as OUTPUT.
SPCR |= _BV(MSTR) | _BV(SPE); //enable SPI and set SPI to MASTER mode
7b08: 8c b5 in r24, 0x2c ; 44
7b0a: 80 65 ori r24, 0x50 ; 80
7b0c: 8c bd out 0x2c, r24 ; 44
//read first byte of JEDECID, if chip is present it should return a non-0 and non-FF value
FLASH_SELECT;
7b0e: 5d 98 cbi 0x0b, 5 ; 11
#define DEBUG_ON // uncomment to enable Serial debugging
// (will output different characters depending on which path the bootloader takes)
uint8_t SPI_transfer(uint8_t _data) {
SPDR = _data;
7b10: 8f e9 ldi r24, 0x9F ; 159
7b12: 8e bd out 0x2e, r24 ; 46
while (!(SPSR & _BV(SPIF)));
7b14: 0d b4 in r0, 0x2d ; 45
7b16: 07 fe sbrs r0, 7
7b18: fd cf rjmp .-6 ; 0x7b14 <CheckFlashImage+0x36>
return SPDR;
7b1a: 8e b5 in r24, 0x2e ; 46