소스 검색

Add bootloader files for ATmega1284/Sanguino

Added the optiboot bootloader, uses only 512kB of FLASH
Includes .hex file is for 20MHz µC Clock and serial speed of 57k6
Dirk Eichel 12 년 전
부모
커밋
f991bf23b2

+ 470
- 0
ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/Makefile 파일 보기

@@ -0,0 +1,470 @@
1
+# Makefile for ATmegaBOOT
2
+# E.Lins, 18.7.2005
3
+# $Id$
4
+#
5
+# Instructions
6
+#
7
+# To make bootloader .hex file:
8
+# make diecimila
9
+# make lilypad
10
+# make ng
11
+# etc...
12
+#
13
+# To burn bootloader .hex file:
14
+# make diecimila_isp
15
+# make lilypad_isp
16
+# make ng_isp
17
+# etc...
18
+
19
+# program name should not be changed...
20
+PROGRAM    = optiboot
21
+
22
+# The default behavior is to build using tools that are in the users
23
+# current path variables, but we can also build using an installed
24
+# Arduino user IDE setup, or the Arduino source tree.
25
+# Uncomment this next lines to build within the arduino environment,
26
+# using the arduino-included avrgcc toolset (mac and pc)
27
+# ENV ?= arduino
28
+# ENV ?= arduinodev
29
+# OS ?= macosx
30
+# OS ?= windows
31
+
32
+
33
+# enter the parameters for the avrdude isp tool
34
+ISPTOOL    = stk500v2
35
+ISPPORT    = usb
36
+ISPSPEED   = -b 115200
37
+
38
+MCU_TARGET = atmega168
39
+LDSECTIONS  = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
40
+
41
+# Build environments
42
+# Start of some ugly makefile-isms to allow optiboot to be built
43
+# in several different environments.  See the README.TXT file for
44
+# details.
45
+
46
+# default
47
+fixpath = $(1)
48
+
49
+ifeq ($(ENV), arduino)
50
+# For Arduino, we assume that we're connected to the optiboot directory
51
+# included with the arduino distribution, which means that the full set
52
+# of avr-tools are "right up there" in standard places.
53
+TOOLROOT = ../../../tools
54
+GCCROOT = $(TOOLROOT)/avr/bin/
55
+AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
56
+
57
+ifeq ($(OS), windows)
58
+# On windows, SOME of the tool paths will need to have backslashes instead
59
+# of forward slashes (because they use windows cmd.exe for execution instead
60
+# of a unix/mingw shell?)  We also have to ensure that a consistent shell
61
+# is used even if a unix shell is installed (ie as part of WINAVR)
62
+fixpath = $(subst /,\,$1)
63
+SHELL = cmd.exe
64
+endif
65
+
66
+else ifeq ($(ENV), arduinodev)
67
+# Arduino IDE source code environment.  Use the unpacked compilers created
68
+# by the build (you'll need to do "ant build" first.)
69
+ifeq ($(OS), macosx)
70
+TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools
71
+endif
72
+ifeq ($(OS), windows)
73
+TOOLROOT = ../../../../build/windows/work/hardware/tools
74
+endif
75
+
76
+GCCROOT = $(TOOLROOT)/avr/bin/
77
+AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
78
+
79
+else
80
+GCCROOT =
81
+AVRDUDE_CONF =
82
+endif
83
+#
84
+# End of build environment code.
85
+
86
+
87
+# the efuse should really be 0xf8; since, however, only the lower
88
+# three bits of that byte are used on the atmega168, avrdude gets
89
+# confused if you specify 1's for the higher bits, see:
90
+# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
91
+#
92
+# similarly, the lock bits should be 0xff instead of 0x3f (to
93
+# unlock the bootloader section) and 0xcf instead of 0x2f (to
94
+# lock it), but since the high two bits of the lock byte are
95
+# unused, avrdude would get confused.
96
+
97
+ISPFUSES    = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
98
+              -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
99
+              -e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
100
+              -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
101
+ISPFLASH    = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
102
+              -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
103
+              -U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
104
+
105
+STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
106
+STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
107
+-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt
108
+STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt
109
+
110
+OBJ        = $(PROGRAM).o
111
+OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls
112
+
113
+DEFS       = 
114
+LIBS       =
115
+
116
+CC         = $(GCCROOT)avr-gcc
117
+
118
+# Override is only needed by avr-lib build system.
119
+
120
+override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
121
+override LDFLAGS       = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
122
+
123
+OBJCOPY        = $(GCCROOT)avr-objcopy
124
+OBJDUMP        = $(call fixpath,$(GCCROOT)avr-objdump)
125
+
126
+SIZE           = $(GCCROOT)avr-size
127
+
128
+# Test platforms
129
+# Virtual boot block test
130
+virboot328: TARGET = atmega328
131
+virboot328: MCU_TARGET = atmega328p
132
+virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT'
133
+virboot328: AVR_FREQ = 16000000L
134
+virboot328: LDSECTIONS  = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
135
+virboot328: $(PROGRAM)_atmega328.hex
136
+virboot328: $(PROGRAM)_atmega328.lst
137
+
138
+# 20MHz clocked platforms
139
+#
140
+# These are capable of 230400 baud, or 115200 baud on PC (Arduino Avrdude issue)
141
+#
142
+
143
+pro20: TARGET = pro_20mhz
144
+pro20: MCU_TARGET = atmega168
145
+pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
146
+pro20: AVR_FREQ = 20000000L
147
+pro20: $(PROGRAM)_pro_20mhz.hex
148
+pro20: $(PROGRAM)_pro_20mhz.lst
149
+
150
+pro20_isp: pro20
151
+pro20_isp: TARGET = pro_20mhz
152
+# 2.7V brownout
153
+pro20_isp: HFUSE = DD
154
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
155
+pro20_isp: LFUSE = C6
156
+# 512 byte boot
157
+pro20_isp: EFUSE = 04
158
+pro20_isp: isp
159
+
160
+# 16MHz clocked platforms
161
+#
162
+# These are capable of 230400 baud, or 115200 baud on PC (Arduino Avrdude issue)
163
+#
164
+
165
+pro16: TARGET = pro_16MHz
166
+pro16: MCU_TARGET = atmega168
167
+pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
168
+pro16: AVR_FREQ = 16000000L
169
+pro16: $(PROGRAM)_pro_16MHz.hex
170
+pro16: $(PROGRAM)_pro_16MHz.lst
171
+
172
+pro16_isp: pro16
173
+pro16_isp: TARGET = pro_16MHz
174
+# 2.7V brownout
175
+pro16_isp: HFUSE = DD
176
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
177
+pro16_isp: LFUSE = C6
178
+# 512 byte boot
179
+pro16_isp: EFUSE = 04
180
+pro16_isp: isp
181
+
182
+# Diecimila, Duemilanove with m168, and NG use identical bootloaders
183
+# Call it "atmega168" for generality and clarity, keep "diecimila" for
184
+# backward compatibility of makefile
185
+#
186
+atmega168: TARGET = atmega168
187
+atmega168: MCU_TARGET = atmega168
188
+atmega168: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
189
+atmega168: AVR_FREQ = 16000000L 
190
+atmega168: $(PROGRAM)_atmega168.hex
191
+atmega168: $(PROGRAM)_atmega168.lst
192
+
193
+atmega168_isp: atmega168
194
+atmega168_isp: TARGET = atmega168
195
+# 2.7V brownout
196
+atmega168_isp: HFUSE = DD
197
+# Low power xtal (16MHz) 16KCK/14CK+65ms
198
+atmega168_isp: LFUSE = FF
199
+# 512 byte boot
200
+atmega168_isp: EFUSE = 04
201
+atmega168_isp: isp
202
+
203
+diecimila: TARGET = diecimila
204
+diecimila: MCU_TARGET = atmega168
205
+diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
206
+diecimila: AVR_FREQ = 16000000L 
207
+diecimila: $(PROGRAM)_diecimila.hex
208
+diecimila: $(PROGRAM)_diecimila.lst
209
+
210
+diecimila_isp: diecimila
211
+diecimila_isp: TARGET = diecimila
212
+# 2.7V brownout
213
+diecimila_isp: HFUSE = DD
214
+# Low power xtal (16MHz) 16KCK/14CK+65ms
215
+diecimila_isp: LFUSE = FF
216
+# 512 byte boot
217
+diecimila_isp: EFUSE = 04
218
+diecimila_isp: isp
219
+
220
+atmega328: TARGET = atmega328
221
+atmega328: MCU_TARGET = atmega328p
222
+atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
223
+atmega328: AVR_FREQ = 16000000L
224
+atmega328: LDSECTIONS  = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
225
+atmega328: $(PROGRAM)_atmega328.hex
226
+atmega328: $(PROGRAM)_atmega328.lst
227
+
228
+atmega328_isp: atmega328
229
+atmega328_isp: TARGET = atmega328
230
+atmega328_isp: MCU_TARGET = atmega328p
231
+# 512 byte boot, SPIEN
232
+atmega328_isp: HFUSE = DE
233
+# Low power xtal (16MHz) 16KCK/14CK+65ms
234
+atmega328_isp: LFUSE = FF
235
+# 2.7V brownout
236
+atmega328_isp: EFUSE = 05
237
+atmega328_isp: isp
238
+
239
+atmega1284: TARGET = atmega1284p
240
+atmega1284: MCU_TARGET = atmega1284p
241
+atmega1284: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
242
+atmega1284: AVR_FREQ = 16000000L
243
+atmega1284: LDSECTIONS  = -Wl,--section-start=.text=0x1fc00
244
+atmega1284: $(PROGRAM)_atmega1284p.hex
245
+atmega1284: $(PROGRAM)_atmega1284p.lst
246
+
247
+atmega1284_isp: atmega1284
248
+atmega1284_isp: TARGET = atmega1284p
249
+atmega1284_isp: MCU_TARGET = atmega1284p
250
+# 1024 byte boot
251
+atmega1284_isp: HFUSE = DE
252
+# Low power xtal (16MHz) 16KCK/14CK+65ms
253
+atmega1284_isp: LFUSE = FF
254
+# 2.7V brownout
255
+atmega1284_isp: EFUSE = FD
256
+atmega1284_isp: isp
257
+
258
+# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
259
+#
260
+sanguino: TARGET = atmega644p
261
+sanguino: MCU_TARGET = atmega644p
262
+sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
263
+sanguino: AVR_FREQ = 16000000L
264
+sanguino: LDSECTIONS  = -Wl,--section-start=.text=0xfc00
265
+sanguino: $(PROGRAM)_atmega644p.hex
266
+sanguino: $(PROGRAM)_atmega644p.lst
267
+
268
+sanguino_isp: sanguino
269
+sanguino_isp: TARGET = atmega644p
270
+sanguino_isp: MCU_TARGET = atmega644p
271
+# 1024 byte boot
272
+sanguino_isp: HFUSE = DE
273
+# Low power xtal (16MHz) 16KCK/14CK+65ms
274
+sanguino_isp: LFUSE = FF
275
+# 2.7V brownout
276
+sanguino_isp: EFUSE = 05
277
+sanguino_isp: isp
278
+
279
+# Mega has a minimum boot size of 1024 bytes, so enable extra functions
280
+#mega: TARGET = atmega1280
281
+mega: MCU_TARGET = atmega1280
282
+mega: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
283
+mega: AVR_FREQ = 16000000L
284
+mega: LDSECTIONS  = -Wl,--section-start=.text=0x1fc00
285
+mega: $(PROGRAM)_atmega1280.hex
286
+mega: $(PROGRAM)_atmega1280.lst
287
+
288
+mega_isp: mega
289
+mega_isp: TARGET = atmega1280
290
+mega_isp: MCU_TARGET = atmega1280
291
+# 1024 byte boot
292
+mega_isp: HFUSE = DE
293
+# Low power xtal (16MHz) 16KCK/14CK+65ms
294
+mega_isp: LFUSE = FF
295
+# 2.7V brownout
296
+mega_isp: EFUSE = 05
297
+mega_isp: isp
298
+
299
+# ATmega8
300
+#
301
+atmega8: TARGET = atmega8
302
+atmega8: MCU_TARGET = atmega8
303
+atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
304
+atmega8: AVR_FREQ = 16000000L 
305
+atmega8: LDSECTIONS  = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
306
+atmega8: $(PROGRAM)_atmega8.hex
307
+atmega8: $(PROGRAM)_atmega8.lst
308
+
309
+atmega8_isp: atmega8
310
+atmega8_isp: TARGET = atmega8
311
+atmega8_isp: MCU_TARGET = atmega8
312
+# SPIEN, CKOPT, Bootsize=512B
313
+atmega8_isp: HFUSE = CC
314
+# 2.7V brownout, Low power xtal (16MHz) 16KCK/14CK+65ms
315
+atmega8_isp: LFUSE = BF
316
+atmega8_isp: isp
317
+
318
+# ATmega88
319
+#
320
+atmega88: TARGET = atmega88
321
+atmega88: MCU_TARGET = atmega88
322
+atmega88: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
323
+atmega88: AVR_FREQ = 16000000L 
324
+atmega88: LDSECTIONS  = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
325
+atmega88: $(PROGRAM)_atmega88.hex
326
+atmega88: $(PROGRAM)_atmega88.lst
327
+
328
+atmega88_isp: atmega88
329
+atmega88_isp: TARGET = atmega88
330
+atmega88_isp: MCU_TARGET = atmega88
331
+# 2.7V brownout
332
+atmega88_isp: HFUSE = DD
333
+# Low power xtal (16MHz) 16KCK/14CK+65ms
334
+atemga88_isp: LFUSE = FF
335
+# 512 byte boot
336
+atmega88_isp: EFUSE = 04
337
+atmega88_isp: isp
338
+
339
+
340
+# 8MHz clocked platforms
341
+#
342
+# These are capable of 115200 baud
343
+#
344
+
345
+lilypad: TARGET = lilypad
346
+lilypad: MCU_TARGET = atmega168
347
+lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
348
+lilypad: AVR_FREQ = 8000000L
349
+lilypad: $(PROGRAM)_lilypad.hex
350
+lilypad: $(PROGRAM)_lilypad.lst
351
+
352
+lilypad_isp: lilypad
353
+lilypad_isp: TARGET = lilypad
354
+# 2.7V brownout
355
+lilypad_isp: HFUSE = DD
356
+# Internal 8MHz osc (8MHz) Slow rising power
357
+lilypad_isp: LFUSE = E2
358
+# 512 byte boot
359
+lilypad_isp: EFUSE = 04
360
+lilypad_isp: isp
361
+
362
+lilypad_resonator: TARGET = lilypad_resonator
363
+lilypad_resonator: MCU_TARGET = atmega168
364
+lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
365
+lilypad_resonator: AVR_FREQ = 8000000L
366
+lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
367
+lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst
368
+
369
+lilypad_resonator_isp: lilypad_resonator
370
+lilypad_resonator_isp: TARGET = lilypad_resonator
371
+# 2.7V brownout
372
+lilypad_resonator_isp: HFUSE = DD
373
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
374
+lilypad_resonator_isp: LFUSE = C6
375
+# 512 byte boot
376
+lilypad_resonator_isp: EFUSE = 04
377
+lilypad_resonator_isp: isp
378
+
379
+pro8: TARGET = pro_8MHz
380
+pro8: MCU_TARGET = atmega168
381
+pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
382
+pro8: AVR_FREQ = 8000000L
383
+pro8: $(PROGRAM)_pro_8MHz.hex
384
+pro8: $(PROGRAM)_pro_8MHz.lst
385
+
386
+pro8_isp: pro8
387
+pro8_isp: TARGET = pro_8MHz
388
+# 2.7V brownout
389
+pro8_isp: HFUSE = DD
390
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
391
+pro8_isp: LFUSE = C6
392
+# 512 byte boot
393
+pro8_isp: EFUSE = 04
394
+pro8_isp: isp
395
+
396
+atmega328_pro8: TARGET = atmega328_pro_8MHz
397
+atmega328_pro8: MCU_TARGET = atmega328p
398
+atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
399
+atmega328_pro8: AVR_FREQ = 8000000L
400
+atmega328_pro8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
401
+atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
402
+atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
403
+
404
+atmega328_pro8_isp: atmega328_pro8
405
+atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
406
+atmega328_pro8_isp: MCU_TARGET = atmega328p
407
+# 512 byte boot, SPIEN
408
+atmega328_pro8_isp: HFUSE = DE
409
+# Low power xtal (16MHz) 16KCK/14CK+65ms
410
+atmega328_pro8_isp: LFUSE = FF
411
+# 2.7V brownout
412
+atmega328_pro8_isp: EFUSE = 05
413
+atmega328_pro8_isp: isp
414
+
415
+# 1MHz clocked platforms
416
+#
417
+# These are capable of 9600 baud
418
+#
419
+
420
+luminet: TARGET = luminet
421
+luminet: MCU_TARGET = attiny84
422
+luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
423
+luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
424
+luminet: AVR_FREQ = 1000000L
425
+luminet: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe
426
+luminet: $(PROGRAM)_luminet.hex
427
+luminet: $(PROGRAM)_luminet.lst
428
+
429
+luminet_isp: luminet
430
+luminet_isp: TARGET = luminet
431
+luminet_isp: MCU_TARGET = attiny84
432
+# Brownout disabled
433
+luminet_isp: HFUSE = DF
434
+# 1MHz internal oscillator, slowly rising power
435
+luminet_isp: LFUSE = 62
436
+# Self-programming enable
437
+luminet_isp: EFUSE = FE
438
+luminet_isp: isp
439
+
440
+#
441
+# Generic build instructions
442
+#
443
+#
444
+
445
+isp: $(TARGET)
446
+        $(ISPFUSES)
447
+        $(ISPFLASH)
448
+
449
+isp-stk500: $(PROGRAM)_$(TARGET).hex
450
+        $(STK500-1)
451
+        $(STK500-2)
452
+
453
+%.elf: $(OBJ)
454
+        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
455
+        $(SIZE) $@
456
+
457
+clean:
458
+        rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
459
+
460
+%.lst: %.elf
461
+        $(OBJDUMP) -h -S $< > $@
462
+
463
+%.hex: %.elf
464
+        $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
465
+
466
+%.srec: %.elf
467
+        $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
468
+
469
+%.bin: %.elf
470
+        $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@

+ 848
- 0
ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/boot.h 파일 보기

@@ -0,0 +1,848 @@
1
+/* Modified to use out for SPM access
2
+** Peter Knight, Optiboot project http://optiboot.googlecode.com
3
+**
4
+** Todo: Tidy up
5
+**
6
+** "_short" routines execute 1 cycle faster and use 1 less word of flash
7
+** by using "out" instruction instead of "sts".
8
+**
9
+** Additional elpm variants that trust the value of RAMPZ
10
+*/
11
+
12
+/* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007  Eric B. Weddington
13
+   All rights reserved.
14
+
15
+   Redistribution and use in source and binary forms, with or without
16
+   modification, are permitted provided that the following conditions are met:
17
+
18
+   * Redistributions of source code must retain the above copyright
19
+     notice, this list of conditions and the following disclaimer.
20
+   * Redistributions in binary form must reproduce the above copyright
21
+     notice, this list of conditions and the following disclaimer in
22
+     the documentation and/or other materials provided with the
23
+     distribution.
24
+   * Neither the name of the copyright holders nor the names of
25
+     contributors may be used to endorse or promote products derived
26
+     from this software without specific prior written permission.
27
+
28
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
+  POSSIBILITY OF SUCH DAMAGE. */
39
+
40
+/* $Id: boot.h,v 1.27.2.3 2008/09/30 13:58:48 arcanum Exp $ */
41
+
42
+#ifndef _AVR_BOOT_H_
43
+#define _AVR_BOOT_H_    1
44
+
45
+/** \file */
46
+/** \defgroup avr_boot <avr/boot.h>: Bootloader Support Utilities
47
+    \code
48
+    #include <avr/io.h>
49
+    #include <avr/boot.h>
50
+    \endcode
51
+
52
+    The macros in this module provide a C language interface to the
53
+    bootloader support functionality of certain AVR processors. These
54
+    macros are designed to work with all sizes of flash memory.
55
+
56
+    Global interrupts are not automatically disabled for these macros. It
57
+    is left up to the programmer to do this. See the code example below. 
58
+    Also see the processor datasheet for caveats on having global interrupts 
59
+    enabled during writing of the Flash.
60
+
61
+    \note Not all AVR processors provide bootloader support. See your
62
+    processor datasheet to see if it provides bootloader support.
63
+
64
+    \todo From email with Marek: On smaller devices (all except ATmega64/128),
65
+    __SPM_REG is in the I/O space, accessible with the shorter "in" and "out"
66
+    instructions - since the boot loader has a limited size, this could be an
67
+    important optimization.
68
+
69
+    \par API Usage Example
70
+    The following code shows typical usage of the boot API.
71
+
72
+    \code
73
+    #include <inttypes.h>
74
+    #include <avr/interrupt.h>
75
+    #include <avr/pgmspace.h>
76
+    
77
+    void boot_program_page (uint32_t page, uint8_t *buf)
78
+    {
79
+        uint16_t i;
80
+        uint8_t sreg;
81
+
82
+        // Disable interrupts.
83
+
84
+        sreg = SREG;
85
+        cli();
86
+    
87
+        eeprom_busy_wait ();
88
+
89
+        boot_page_erase (page);
90
+        boot_spm_busy_wait ();      // Wait until the memory is erased.
91
+
92
+        for (i=0; i<SPM_PAGESIZE; i+=2)
93
+        {
94
+            // Set up little-endian word.
95
+
96
+            uint16_t w = *buf++;
97
+            w += (*buf++) << 8;
98
+        
99
+            boot_page_fill (page + i, w);
100
+        }
101
+
102
+        boot_page_write (page);     // Store buffer in flash page.
103
+        boot_spm_busy_wait();       // Wait until the memory is written.
104
+
105
+        // Reenable RWW-section again. We need this if we want to jump back
106
+        // to the application after bootloading.
107
+
108
+        boot_rww_enable ();
109
+
110
+        // Re-enable interrupts (if they were ever enabled).
111
+
112
+        SREG = sreg;
113
+    }\endcode */
114
+
115
+#include <avr/eeprom.h>
116
+#include <avr/io.h>
117
+#include <inttypes.h>
118
+#include <limits.h>
119
+
120
+/* Check for SPM Control Register in processor. */
121
+#if defined (SPMCSR)
122
+#  define __SPM_REG    SPMCSR
123
+#elif defined (SPMCR)
124
+#  define __SPM_REG    SPMCR
125
+#else
126
+#  error AVR processor does not provide bootloader support!
127
+#endif
128
+
129
+
130
+/* Check for SPM Enable bit. */
131
+#if defined(SPMEN)
132
+#  define __SPM_ENABLE  SPMEN
133
+#elif defined(SELFPRGEN)
134
+#  define __SPM_ENABLE  SELFPRGEN
135
+#else
136
+#  error Cannot find SPM Enable bit definition!
137
+#endif
138
+
139
+/** \ingroup avr_boot
140
+    \def BOOTLOADER_SECTION
141
+
142
+    Used to declare a function or variable to be placed into a
143
+    new section called .bootloader. This section and its contents
144
+    can then be relocated to any address (such as the bootloader
145
+    NRWW area) at link-time. */
146
+
147
+#define BOOTLOADER_SECTION    __attribute__ ((section (".bootloader")))
148
+
149
+/* Create common bit definitions. */
150
+#ifdef ASB
151
+#define __COMMON_ASB    ASB
152
+#else
153
+#define __COMMON_ASB    RWWSB
154
+#endif
155
+
156
+#ifdef ASRE
157
+#define __COMMON_ASRE   ASRE
158
+#else
159
+#define __COMMON_ASRE   RWWSRE
160
+#endif
161
+
162
+/* Define the bit positions of the Boot Lock Bits. */
163
+
164
+#define BLB12           5
165
+#define BLB11           4
166
+#define BLB02           3
167
+#define BLB01           2
168
+
169
+/** \ingroup avr_boot
170
+    \def boot_spm_interrupt_enable()
171
+    Enable the SPM interrupt. */
172
+
173
+#define boot_spm_interrupt_enable()   (__SPM_REG |= (uint8_t)_BV(SPMIE))
174
+
175
+/** \ingroup avr_boot
176
+    \def boot_spm_interrupt_disable()
177
+    Disable the SPM interrupt. */
178
+
179
+#define boot_spm_interrupt_disable()  (__SPM_REG &= (uint8_t)~_BV(SPMIE))
180
+
181
+/** \ingroup avr_boot
182
+    \def boot_is_spm_interrupt()
183
+    Check if the SPM interrupt is enabled. */
184
+
185
+#define boot_is_spm_interrupt()       (__SPM_REG & (uint8_t)_BV(SPMIE))
186
+
187
+/** \ingroup avr_boot
188
+    \def boot_rww_busy()
189
+    Check if the RWW section is busy. */
190
+
191
+#define boot_rww_busy()          (__SPM_REG & (uint8_t)_BV(__COMMON_ASB))
192
+
193
+/** \ingroup avr_boot
194
+    \def boot_spm_busy()
195
+    Check if the SPM instruction is busy. */
196
+
197
+#define boot_spm_busy()               (__SPM_REG & (uint8_t)_BV(__SPM_ENABLE))
198
+
199
+/** \ingroup avr_boot
200
+    \def boot_spm_busy_wait()
201
+    Wait while the SPM instruction is busy. */
202
+
203
+#define boot_spm_busy_wait()          do{}while(boot_spm_busy())
204
+
205
+#define __BOOT_PAGE_ERASE         (_BV(__SPM_ENABLE) | _BV(PGERS))
206
+#define __BOOT_PAGE_WRITE         (_BV(__SPM_ENABLE) | _BV(PGWRT))
207
+#define __BOOT_PAGE_FILL          _BV(__SPM_ENABLE)
208
+#define __BOOT_RWW_ENABLE         (_BV(__SPM_ENABLE) | _BV(__COMMON_ASRE))
209
+#define __BOOT_LOCK_BITS_SET      (_BV(__SPM_ENABLE) | _BV(BLBSET))
210
+
211
+#define __boot_page_fill_short(address, data)   \
212
+(__extension__({                                 \
213
+    __asm__ __volatile__                         \
214
+    (                                            \
215
+        "movw  r0, %3\n\t"                       \
216
+        "out %0, %1\n\t"                         \
217
+        "spm\n\t"                                \
218
+        "clr  r1\n\t"                            \
219
+        :                                        \
220
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
221
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
222
+          "z" ((uint16_t)address),               \
223
+          "r" ((uint16_t)data)                   \
224
+        : "r0"                                   \
225
+    );                                           \
226
+}))
227
+
228
+#define __boot_page_fill_normal(address, data)   \
229
+(__extension__({                                 \
230
+    __asm__ __volatile__                         \
231
+    (                                            \
232
+        "movw  r0, %3\n\t"                       \
233
+        "sts %0, %1\n\t"                         \
234
+        "spm\n\t"                                \
235
+        "clr  r1\n\t"                            \
236
+        :                                        \
237
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
238
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
239
+          "z" ((uint16_t)address),               \
240
+          "r" ((uint16_t)data)                   \
241
+        : "r0"                                   \
242
+    );                                           \
243
+}))
244
+
245
+#define __boot_page_fill_alternate(address, data)\
246
+(__extension__({                                 \
247
+    __asm__ __volatile__                         \
248
+    (                                            \
249
+        "movw  r0, %3\n\t"                       \
250
+        "sts %0, %1\n\t"                         \
251
+        "spm\n\t"                                \
252
+        ".word 0xffff\n\t"                       \
253
+        "nop\n\t"                                \
254
+        "clr  r1\n\t"                            \
255
+        :                                        \
256
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
257
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
258
+          "z" ((uint16_t)address),               \
259
+          "r" ((uint16_t)data)                   \
260
+        : "r0"                                   \
261
+    );                                           \
262
+}))
263
+
264
+#define __boot_page_fill_extended(address, data) \
265
+(__extension__({                                 \
266
+    __asm__ __volatile__                         \
267
+    (                                            \
268
+        "movw  r0, %4\n\t"                       \
269
+        "movw r30, %A3\n\t"                      \
270
+        "sts %1, %C3\n\t"                        \
271
+        "sts %0, %2\n\t"                         \
272
+        "spm\n\t"                                \
273
+        "clr  r1\n\t"                            \
274
+        :                                        \
275
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
276
+          "i" (_SFR_MEM_ADDR(RAMPZ)),            \
277
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
278
+          "r" ((uint32_t)address),               \
279
+          "r" ((uint16_t)data)                   \
280
+        : "r0", "r30", "r31"                     \
281
+    );                                           \
282
+}))
283
+
284
+#define __boot_page_fill_extended_short(address, data) \
285
+(__extension__({                                 \
286
+    __asm__ __volatile__                         \
287
+    (                                            \
288
+        "movw  r0, %4\n\t"                       \
289
+        "movw r30, %A3\n\t"                      \
290
+        "out %1, %C3\n\t"                        \
291
+        "out %0, %2\n\t"                         \
292
+        "spm\n\t"                                \
293
+        "clr  r1\n\t"                            \
294
+        :                                        \
295
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
296
+          "i" (_SFR_IO_ADDR(RAMPZ)),            \
297
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
298
+          "r" ((uint32_t)address),               \
299
+          "r" ((uint16_t)data)                   \
300
+        : "r0", "r30", "r31"                     \
301
+    );                                           \
302
+}))
303
+
304
+#define __boot_page_erase_short(address)        \
305
+(__extension__({                                 \
306
+    __asm__ __volatile__                         \
307
+    (                                            \
308
+        "out %0, %1\n\t"                         \
309
+        "spm\n\t"                                \
310
+        :                                        \
311
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
312
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
313
+          "z" ((uint16_t)address)                \
314
+    );                                           \
315
+}))
316
+
317
+
318
+#define __boot_page_erase_normal(address)        \
319
+(__extension__({                                 \
320
+    __asm__ __volatile__                         \
321
+    (                                            \
322
+        "sts %0, %1\n\t"                         \
323
+        "spm\n\t"                                \
324
+        :                                        \
325
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
326
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
327
+          "z" ((uint16_t)address)                \
328
+    );                                           \
329
+}))
330
+
331
+#define __boot_page_erase_alternate(address)     \
332
+(__extension__({                                 \
333
+    __asm__ __volatile__                         \
334
+    (                                            \
335
+        "sts %0, %1\n\t"                         \
336
+        "spm\n\t"                                \
337
+        ".word 0xffff\n\t"                       \
338
+        "nop\n\t"                                \
339
+        :                                        \
340
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
341
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
342
+          "z" ((uint16_t)address)                \
343
+    );                                           \
344
+}))
345
+
346
+#define __boot_page_erase_extended(address)      \
347
+(__extension__({                                 \
348
+    __asm__ __volatile__                         \
349
+    (                                            \
350
+        "movw r30, %A3\n\t"                      \
351
+        "sts  %1, %C3\n\t"                       \
352
+        "sts %0, %2\n\t"                         \
353
+        "spm\n\t"                                \
354
+        :                                        \
355
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
356
+          "i" (_SFR_MEM_ADDR(RAMPZ)),            \
357
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
358
+          "r" ((uint32_t)address)                \
359
+        : "r30", "r31"                           \
360
+    );                                           \
361
+}))
362
+#define __boot_page_erase_extended_short(address)      \
363
+(__extension__({                                 \
364
+    __asm__ __volatile__                         \
365
+    (                                            \
366
+        "movw r30, %A3\n\t"                      \
367
+        "out  %1, %C3\n\t"                       \
368
+        "out %0, %2\n\t"                         \
369
+        "spm\n\t"                                \
370
+        :                                        \
371
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
372
+          "i" (_SFR_IO_ADDR(RAMPZ)),            \
373
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
374
+          "r" ((uint32_t)address)                \
375
+        : "r30", "r31"                           \
376
+    );                                           \
377
+}))
378
+
379
+#define __boot_page_write_short(address)        \
380
+(__extension__({                                 \
381
+    __asm__ __volatile__                         \
382
+    (                                            \
383
+        "out %0, %1\n\t"                         \
384
+        "spm\n\t"                                \
385
+        :                                        \
386
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
387
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
388
+          "z" ((uint16_t)address)                \
389
+    );                                           \
390
+}))
391
+
392
+#define __boot_page_write_normal(address)        \
393
+(__extension__({                                 \
394
+    __asm__ __volatile__                         \
395
+    (                                            \
396
+        "sts %0, %1\n\t"                         \
397
+        "spm\n\t"                                \
398
+        :                                        \
399
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
400
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
401
+          "z" ((uint16_t)address)                \
402
+    );                                           \
403
+}))
404
+
405
+#define __boot_page_write_alternate(address)     \
406
+(__extension__({                                 \
407
+    __asm__ __volatile__                         \
408
+    (                                            \
409
+        "sts %0, %1\n\t"                         \
410
+        "spm\n\t"                                \
411
+        ".word 0xffff\n\t"                       \
412
+        "nop\n\t"                                \
413
+        :                                        \
414
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
415
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
416
+          "z" ((uint16_t)address)                \
417
+    );                                           \
418
+}))
419
+
420
+#define __boot_page_write_extended(address)      \
421
+(__extension__({                                 \
422
+    __asm__ __volatile__                         \
423
+    (                                            \
424
+        "movw r30, %A3\n\t"                      \
425
+        "sts %1, %C3\n\t"                        \
426
+        "sts %0, %2\n\t"                         \
427
+        "spm\n\t"                                \
428
+        :                                        \
429
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
430
+          "i" (_SFR_MEM_ADDR(RAMPZ)),            \
431
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
432
+          "r" ((uint32_t)address)                \
433
+        : "r30", "r31"                           \
434
+    );                                           \
435
+}))
436
+#define __boot_page_write_extended_short(address)      \
437
+(__extension__({                                 \
438
+    __asm__ __volatile__                         \
439
+    (                                            \
440
+        "movw r30, %A3\n\t"                      \
441
+        "out %1, %C3\n\t"                        \
442
+        "out %0, %2\n\t"                         \
443
+        "spm\n\t"                                \
444
+        :                                        \
445
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
446
+          "i" (_SFR_IO_ADDR(RAMPZ)),            \
447
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
448
+          "r" ((uint32_t)address)                \
449
+        : "r30", "r31"                           \
450
+    );                                           \
451
+}))
452
+
453
+#define __boot_rww_enable_short()                      \
454
+(__extension__({                                 \
455
+    __asm__ __volatile__                         \
456
+    (                                            \
457
+        "out %0, %1\n\t"                         \
458
+        "spm\n\t"                                \
459
+        :                                        \
460
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
461
+          "r" ((uint8_t)__BOOT_RWW_ENABLE)       \
462
+    );                                           \
463
+}))
464
+
465
+#define __boot_rww_enable()                      \
466
+(__extension__({                                 \
467
+    __asm__ __volatile__                         \
468
+    (                                            \
469
+        "sts %0, %1\n\t"                         \
470
+        "spm\n\t"                                \
471
+        :                                        \
472
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
473
+          "r" ((uint8_t)__BOOT_RWW_ENABLE)       \
474
+    );                                           \
475
+}))
476
+
477
+#define __boot_rww_enable_alternate()            \
478
+(__extension__({                                 \
479
+    __asm__ __volatile__                         \
480
+    (                                            \
481
+        "sts %0, %1\n\t"                         \
482
+        "spm\n\t"                                \
483
+        ".word 0xffff\n\t"                       \
484
+        "nop\n\t"                                \
485
+        :                                        \
486
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
487
+          "r" ((uint8_t)__BOOT_RWW_ENABLE)       \
488
+    );                                           \
489
+}))
490
+
491
+/* From the mega16/mega128 data sheets (maybe others):
492
+
493
+     Bits by SPM To set the Boot Loader Lock bits, write the desired data to
494
+     R0, write "X0001001" to SPMCR and execute SPM within four clock cycles
495
+     after writing SPMCR. The only accessible Lock bits are the Boot Lock bits
496
+     that may prevent the Application and Boot Loader section from any
497
+     software update by the MCU.
498
+
499
+     If bits 5..2 in R0 are cleared (zero), the corresponding Boot Lock bit
500
+     will be programmed if an SPM instruction is executed within four cycles
501
+     after BLBSET and SPMEN (or SELFPRGEN) are set in SPMCR. The Z-pointer is 
502
+     don't care during this operation, but for future compatibility it is 
503
+     recommended to load the Z-pointer with $0001 (same as used for reading the 
504
+     Lock bits). For future compatibility It is also recommended to set bits 7, 
505
+     6, 1, and 0 in R0 to 1 when writing the Lock bits. When programming the 
506
+     Lock bits the entire Flash can be read during the operation. */
507
+
508
+#define __boot_lock_bits_set_short(lock_bits)                    \
509
+(__extension__({                                           \
510
+    uint8_t value = (uint8_t)(~(lock_bits));               \
511
+    __asm__ __volatile__                                   \
512
+    (                                                      \
513
+        "ldi r30, 1\n\t"                                   \
514
+        "ldi r31, 0\n\t"                                   \
515
+        "mov r0, %2\n\t"                                   \
516
+        "out %0, %1\n\t"                                   \
517
+        "spm\n\t"                                          \
518
+        :                                                  \
519
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),                  \
520
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
521
+          "r" (value)                                      \
522
+        : "r0", "r30", "r31"                               \
523
+    );                                                     \
524
+}))
525
+
526
+#define __boot_lock_bits_set(lock_bits)                    \
527
+(__extension__({                                           \
528
+    uint8_t value = (uint8_t)(~(lock_bits));               \
529
+    __asm__ __volatile__                                   \
530
+    (                                                      \
531
+        "ldi r30, 1\n\t"                                   \
532
+        "ldi r31, 0\n\t"                                   \
533
+        "mov r0, %2\n\t"                                   \
534
+        "sts %0, %1\n\t"                                   \
535
+        "spm\n\t"                                          \
536
+        :                                                  \
537
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \
538
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
539
+          "r" (value)                                      \
540
+        : "r0", "r30", "r31"                               \
541
+    );                                                     \
542
+}))
543
+
544
+#define __boot_lock_bits_set_alternate(lock_bits)          \
545
+(__extension__({                                           \
546
+    uint8_t value = (uint8_t)(~(lock_bits));               \
547
+    __asm__ __volatile__                                   \
548
+    (                                                      \
549
+        "ldi r30, 1\n\t"                                   \
550
+        "ldi r31, 0\n\t"                                   \
551
+        "mov r0, %2\n\t"                                   \
552
+        "sts %0, %1\n\t"                                   \
553
+        "spm\n\t"                                          \
554
+        ".word 0xffff\n\t"                                 \
555
+        "nop\n\t"                                          \
556
+        :                                                  \
557
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \
558
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
559
+          "r" (value)                                      \
560
+        : "r0", "r30", "r31"                               \
561
+    );                                                     \
562
+}))
563
+
564
+/*
565
+   Reading lock and fuse bits:
566
+
567
+     Similarly to writing the lock bits above, set BLBSET and SPMEN (or 
568
+     SELFPRGEN) bits in __SPMREG, and then (within four clock cycles) issue an 
569
+     LPM instruction.
570
+
571
+     Z address:       contents:
572
+     0x0000           low fuse bits
573
+     0x0001           lock bits
574
+     0x0002           extended fuse bits
575
+     0x0003           high fuse bits
576
+
577
+     Sounds confusing, doesn't it?
578
+
579
+     Unlike the macros in pgmspace.h, no need to care for non-enhanced
580
+     cores here as these old cores do not provide SPM support anyway.
581
+ */
582
+
583
+/** \ingroup avr_boot
584
+    \def GET_LOW_FUSE_BITS
585
+    address to read the low fuse bits, using boot_lock_fuse_bits_get
586
+ */
587
+#define GET_LOW_FUSE_BITS           (0x0000)
588
+/** \ingroup avr_boot
589
+    \def GET_LOCK_BITS
590
+    address to read the lock bits, using boot_lock_fuse_bits_get
591
+ */
592
+#define GET_LOCK_BITS               (0x0001)
593
+/** \ingroup avr_boot
594
+    \def GET_EXTENDED_FUSE_BITS
595
+    address to read the extended fuse bits, using boot_lock_fuse_bits_get
596
+ */
597
+#define GET_EXTENDED_FUSE_BITS      (0x0002)
598
+/** \ingroup avr_boot
599
+    \def GET_HIGH_FUSE_BITS
600
+    address to read the high fuse bits, using boot_lock_fuse_bits_get
601
+ */
602
+#define GET_HIGH_FUSE_BITS          (0x0003)
603
+
604
+/** \ingroup avr_boot
605
+    \def boot_lock_fuse_bits_get(address)
606
+
607
+    Read the lock or fuse bits at \c address.
608
+
609
+    Parameter \c address can be any of GET_LOW_FUSE_BITS,
610
+    GET_LOCK_BITS, GET_EXTENDED_FUSE_BITS, or GET_HIGH_FUSE_BITS.
611
+
612
+    \note The lock and fuse bits returned are the physical values,
613
+    i.e. a bit returned as 0 means the corresponding fuse or lock bit
614
+    is programmed.
615
+ */
616
+#define boot_lock_fuse_bits_get_short(address)                   \
617
+(__extension__({                                           \
618
+    uint8_t __result;                                      \
619
+    __asm__ __volatile__                                   \
620
+    (                                                      \
621
+        "ldi r30, %3\n\t"                                  \
622
+        "ldi r31, 0\n\t"                                   \
623
+        "out %1, %2\n\t"                                   \
624
+        "lpm %0, Z\n\t"                                    \
625
+        : "=r" (__result)                                  \
626
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),                  \
627
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
628
+          "M" (address)                                    \
629
+        : "r0", "r30", "r31"                               \
630
+    );                                                     \
631
+    __result;                                              \
632
+}))
633
+
634
+#define boot_lock_fuse_bits_get(address)                   \
635
+(__extension__({                                           \
636
+    uint8_t __result;                                      \
637
+    __asm__ __volatile__                                   \
638
+    (                                                      \
639
+        "ldi r30, %3\n\t"                                  \
640
+        "ldi r31, 0\n\t"                                   \
641
+        "sts %1, %2\n\t"                                   \
642
+        "lpm %0, Z\n\t"                                    \
643
+        : "=r" (__result)                                  \
644
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \
645
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
646
+          "M" (address)                                    \
647
+        : "r0", "r30", "r31"                               \
648
+    );                                                     \
649
+    __result;                                              \
650
+}))
651
+
652
+/** \ingroup avr_boot
653
+    \def boot_signature_byte_get(address)
654
+
655
+    Read the Signature Row byte at \c address.  For some MCU types,
656
+    this function can also retrieve the factory-stored oscillator
657
+    calibration bytes.
658
+
659
+    Parameter \c address can be 0-0x1f as documented by the datasheet.
660
+    \note The values are MCU type dependent.
661
+*/
662
+
663
+#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
664
+
665
+#define boot_signature_byte_get_short(addr) \
666
+(__extension__({                      \
667
+      uint16_t __addr16 = (uint16_t)(addr);     \
668
+      uint8_t __result;                         \
669
+      __asm__ __volatile__                      \
670
+      (                                         \
671
+        "out %1, %2\n\t"                        \
672
+        "lpm %0, Z" "\n\t"                      \
673
+        : "=r" (__result)                       \
674
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
675
+          "r" ((uint8_t) __BOOT_SIGROW_READ),   \
676
+          "z" (__addr16)                        \
677
+      );                                        \
678
+      __result;                                 \
679
+}))
680
+
681
+#define boot_signature_byte_get(addr) \
682
+(__extension__({                      \
683
+      uint16_t __addr16 = (uint16_t)(addr);     \
684
+      uint8_t __result;                         \
685
+      __asm__ __volatile__                      \
686
+      (                                         \
687
+        "sts %1, %2\n\t"                        \
688
+        "lpm %0, Z" "\n\t"                      \
689
+        : "=r" (__result)                       \
690
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),       \
691
+          "r" ((uint8_t) __BOOT_SIGROW_READ),   \
692
+          "z" (__addr16)                        \
693
+      );                                        \
694
+      __result;                                 \
695
+}))
696
+
697
+/** \ingroup avr_boot
698
+    \def boot_page_fill(address, data)
699
+
700
+    Fill the bootloader temporary page buffer for flash 
701
+    address with data word. 
702
+
703
+    \note The address is a byte address. The data is a word. The AVR 
704
+    writes data to the buffer a word at a time, but addresses the buffer
705
+    per byte! So, increment your address by 2 between calls, and send 2
706
+    data bytes in a word format! The LSB of the data is written to the lower 
707
+    address; the MSB of the data is written to the higher address.*/
708
+
709
+/** \ingroup avr_boot
710
+    \def boot_page_erase(address)
711
+
712
+    Erase the flash page that contains address.
713
+
714
+    \note address is a byte address in flash, not a word address. */
715
+
716
+/** \ingroup avr_boot
717
+    \def boot_page_write(address)
718
+
719
+    Write the bootloader temporary page buffer 
720
+    to flash page that contains address.
721
+    
722
+    \note address is a byte address in flash, not a word address. */
723
+
724
+/** \ingroup avr_boot
725
+    \def boot_rww_enable()
726
+
727
+    Enable the Read-While-Write memory section. */
728
+
729
+/** \ingroup avr_boot
730
+    \def boot_lock_bits_set(lock_bits)
731
+
732
+    Set the bootloader lock bits.
733
+
734
+    \param lock_bits A mask of which Boot Loader Lock Bits to set.
735
+
736
+    \note In this context, a 'set bit' will be written to a zero value.
737
+    Note also that only BLBxx bits can be programmed by this command.
738
+
739
+    For example, to disallow the SPM instruction from writing to the Boot
740
+    Loader memory section of flash, you would use this macro as such:
741
+
742
+    \code
743
+    boot_lock_bits_set (_BV (BLB11));
744
+    \endcode
745
+
746
+    \note Like any lock bits, the Boot Loader Lock Bits, once set,
747
+    cannot be cleared again except by a chip erase which will in turn
748
+    also erase the boot loader itself. */
749
+
750
+/* Normal versions of the macros use 16-bit addresses.
751
+   Extended versions of the macros use 32-bit addresses.
752
+   Alternate versions of the macros use 16-bit addresses and require special
753
+   instruction sequences after LPM.
754
+
755
+   FLASHEND is defined in the ioXXXX.h file.
756
+   USHRT_MAX is defined in <limits.h>. */ 
757
+
758
+#if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \
759
+    || defined(__AVR_ATmega323__)
760
+
761
+/* Alternate: ATmega161/163/323 and 16 bit address */
762
+#define boot_page_fill(address, data) __boot_page_fill_alternate(address, data)
763
+#define boot_page_erase(address)      __boot_page_erase_alternate(address)
764
+#define boot_page_write(address)      __boot_page_write_alternate(address)
765
+#define boot_rww_enable()             __boot_rww_enable_alternate()
766
+#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits)
767
+
768
+#elif (FLASHEND > USHRT_MAX)
769
+
770
+/* Extended: >16 bit address */
771
+#define boot_page_fill(address, data) __boot_page_fill_extended_short(address, data)
772
+#define boot_page_erase(address)      __boot_page_erase_extended_short(address)
773
+#define boot_page_write(address)      __boot_page_write_extended_short(address)
774
+#define boot_rww_enable()             __boot_rww_enable_short()
775
+#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits)
776
+
777
+#else
778
+
779
+/* Normal: 16 bit address */
780
+#define boot_page_fill(address, data) __boot_page_fill_short(address, data)
781
+#define boot_page_erase(address)      __boot_page_erase_short(address)
782
+#define boot_page_write(address)      __boot_page_write_short(address)
783
+#define boot_rww_enable()             __boot_rww_enable_short()
784
+#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits)
785
+
786
+#endif
787
+
788
+/** \ingroup avr_boot
789
+
790
+    Same as boot_page_fill() except it waits for eeprom and spm operations to
791
+    complete before filling the page. */
792
+
793
+#define boot_page_fill_safe(address, data) \
794
+do { \
795
+    boot_spm_busy_wait();                       \
796
+    eeprom_busy_wait();                         \
797
+    boot_page_fill(address, data);              \
798
+} while (0)
799
+
800
+/** \ingroup avr_boot
801
+
802
+    Same as boot_page_erase() except it waits for eeprom and spm operations to
803
+    complete before erasing the page. */
804
+
805
+#define boot_page_erase_safe(address) \
806
+do { \
807
+    boot_spm_busy_wait();                       \
808
+    eeprom_busy_wait();                         \
809
+    boot_page_erase (address);                  \
810
+} while (0)
811
+
812
+/** \ingroup avr_boot
813
+
814
+    Same as boot_page_write() except it waits for eeprom and spm operations to
815
+    complete before writing the page. */
816
+
817
+#define boot_page_write_safe(address) \
818
+do { \
819
+    boot_spm_busy_wait();                       \
820
+    eeprom_busy_wait();                         \
821
+    boot_page_write (address);                  \
822
+} while (0)
823
+
824
+/** \ingroup avr_boot
825
+
826
+    Same as boot_rww_enable() except waits for eeprom and spm operations to
827
+    complete before enabling the RWW mameory. */
828
+
829
+#define boot_rww_enable_safe() \
830
+do { \
831
+    boot_spm_busy_wait();                       \
832
+    eeprom_busy_wait();                         \
833
+    boot_rww_enable();                          \
834
+} while (0)
835
+
836
+/** \ingroup avr_boot
837
+
838
+    Same as boot_lock_bits_set() except waits for eeprom and spm operations to
839
+    complete before setting the lock bits. */
840
+
841
+#define boot_lock_bits_set_safe(lock_bits) \
842
+do { \
843
+    boot_spm_busy_wait();                       \
844
+    eeprom_busy_wait();                         \
845
+    boot_lock_bits_set (lock_bits);             \
846
+} while (0)
847
+
848
+#endif /* _AVR_BOOT_H_ */

+ 724
- 0
ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/optiboot.c 파일 보기

@@ -0,0 +1,724 @@
1
+/**********************************************************/
2
+/* -Wl,-section-start=bootloader=0x1fc00 */
3
+/* Optiboot bootloader for Arduino                        */
4
+/*                                                        */
5
+/* http://optiboot.googlecode.com                         */
6
+/*                                                        */
7
+/* Arduino-maintained version : See README.TXT            */
8
+/* http://code.google.com/p/arduino/                      */
9
+/*                                                        */
10
+/* Heavily optimised bootloader that is faster and        */
11
+/* smaller than the Arduino standard bootloader           */
12
+/*                                                        */
13
+/* Enhancements:                                          */
14
+/*   Fits in 512 bytes, saving 1.5K of code space         */
15
+/*   Background page erasing speeds up programming        */
16
+/*   Higher baud rate speeds up programming               */
17
+/*   Written almost entirely in C                         */
18
+/*   Customisable timeout with accurate timeconstant      */
19
+/*   Optional virtual UART. No hardware UART required.    */
20
+/*   Optional virtual boot partition for devices without. */
21
+/*                                                        */
22
+/* What you lose:                                         */
23
+/*   Implements a skeleton STK500 protocol which is       */
24
+/*     missing several features including EEPROM          */
25
+/*     programming and non-page-aligned writes            */
26
+/*   High baud rate breaks compatibility with standard    */
27
+/*     Arduino flash settings                             */
28
+/*                                                        */
29
+/* Fully supported:                                       */
30
+/*   ATmega168 based devices  (Diecimila etc)             */
31
+/*   ATmega328P based devices (Duemilanove etc)           */
32
+/*                                                        */
33
+/* Alpha test                                             */
34
+/*   ATmega1280 based devices (Arduino Mega)              */
35
+/*                                                        */
36
+/* Work in progress:                                      */
37
+/*   ATmega644P based devices (Sanguino)                  */
38
+/*   ATtiny84 based devices (Luminet)                     */
39
+/*                                                        */
40
+/* Does not support:                                      */
41
+/*   USB based devices (eg. Teensy)                       */
42
+/*                                                        */
43
+/* Assumptions:                                           */
44
+/*   The code makes several assumptions that reduce the   */
45
+/*   code size. They are all true after a hardware reset, */
46
+/*   but may not be true if the bootloader is called by   */
47
+/*   other means or on other hardware.                    */
48
+/*     No interrupts can occur                            */
49
+/*     UART and Timer 1 are set to their reset state      */
50
+/*     SP points to RAMEND                                */
51
+/*                                                        */
52
+/* Code builds on code, libraries and optimisations from: */
53
+/*   stk500boot.c          by Jason P. Kyle               */
54
+/*   Arduino bootloader    http://arduino.cc              */
55
+/*   Spiff's 1K bootloader http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml */
56
+/*   avr-libc project      http://nongnu.org/avr-libc     */
57
+/*   Adaboot               http://www.ladyada.net/library/arduino/bootloader.html */
58
+/*   AVR305                Atmel Application Note         */
59
+/*                                                        */
60
+/* This program is free software; you can redistribute it */
61
+/* and/or modify it under the terms of the GNU General    */
62
+/* Public License as published by the Free Software       */
63
+/* Foundation; either version 2 of the License, or        */
64
+/* (at your option) any later version.                    */
65
+/*                                                        */
66
+/* This program is distributed in the hope that it will   */
67
+/* be useful, but WITHOUT ANY WARRANTY; without even the  */
68
+/* implied warranty of MERCHANTABILITY or FITNESS FOR A   */
69
+/* PARTICULAR PURPOSE.  See the GNU General Public        */
70
+/* License for more details.                              */
71
+/*                                                        */
72
+/* You should have received a copy of the GNU General     */
73
+/* Public License along with this program; if not, write  */
74
+/* to the Free Software Foundation, Inc.,                 */
75
+/* 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
76
+/*                                                        */
77
+/* Licence can be viewed at                               */
78
+/* http://www.fsf.org/licenses/gpl.txt                    */
79
+/*                                                        */
80
+/**********************************************************/
81
+
82
+
83
+/**********************************************************/
84
+/*                                                        */
85
+/* Optional defines:                                      */
86
+/*                                                        */
87
+/**********************************************************/
88
+/*                                                        */
89
+/* BIG_BOOT:                                              */
90
+/* Build a 1k bootloader, not 512 bytes. This turns on    */
91
+/* extra functionality.                                   */
92
+/*                                                        */
93
+/* BAUD_RATE:                                             */
94
+/* Set bootloader baud rate.                              */
95
+/*                                                        */
96
+/* LUDICROUS_SPEED:                                       */
97
+/* 230400 baud :-)                                        */
98
+/*                                                        */
99
+/* SOFT_UART:                                             */
100
+/* Use AVR305 soft-UART instead of hardware UART.         */
101
+/*                                                        */
102
+/* LED_START_FLASHES:                                     */
103
+/* Number of LED flashes on bootup.                       */
104
+/*                                                        */
105
+/* LED_DATA_FLASH:                                        */
106
+/* Flash LED when transferring data. For boards without   */
107
+/* TX or RX LEDs, or for people who like blinky lights.   */
108
+/*                                                        */
109
+/* SUPPORT_EEPROM:                                        */
110
+/* Support reading and writing from EEPROM. This is not   */
111
+/* used by Arduino, so off by default.                    */
112
+/*                                                        */
113
+/* TIMEOUT_MS:                                            */
114
+/* Bootloader timeout period, in milliseconds.            */
115
+/* 500,1000,2000,4000,8000 supported.                     */
116
+/*                                                        */
117
+/**********************************************************/
118
+
119
+/**********************************************************/
120
+/* Version Numbers!                                       */
121
+/*                                                        */
122
+/* Arduino Optiboot now includes this Version number in   */
123
+/* the source and object code.                            */
124
+/*                                                        */
125
+/* Version 3 was released as zip from the optiboot        */
126
+/*  repository and was distributed with Arduino 0022.     */
127
+/* Version 4 starts with the arduino repository commit    */
128
+/*  that brought the arduino repository up-to-date with   */
129
+/* the optiboot source tree changes since v3.             */
130
+/*                                                        */
131
+/**********************************************************/
132
+
133
+/**********************************************************/
134
+/* Edit History:                                          */
135
+/*                                                        */
136
+/* Jan 2012:                                              */
137
+/* 4.5 WestfW: fix NRWW value for m1284.                  */
138
+/* 4.4 WestfW: use attribute OS_main instead of naked for */
139
+/*             main().  This allows optimizations that we */
140
+/*             count on, which are prohibited in naked    */
141
+/*             functions due to PR42240.  (keeps us less  */
142
+/*             than 512 bytes when compiler is gcc4.5     */
143
+/*             (code from 4.3.2 remains the same.)        */
144
+/* 4.4 WestfW and Maniacbug:  Add m1284 support.  This    */
145
+/*             does not change the 328 binary, so the     */
146
+/*             version number didn't change either. (?)   */
147
+/* June 2011:                                             */
148
+/* 4.4 WestfW: remove automatic soft_uart detect (didn't  */
149
+/*             know what it was doing or why.)  Added a   */
150
+/*             check of the calculated BRG value instead. */
151
+/*             Version stays 4.4; existing binaries are   */
152
+/*             not changed.                               */
153
+/* 4.4 WestfW: add initialization of address to keep      */
154
+/*             the compiler happy.  Change SC'ed targets. */
155
+/*             Return the SW version via READ PARAM       */
156
+/* 4.3 WestfW: catch framing errors in getch(), so that   */
157
+/*             AVRISP works without HW kludges.           */
158
+/*  http://code.google.com/p/arduino/issues/detail?id=368n*/
159
+/* 4.2 WestfW: reduce code size, fix timeouts, change     */
160
+/*             verifySpace to use WDT instead of appstart */
161
+/* 4.1 WestfW: put version number in binary.              */
162
+/**********************************************************/
163
+
164
+#define OPTIBOOT_MAJVER 4
165
+#define OPTIBOOT_MINVER 5
166
+
167
+#define MAKESTR(a) #a
168
+#define MAKEVER(a, b) MAKESTR(a*256+b)
169
+
170
+asm("  .section .version\n"
171
+    "optiboot_version:  .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
172
+    "  .section .text\n");
173
+
174
+#include <inttypes.h>
175
+#include <avr/io.h>
176
+#include <avr/pgmspace.h>
177
+
178
+// <avr/boot.h> uses sts instructions, but this version uses out instructions
179
+// This saves cycles and program memory.
180
+#include "boot.h"
181
+
182
+
183
+// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
184
+
185
+#include "pin_defs.h"
186
+#include "stk500.h"
187
+
188
+#ifndef LED_START_FLASHES
189
+#define LED_START_FLASHES 0
190
+#endif
191
+
192
+#ifdef LUDICROUS_SPEED
193
+#define BAUD_RATE 230400L
194
+#endif
195
+
196
+/* set the UART baud rate defaults */
197
+#ifndef BAUD_RATE
198
+#if F_CPU >= 8000000L
199
+#define BAUD_RATE   115200L // Highest rate Avrdude win32 will support
200
+#elsif F_CPU >= 1000000L
201
+#define BAUD_RATE   9600L   // 19200 also supported, but with significant error
202
+#elsif F_CPU >= 128000L
203
+#define BAUD_RATE   4800L   // Good for 128kHz internal RC
204
+#else
205
+#define BAUD_RATE 1200L     // Good even at 32768Hz
206
+#endif
207
+#endif
208
+
209
+#if 0
210
+/* Switch in soft UART for hard baud rates */
211
+/*
212
+ * I don't understand what this was supposed to accomplish, where the
213
+ * constant "280" came from, or why automatically (and perhaps unexpectedly)
214
+ * switching to a soft uart is a good thing, so I'm undoing this in favor
215
+ * of a range check using the same calc used to config the BRG...
216
+ */
217
+#if (F_CPU/BAUD_RATE) > 280 // > 57600 for 16MHz
218
+#ifndef SOFT_UART
219
+#define SOFT_UART
220
+#endif
221
+#endif
222
+#else // 0
223
+#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
224
+#error Unachievable baud rate (too slow) BAUD_RATE 
225
+#endif // baud rate slow check
226
+#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
227
+#error Unachievable baud rate (too fast) BAUD_RATE 
228
+#endif // baud rate fastn check
229
+#endif
230
+
231
+/* Watchdog settings */
232
+#define WATCHDOG_OFF    (0)
233
+#define WATCHDOG_16MS   (_BV(WDE))
234
+#define WATCHDOG_32MS   (_BV(WDP0) | _BV(WDE))
235
+#define WATCHDOG_64MS   (_BV(WDP1) | _BV(WDE))
236
+#define WATCHDOG_125MS  (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
237
+#define WATCHDOG_250MS  (_BV(WDP2) | _BV(WDE))
238
+#define WATCHDOG_500MS  (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
239
+#define WATCHDOG_1S     (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
240
+#define WATCHDOG_2S     (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
241
+#ifndef __AVR_ATmega8__
242
+#define WATCHDOG_4S     (_BV(WDP3) | _BV(WDE))
243
+#define WATCHDOG_8S     (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
244
+#endif
245
+
246
+/* Function Prototypes */
247
+/* The main function is in init9, which removes the interrupt vector table */
248
+/* we don't need. It is also 'naked', which means the compiler does not    */
249
+/* generate any entry or exit code itself. */
250
+int main(void) __attribute__ ((OS_main)) __attribute__ ((section (".init9")));
251
+void putch(char);
252
+uint8_t getch(void);
253
+static inline void getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */
254
+void verifySpace();
255
+static inline void flash_led(uint8_t);
256
+uint8_t getLen();
257
+static inline void watchdogReset();
258
+void watchdogConfig(uint8_t x);
259
+#ifdef SOFT_UART
260
+void uartDelay() __attribute__ ((naked));
261
+#endif
262
+void appStart() __attribute__ ((naked));
263
+
264
+/*
265
+ * NRWW memory
266
+ * Addresses below NRWW (Non-Read-While-Write) can be programmed while
267
+ * continuing to run code from flash, slightly speeding up programming
268
+ * time.  Beware that Atmel data sheets specify this as a WORD address,
269
+ * while optiboot will be comparing against a 16-bit byte address.  This
270
+ * means that on a part with 128kB of memory, the upper part of the lower
271
+ * 64k will get NRWW processing as well, even though it doesn't need it.
272
+ * That's OK.  In fact, you can disable the overlapping processing for
273
+ * a part entirely by setting NRWWSTART to zero.  This reduces code
274
+ * space a bit, at the expense of being slightly slower, overall.
275
+ *
276
+ * RAMSTART should be self-explanatory.  It's bigger on parts with a
277
+ * lot of peripheral registers.
278
+ */
279
+#if defined(__AVR_ATmega168__)
280
+#define RAMSTART (0x100)
281
+#define NRWWSTART (0x3800)
282
+#elif defined(__AVR_ATmega328P__)
283
+#define RAMSTART (0x100)
284
+#define NRWWSTART (0x7000)
285
+#elif defined (__AVR_ATmega644P__)
286
+#define RAMSTART (0x100)
287
+#define NRWWSTART (0xE000)
288
+#elif defined (__AVR_ATmega1284P__)
289
+#define RAMSTART (0x100)
290
+#define NRWWSTART (0xE000)
291
+#elif defined(__AVR_ATtiny84__)
292
+#define RAMSTART (0x100)
293
+#define NRWWSTART (0x0000)
294
+#elif defined(__AVR_ATmega1280__)
295
+#define RAMSTART (0x200)
296
+#define NRWWSTART (0xE000)
297
+#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
298
+#define RAMSTART (0x100)
299
+#define NRWWSTART (0x1800)
300
+#endif
301
+
302
+/* C zero initialises all global variables. However, that requires */
303
+/* These definitions are NOT zero initialised, but that doesn't matter */
304
+/* This allows us to drop the zero init code, saving us memory */
305
+#define buff    ((uint8_t*)(RAMSTART))
306
+#ifdef VIRTUAL_BOOT_PARTITION
307
+#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
308
+#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
309
+#endif
310
+
311
+/* main program starts here */
312
+int main(void) {
313
+  uint8_t ch;
314
+
315
+  /*
316
+   * Making these local and in registers prevents the need for initializing
317
+   * them, and also saves space because code no longer stores to memory.
318
+   * (initializing address keeps the compiler happy, but isn't really
319
+   *  necessary, and uses 4 bytes of flash.)
320
+   */
321
+  register uint16_t address = 0;
322
+  register uint8_t  length;
323
+
324
+  // After the zero init loop, this is the first code to run.
325
+  //
326
+  // This code makes the following assumptions:
327
+  //  No interrupts will execute
328
+  //  SP points to RAMEND
329
+  //  r1 contains zero
330
+  //
331
+  // If not, uncomment the following instructions:
332
+  // cli();
333
+  asm volatile ("clr __zero_reg__");
334
+#ifdef __AVR_ATmega8__
335
+  SP=RAMEND;  // This is done by hardware reset
336
+#endif
337
+
338
+  // Adaboot no-wait mod
339
+  ch = MCUSR;
340
+  MCUSR = 0;
341
+  if (!(ch & _BV(EXTRF))) appStart();
342
+
343
+#if LED_START_FLASHES > 0
344
+  // Set up Timer 1 for timeout counter
345
+  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
346
+#endif
347
+#ifndef SOFT_UART
348
+#ifdef __AVR_ATmega8__
349
+  UCSRA = _BV(U2X); //Double speed mode USART
350
+  UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
351
+  UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
352
+  UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
353
+#else
354
+  UCSR0A = _BV(U2X0); //Double speed mode USART0
355
+  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
356
+  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
357
+  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
358
+#endif
359
+#endif
360
+
361
+  // Set up watchdog to trigger after 500ms
362
+  watchdogConfig(WATCHDOG_1S);
363
+
364
+  /* Set LED pin as output */
365
+  LED_DDR |= _BV(LED);
366
+
367
+#ifdef SOFT_UART
368
+  /* Set TX pin as output */
369
+  UART_DDR |= _BV(UART_TX_BIT);
370
+#endif
371
+
372
+#if LED_START_FLASHES > 0
373
+  /* Flash onboard LED to signal entering of bootloader */
374
+  flash_led(LED_START_FLASHES * 2);
375
+#endif
376
+
377
+  /* Forever loop */
378
+  for (;;) {
379
+    /* get character from UART */
380
+    ch = getch();
381
+
382
+    if(ch == STK_GET_PARAMETER) {
383
+      unsigned char which = getch();
384
+      verifySpace();
385
+      if (which == 0x82) {
386
+        /*
387
+         * Send optiboot version as "minor SW version"
388
+         */
389
+        putch(OPTIBOOT_MINVER);
390
+      } else if (which == 0x81) {
391
+          putch(OPTIBOOT_MAJVER);
392
+      } else {
393
+        /*
394
+         * GET PARAMETER returns a generic 0x03 reply for
395
+         * other parameters - enough to keep Avrdude happy
396
+         */
397
+        putch(0x03);
398
+      }
399
+    }
400
+    else if(ch == STK_SET_DEVICE) {
401
+      // SET DEVICE is ignored
402
+      getNch(20);
403
+    }
404
+    else if(ch == STK_SET_DEVICE_EXT) {
405
+      // SET DEVICE EXT is ignored
406
+      getNch(5);
407
+    }
408
+    else if(ch == STK_LOAD_ADDRESS) {
409
+      // LOAD ADDRESS
410
+      uint16_t newAddress;
411
+      newAddress = getch();
412
+      newAddress = (newAddress & 0xff) | (getch() << 8);
413
+#ifdef RAMPZ
414
+      // Transfer top bit to RAMPZ
415
+      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
416
+#endif
417
+      newAddress += newAddress; // Convert from word address to byte address
418
+      address = newAddress;
419
+      verifySpace();
420
+    }
421
+    else if(ch == STK_UNIVERSAL) {
422
+      // UNIVERSAL command is ignored
423
+      getNch(4);
424
+      putch(0x00);
425
+    }
426
+    /* Write memory, length is big endian and is in bytes */
427
+    else if(ch == STK_PROG_PAGE) {
428
+      // PROGRAM PAGE - we support flash programming only, not EEPROM
429
+      uint8_t *bufPtr;
430
+      uint16_t addrPtr;
431
+
432
+      getch();                  /* getlen() */
433
+      length = getch();
434
+      getch();
435
+
436
+      // If we are in RWW section, immediately start page erase
437
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
438
+
439
+      // While that is going on, read in page contents
440
+      bufPtr = buff;
441
+      do *bufPtr++ = getch();
442
+      while (--length);
443
+
444
+      // If we are in NRWW section, page erase has to be delayed until now.
445
+      // Todo: Take RAMPZ into account
446
+      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
447
+
448
+      // Read command terminator, start reply
449
+      verifySpace();
450
+
451
+      // If only a partial page is to be programmed, the erase might not be complete.
452
+      // So check that here
453
+      boot_spm_busy_wait();
454
+
455
+#ifdef VIRTUAL_BOOT_PARTITION
456
+      if ((uint16_t)(void*)address == 0) {
457
+        // This is the reset vector page. We need to live-patch the code so the
458
+        // bootloader runs.
459
+        //
460
+        // Move RESET vector to WDT vector
461
+        uint16_t vect = buff[0] | (buff[1]<<8);
462
+        rstVect = vect;
463
+        wdtVect = buff[8] | (buff[9]<<8);
464
+        vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
465
+        buff[8] = vect & 0xff;
466
+        buff[9] = vect >> 8;
467
+
468
+        // Add jump to bootloader at RESET vector
469
+        buff[0] = 0x7f;
470
+        buff[1] = 0xce; // rjmp 0x1d00 instruction
471
+      }
472
+#endif
473
+
474
+      // Copy buffer into programming buffer
475
+      bufPtr = buff;
476
+      addrPtr = (uint16_t)(void*)address;
477
+      ch = SPM_PAGESIZE / 2;
478
+      do {
479
+        uint16_t a;
480
+        a = *bufPtr++;
481
+        a |= (*bufPtr++) << 8;
482
+        __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
483
+        addrPtr += 2;
484
+      } while (--ch);
485
+
486
+      // Write from programming buffer
487
+      __boot_page_write_short((uint16_t)(void*)address);
488
+      boot_spm_busy_wait();
489
+
490
+#if defined(RWWSRE)
491
+      // Reenable read access to flash
492
+      boot_rww_enable();
493
+#endif
494
+
495
+    }
496
+    /* Read memory block mode, length is big endian.  */
497
+    else if(ch == STK_READ_PAGE) {
498
+      // READ PAGE - we only read flash
499
+      getch();                  /* getlen() */
500
+      length = getch();
501
+      getch();
502
+
503
+      verifySpace();
504
+#ifdef VIRTUAL_BOOT_PARTITION
505
+      do {
506
+        // Undo vector patch in bottom page so verify passes
507
+        if (address == 0)       ch=rstVect & 0xff;
508
+        else if (address == 1)  ch=rstVect >> 8;
509
+        else if (address == 8)  ch=wdtVect & 0xff;
510
+        else if (address == 9) ch=wdtVect >> 8;
511
+        else ch = pgm_read_byte_near(address);
512
+        address++;
513
+        putch(ch);
514
+      } while (--length);
515
+#else
516
+#ifdef RAMPZ
517
+// Since RAMPZ should already be set, we need to use EPLM directly.
518
+//      do putch(pgm_read_byte_near(address++));
519
+//      while (--length);
520
+      do {
521
+        uint8_t result;
522
+        __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address));
523
+        putch(result);
524
+        address++;
525
+      }
526
+      while (--length);
527
+#else
528
+      do putch(pgm_read_byte_near(address++));
529
+      while (--length);
530
+#endif
531
+#endif
532
+    }
533
+
534
+    /* Get device signature bytes  */
535
+    else if(ch == STK_READ_SIGN) {
536
+      // READ SIGN - return what Avrdude wants to hear
537
+      verifySpace();
538
+      putch(SIGNATURE_0);
539
+      putch(SIGNATURE_1);
540
+      putch(SIGNATURE_2);
541
+    }
542
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
543
+      // Adaboot no-wait mod
544
+      watchdogConfig(WATCHDOG_16MS);
545
+      verifySpace();
546
+    }
547
+    else {
548
+      // This covers the response to commands like STK_ENTER_PROGMODE
549
+      verifySpace();
550
+    }
551
+    putch(STK_OK);
552
+  }
553
+}
554
+
555
+void putch(char ch) {
556
+#ifndef SOFT_UART
557
+  while (!(UCSR0A & _BV(UDRE0)));
558
+  UDR0 = ch;
559
+#else
560
+  __asm__ __volatile__ (
561
+    "   com %[ch]\n" // ones complement, carry set
562
+    "   sec\n"
563
+    "1: brcc 2f\n"
564
+    "   cbi %[uartPort],%[uartBit]\n"
565
+    "   rjmp 3f\n"
566
+    "2: sbi %[uartPort],%[uartBit]\n"
567
+    "   nop\n"
568
+    "3: rcall uartDelay\n"
569
+    "   rcall uartDelay\n"
570
+    "   lsr %[ch]\n"
571
+    "   dec %[bitcnt]\n"
572
+    "   brne 1b\n"
573
+    :
574
+    :
575
+      [bitcnt] "d" (10),
576
+      [ch] "r" (ch),
577
+      [uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
578
+      [uartBit] "I" (UART_TX_BIT)
579
+    :
580
+      "r25"
581
+  );
582
+#endif
583
+}
584
+
585
+uint8_t getch(void) {
586
+  uint8_t ch;
587
+
588
+#ifdef LED_DATA_FLASH
589
+#ifdef __AVR_ATmega8__
590
+  LED_PORT ^= _BV(LED);
591
+#else
592
+  LED_PIN |= _BV(LED);
593
+#endif
594
+#endif
595
+
596
+#ifdef SOFT_UART
597
+  __asm__ __volatile__ (
598
+    "1: sbic  %[uartPin],%[uartBit]\n"  // Wait for start edge
599
+    "   rjmp  1b\n"
600
+    "   rcall uartDelay\n"          // Get to middle of start bit
601
+    "2: rcall uartDelay\n"              // Wait 1 bit period
602
+    "   rcall uartDelay\n"              // Wait 1 bit period
603
+    "   clc\n"
604
+    "   sbic  %[uartPin],%[uartBit]\n"
605
+    "   sec\n"
606
+    "   dec   %[bitCnt]\n"
607
+    "   breq  3f\n"
608
+    "   ror   %[ch]\n"
609
+    "   rjmp  2b\n"
610
+    "3:\n"
611
+    :
612
+      [ch] "=r" (ch)
613
+    :
614
+      [bitCnt] "d" (9),
615
+      [uartPin] "I" (_SFR_IO_ADDR(UART_PIN)),
616
+      [uartBit] "I" (UART_RX_BIT)
617
+    :
618
+      "r25"
619
+);
620
+#else
621
+  while(!(UCSR0A & _BV(RXC0)))
622
+    ;
623
+  if (!(UCSR0A & _BV(FE0))) {
624
+      /*
625
+       * A Framing Error indicates (probably) that something is talking
626
+       * to us at the wrong bit rate.  Assume that this is because it
627
+       * expects to be talking to the application, and DON'T reset the
628
+       * watchdog.  This should cause the bootloader to abort and run
629
+       * the application "soon", if it keeps happening.  (Note that we
630
+       * don't care that an invalid char is returned...)
631
+       */
632
+    watchdogReset();
633
+  }
634
+  
635
+  ch = UDR0;
636
+#endif
637
+
638
+#ifdef LED_DATA_FLASH
639
+#ifdef __AVR_ATmega8__
640
+  LED_PORT ^= _BV(LED);
641
+#else
642
+  LED_PIN |= _BV(LED);
643
+#endif
644
+#endif
645
+
646
+  return ch;
647
+}
648
+
649
+#ifdef SOFT_UART
650
+// AVR305 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6)
651
+// Adding 3 to numerator simulates nearest rounding for more accurate baud rates
652
+#define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6)
653
+#if UART_B_VALUE > 255
654
+#error Baud rate too slow for soft UART
655
+#endif
656
+
657
+void uartDelay() {
658
+  __asm__ __volatile__ (
659
+    "ldi r25,%[count]\n"
660
+    "1:dec r25\n"
661
+    "brne 1b\n"
662
+    "ret\n"
663
+    ::[count] "M" (UART_B_VALUE)
664
+  );
665
+}
666
+#endif
667
+
668
+void getNch(uint8_t count) {
669
+  do getch(); while (--count);
670
+  verifySpace();
671
+}
672
+
673
+void verifySpace() {
674
+  if (getch() != CRC_EOP) {
675
+    watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
676
+    while (1)                         // and busy-loop so that WD causes
677
+      ;                               //  a reset and app start.
678
+  }
679
+  putch(STK_INSYNC);
680
+}
681
+
682
+#if LED_START_FLASHES > 0
683
+void flash_led(uint8_t count) {
684
+  do {
685
+    TCNT1 = -(F_CPU/(1024*16));
686
+    TIFR1 = _BV(TOV1);
687
+    while(!(TIFR1 & _BV(TOV1)));
688
+#ifdef __AVR_ATmega8__
689
+    LED_PORT ^= _BV(LED);
690
+#else
691
+    LED_PIN |= _BV(LED);
692
+#endif
693
+    watchdogReset();
694
+  } while (--count);
695
+}
696
+#endif
697
+
698
+// Watchdog functions. These are only safe with interrupts turned off.
699
+void watchdogReset() {
700
+  __asm__ __volatile__ (
701
+    "wdr\n"
702
+  );
703
+}
704
+
705
+void watchdogConfig(uint8_t x) {
706
+  WDTCSR = _BV(WDCE) | _BV(WDE);
707
+  WDTCSR = x;
708
+}
709
+
710
+void appStart() {
711
+  watchdogConfig(WATCHDOG_OFF);
712
+  __asm__ __volatile__ (
713
+#ifdef VIRTUAL_BOOT_PARTITION
714
+    // Jump to WDT vector
715
+    "ldi r30,4\n"
716
+    "clr r31\n"
717
+#else
718
+    // Jump to RST vector
719
+    "clr r30\n"
720
+    "clr r31\n"
721
+#endif
722
+    "ijmp\n"
723
+  );
724
+}

+ 33
- 0
ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/optiboot_1284P_20MHz_57k6_baud.hex 파일 보기

@@ -0,0 +1,33 @@
1
+:020000021000EC
2
+:10FE00000F92CDB7DEB7112484B714BE81FFDFD0C7
3
+:10FE100082E08093C00088E18093C10086E08093F7
4
+:10FE2000C2008AE28093C4008EE0BBD0209A00E03A
5
+:10FE300010E0EE24E394E1E1DE2EF3E0FF2EA5D006
6
+:10FE4000813471F4A2D08983B2D08981823809F4D7
7
+:10FE50008BC0813811F484E001C083E08FD08BC067
8
+:10FE6000823411F484E103C0853419F485E0A7D00D
9
+:10FE700082C0853591F489D0A82EBB2486D0082F66
10
+:10FE800010E0102F00270A291B29812F881F88279F
11
+:10FE9000881F8BBF000F111F6DC0863521F484E0D1
12
+:10FEA0008ED080E0DBCF843609F040C06ED06DD0BC
13
+:10FEB000C82E6BD080EE0030180718F4F801F7BE9A
14
+:10FEC000E895A12C51E0B52E60D0F50181935F013A
15
+:10FED000CE16D1F7F0EE00301F0718F0F801F7BE8C
16
+:10FEE000E89565D007B600FCFDCFF801A0E0B1E0D1
17
+:10FEF0002C9130E011968C91119790E0982F8827E3
18
+:10FF0000822B932B12960C01E7BEE89511243296B2
19
+:10FF100082E0A030B80761F785E0F80187BFE89577
20
+:10FF200007B600FCFDCFD7BEE89525C08437A9F4FD
21
+:10FF30002CD02BD0B82E29D03AD0CB2C4801F401AC
22
+:10FF400086911CD00894811C911CCA94C1F70F5F44
23
+:10FF50001F4FBA940B0D111D0EC0853739F427D0F1
24
+:10FF60008EE10CD087E90AD085E078CF813511F495
25
+:10FF700088E017D01CD080E101D061CF9091C00003
26
+:10FF800095FFFCCF8093C60008958091C00087FF45
27
+:10FF9000FCCF8091C00084FD01C0A8958091C6006F
28
+:10FFA0000895E0E6F0E098E1908380830895EDDF26
29
+:10FFB000803219F088E0F5DFFFCF84E1DFCFCF9307
30
+:10FFC000C82FE3DFC150E9F7F2DFCF91089580E059
31
+:08FFD000E8DFEE27FF2709948A
32
+:040000031000FE00EB
33
+:00000001FF

+ 81
- 0
ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/pin_defs.h 파일 보기

@@ -0,0 +1,81 @@
1
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
2
+/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */
3
+#define LED_DDR     DDRB
4
+#define LED_PORT    PORTB
5
+#define LED_PIN     PINB
6
+#define LED         PINB5
7
+
8
+/* Ports for soft UART */
9
+#ifdef SOFT_UART
10
+#define UART_PORT   PORTD
11
+#define UART_PIN    PIND
12
+#define UART_DDR    DDRD
13
+#define UART_TX_BIT 1
14
+#define UART_RX_BIT 0
15
+#endif
16
+#endif
17
+
18
+#if defined(__AVR_ATmega8__)
19
+  //Name conversion R.Wiersma
20
+  #define UCSR0A        UCSRA
21
+  #define UDR0          UDR
22
+  #define UDRE0         UDRE
23
+  #define RXC0          RXC
24
+  #define FE0           FE
25
+  #define TIFR1         TIFR
26
+  #define WDTCSR        WDTCR
27
+#endif
28
+
29
+/* Luminet support */
30
+#if defined(__AVR_ATtiny84__)
31
+/* Red LED is connected to pin PA4 */
32
+#define LED_DDR     DDRA
33
+#define LED_PORT    PORTA
34
+#define LED_PIN     PINA
35
+#define LED         PINA4
36
+/* Ports for soft UART - left port only for now. TX/RX on PA2/PA3 */
37
+#ifdef SOFT_UART
38
+#define UART_PORT   PORTA
39
+#define UART_PIN    PINA
40
+#define UART_DDR    DDRA
41
+#define UART_TX_BIT 2
42
+#define UART_RX_BIT 3
43
+#endif
44
+#endif
45
+
46
+/* Sanguino support */
47
+#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
48
+/* Onboard LED is connected to pin PB0 on Sanguino */
49
+#define LED_DDR     DDRB
50
+#define LED_PORT    PORTB
51
+#define LED_PIN     PINB
52
+#define LED         PINB0
53
+
54
+/* Ports for soft UART */
55
+#ifdef SOFT_UART
56
+#define UART_PORT   PORTD
57
+#define UART_PIN    PIND
58
+#define UART_DDR    DDRD
59
+#define UART_TX_BIT 1
60
+#define UART_RX_BIT 0
61
+#endif
62
+#endif
63
+
64
+/* Mega support */
65
+#if defined(__AVR_ATmega1280__)
66
+/* Onboard LED is connected to pin PB7 on Arduino Mega */
67
+#define LED_DDR     DDRB
68
+#define LED_PORT    PORTB
69
+#define LED_PIN     PINB
70
+#define LED         PINB7
71
+
72
+/* Ports for soft UART */
73
+#ifdef SOFT_UART
74
+#define UART_PORT   PORTE
75
+#define UART_PIN    PINE
76
+#define UART_DDR    DDRE
77
+#define UART_TX_BIT 1
78
+#define UART_RX_BIT 0
79
+#endif
80
+#endif
81
+

+ 39
- 0
ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/stk500.h 파일 보기

@@ -0,0 +1,39 @@
1
+/* STK500 constants list, from AVRDUDE */
2
+#define STK_OK              0x10
3
+#define STK_FAILED          0x11  // Not used
4
+#define STK_UNKNOWN         0x12  // Not used
5
+#define STK_NODEVICE        0x13  // Not used
6
+#define STK_INSYNC          0x14  // ' '
7
+#define STK_NOSYNC          0x15  // Not used
8
+#define ADC_CHANNEL_ERROR   0x16  // Not used
9
+#define ADC_MEASURE_OK      0x17  // Not used
10
+#define PWM_CHANNEL_ERROR   0x18  // Not used
11
+#define PWM_ADJUST_OK       0x19  // Not used
12
+#define CRC_EOP             0x20  // 'SPACE'
13
+#define STK_GET_SYNC        0x30  // '0'
14
+#define STK_GET_SIGN_ON     0x31  // '1'
15
+#define STK_SET_PARAMETER   0x40  // '@'
16
+#define STK_GET_PARAMETER   0x41  // 'A'
17
+#define STK_SET_DEVICE      0x42  // 'B'
18
+#define STK_SET_DEVICE_EXT  0x45  // 'E'
19
+#define STK_ENTER_PROGMODE  0x50  // 'P'
20
+#define STK_LEAVE_PROGMODE  0x51  // 'Q'
21
+#define STK_CHIP_ERASE      0x52  // 'R'
22
+#define STK_CHECK_AUTOINC   0x53  // 'S'
23
+#define STK_LOAD_ADDRESS    0x55  // 'U'
24
+#define STK_UNIVERSAL       0x56  // 'V'
25
+#define STK_PROG_FLASH      0x60  // '`'
26
+#define STK_PROG_DATA       0x61  // 'a'
27
+#define STK_PROG_FUSE       0x62  // 'b'
28
+#define STK_PROG_LOCK       0x63  // 'c'
29
+#define STK_PROG_PAGE       0x64  // 'd'
30
+#define STK_PROG_FUSE_EXT   0x65  // 'e'
31
+#define STK_READ_FLASH      0x70  // 'p'
32
+#define STK_READ_DATA       0x71  // 'q'
33
+#define STK_READ_FUSE       0x72  // 'r'
34
+#define STK_READ_LOCK       0x73  // 's'
35
+#define STK_READ_PAGE       0x74  // 't'
36
+#define STK_READ_SIGN       0x75  // 'u'
37
+#define STK_READ_OSCCAL     0x76  // 'v'
38
+#define STK_READ_FUSE_EXT   0x77  // 'w'
39
+#define STK_READ_OSCCAL_EXT 0x78  // 'x'

Loading…
취소
저장