├── README.md
├── package_atmega328pb_index.json
├── src
├── boards.txt
├── bootloaders
│ └── optiboot
│ │ ├── .cproject
│ │ ├── .project
│ │ ├── Makefile
│ │ ├── Makefile.1284
│ │ ├── Makefile.atmel
│ │ ├── Makefile.custom
│ │ ├── Makefile.extras
│ │ ├── Makefile.isp
│ │ ├── README.TXT
│ │ ├── boot.h
│ │ ├── makeall
│ │ ├── omake
│ │ ├── omake.bat
│ │ ├── optiboot.c
│ │ ├── optiboot_atmega328pb_20MHz.hex
│ │ ├── optiboot_atmega328pb_20MHz.lst
│ │ ├── optiboot_m328pb_autobaud.hex
│ │ ├── pin_defs.h
│ │ └── stk500.h
├── libraries
│ └── SPI
│ │ ├── DigitalPotControlviaSPI0
│ │ └── DigitalPotControlviaSPI0.ino
│ │ ├── DigitalPotiControlviaSPI1
│ │ └── DigitalPotiControlviaSPI1.ino
│ │ ├── SPI.cpp
│ │ ├── SPI.h
│ │ ├── SPIDef.h
│ │ ├── keywords.txt
│ │ └── library.properties
├── platform.txt
├── tools
│ ├── etc
│ │ └── avrdude.conf
│ ├── include
│ │ └── avr
│ │ │ └── iom328pb.h
│ └── lib
│ │ ├── crtatmega328pb.o
│ │ └── libatmega328pb.a
└── variants
│ ├── supermini
│ └── pins_arduino.h
│ └── superstick
│ └── pins_arduino.h
└── uino_m328pb_pack_1.0.0.zip
/README.md:
--------------------------------------------------------------------------------
1 | # Arduino Atmega328PB Package
2 | ## Support for the new Atmel Chip
3 |
4 |
5 | This is the worldwide first real Atmega328PB support package for Arduino! No hooks.
6 | Look at my uino-hardware Repo for Schematic of my Boards.
7 | This package lets you compile your code for the Atmel Atmega328PB Microcontroller. There is no additionally compiler needed. You can compile out of the box.
8 |
9 |
10 | ### Requirements
11 | Arduino IDE 1.6.9 or higher which contains avr-gcc in Version 4.9.2
12 |
13 | ### Install
14 | Copy this link into your Arduino IDE.
15 |
16 | **https://raw.githubusercontent.com/amoehl/uino-atmega328pb/master/package_atmega328pb_index.json**
17 |
18 | Run "Bord Manager" -> Contributed -> Atmega328PB -> _Install_
19 |
20 | ### Hardware
21 |
22 | This Package currently supports only my own developed boards.
23 | More Information: https://github.com/amoehl/uino-hardware
24 |
25 |
26 |
--------------------------------------------------------------------------------
/package_atmega328pb_index.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages":[
3 | {
4 | "name": "Atmega328PB",
5 | "maintainer": "Andre Moehl",
6 | "websiteURL": "",
7 | "email": "arduino@ib-moehl.de",
8 | "help": {
9 | "online": ""
10 | },
11 | "platforms":
12 | [
13 | {
14 | "name": "Atmega328PB",
15 | "architecture": "avr",
16 | "version": "1.0.0",
17 | "category": "Atmega328PB",
18 | "url": "https://github.com/amoehl/uino-atmega328pb/raw/master/uino_m328pb_pack_1.0.0.zip",
19 | "checksum": "SHA-256:8e157cfdd5dc2ce3dfc04abbbc58a68b69d96d47201485e27b4646f19eaf1193",
20 | "archiveFileName": "uino_m328pb_pack_1.0.0.zip",
21 | "size": "101006",
22 | "boards":
23 | [
24 | { "name": "Super Mini" },
25 | { "name": "Superstick" }
26 | ],
27 | "toolsDependencies":
28 | [
29 | ]
30 | }
31 | ],
32 | "tools":
33 | [
34 | ]
35 | }
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/src/boards.txt:
--------------------------------------------------------------------------------
1 | # See: http://code.google.com/p/arduino/wiki/Platforms
2 |
3 | ##############################################################
4 |
5 | supermini.name=Super Mini
6 | supermini.upload.tool=avrdude
7 | supermini.upload.protocol=arduino
8 | supermini.upload.maximum_size=32256
9 | supermini.upload.maximum_data_size=2048
10 | supermini.upload.speed=115200
11 |
12 | supermini.bootloader.tool=avrdude
13 | supermini.bootloader.low_fuses=0xFF
14 | supermini.bootloader.high_fuses=0xD8
15 | supermini.bootloader.extended_fuses=0x05
16 | supermini.bootloader.unlock_bits=0x3F
17 | supermini.bootloader.lock_bits=0x0F
18 | #supermini.bootloader.file=optiboot/optiboot_atmega328pb_20MHz.hex
19 | supermini.bootloader.file=optiboot/optiboot_m328pb_autobaud.hex
20 |
21 | supermini.build.f_cpu=20000000L
22 | supermini.build.board=AVR_SUPER_MINI
23 | supermini.build.core=arduino:arduino
24 | supermini.build.variant=supermini
25 | supermini.build.mcu=atmega328pb
26 |
27 | ##############################################################
28 |
29 | Superstick.name=Superstick
30 | Superstick.upload.tool=avrdude
31 | Superstick.upload.protocol=arduino
32 | Superstick.upload.maximum_size=32256
33 | Superstick.upload.maximum_data_size=2048
34 | Superstick.upload.speed=115200
35 |
36 | Superstick.bootloader.tool=avrdude
37 | Superstick.bootloader.low_fuses=0xFF
38 | Superstick.bootloader.high_fuses=0xD8
39 | Superstick.bootloader.extended_fuses=0x05
40 | Superstick.bootloader.unlock_bits=0x3F
41 | Superstick.bootloader.lock_bits=0x0F
42 | #Superstick.bootloader.file=optiboot/optiboot_atmega328pb_20MHz.hex
43 | Superstick.bootloader.file=optiboot/optiboot_m328pb_autobaud.hex
44 |
45 | Superstick.build.f_cpu=20000000L
46 | Superstick.build.board=AVR_SUPERSTICK
47 | Superstick.build.core=arduino:arduino
48 | Superstick.build.variant=superstick
49 | Superstick.build.mcu=atmega328pb
50 |
51 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/.cproject:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | optiboot328pb
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 |
14 |
15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
16 | full,incremental,
17 |
18 |
19 |
20 |
21 |
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.core.ccnature
24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/Makefile:
--------------------------------------------------------------------------------
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 | # Edit History
20 | # 201406xx: WestfW: More Makefile restructuring.
21 | # Split off Makefile.1284, Makefile.extras, Makefile.custom
22 | # So that in theory, the main Makefile contains only the
23 | # official platforms, and does not need to be modified to
24 | # add "less supported" chips and boards.
25 | # 201303xx: WestfW: Major Makefile restructuring.
26 | # Allows options on Make command line "make xx LED=B3"
27 | # (see also pin_defs.h)
28 | # Divide into "chip" targets and "board" targets.
29 | # Most boards are (recursive) board targets with options.
30 | # Move isp target to separate makefile (fixes m8 EFUSE)
31 | # Some (many) targets will now be rebuilt when not
32 | # strictly necessary, so that options will be included.
33 | # (any "make" with options will always compile.)
34 | # Set many variables with ?= so they can be overridden
35 | # Use arduinoISP settings as default for ISP targets
36 | #
37 | #
38 | # * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
39 | # * This software is licensed under version 2 of the Gnu Public Licence.
40 | # * See optiboot.c for details.
41 |
42 | #----------------------------------------------------------------------
43 | #
44 | # program name should not be changed...
45 | PROGRAM = optiboot
46 |
47 | # The default behavior is to build using tools that are in the users
48 | # current path variables, but we can also build using an installed
49 | # Arduino user IDE setup, or the Arduino source tree.
50 | # Uncomment this next lines to build within the arduino environment,
51 | # using the arduino-included avrgcc toolset (mac and pc)
52 | ENV ?= arduino
53 | # ENV ?= arduinodev
54 | # OS ?= macosx
55 | # OS ?= windows
56 |
57 | # export symbols to recursive makes (for ISP)
58 | export
59 |
60 | # defaults
61 | MCU_TARGET = atmega168
62 | LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
63 |
64 | # Build environments
65 | # Start of some ugly makefile-isms to allow optiboot to be built
66 | # in several different environments. See the README.TXT file for
67 | # details.
68 |
69 | # default
70 | fixpath = $(1)
71 | SH := bash
72 |
73 | ifeq ($(ENV), arduino)
74 | # For Arduino, we assume that we're connected to the optiboot directory
75 | # included with the arduino distribution, which means that the full set
76 | # of avr-tools are "right up there" in standard places.
77 | # (except that in 1.5.x, there's an additional level of "up")
78 | TESTDIR := $(firstword $(wildcard ../../../tools/*))
79 | ifeq (,$(TESTDIR))
80 | # Arduino 1.5.x tool location compared to optiboot dir
81 | TOOLROOT = ../../../../tools
82 | else
83 | # Arduino 1.0 (and earlier) tool location
84 | TOOLROOT = ../../../tools
85 | endif
86 | GCCROOT = $(TOOLROOT)/avr2/bin/
87 |
88 | ifeq ($(OS), windows)
89 | # On windows, SOME of the tool paths will need to have backslashes instead
90 | # of forward slashes (because they use windows cmd.exe for execution instead
91 | # of a unix/mingw shell?) We also have to ensure that a consistent shell
92 | # is used even if a unix shell is installed (ie as part of WINAVR)
93 | fixpath = $(subst /,\,$1)
94 | SHELL = cmd.exe
95 | SH = sh
96 | endif
97 |
98 | else ifeq ($(ENV), arduinodev)
99 | # Arduino IDE source code environment. Use the unpacked compilers created
100 | # by the build (you'll need to do "ant build" first.)
101 | ifeq ($(OS), macosx)
102 | TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools
103 | endif
104 | ifeq ($(OS), windows)
105 | TOOLROOT = ../../../../build/windows/work/hardware/tools
106 | endif
107 |
108 | GCCROOT = $(TOOLROOT)/avr/bin/
109 | AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
110 |
111 | else
112 | GCCROOT =
113 | AVRDUDE_CONF =
114 | endif
115 |
116 | STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
117 | STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
118 | -lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt
119 | STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt
120 | #
121 | # End of build environment code.
122 |
123 |
124 | OBJ = $(PROGRAM).o
125 | OPTIMIZE = -Os -fno-split-wide-types -mrelax
126 |
127 | DEFS =
128 |
129 | #
130 | # platforms support EEPROM and large bootloaders need the eeprom functions that
131 | # are defined in libc, even though we explicity remove it with -nostdlib because
132 | # of the space-savings.
133 | LIBS = -lc
134 |
135 | CC = $(GCCROOT)avr-gcc
136 |
137 | # Override is only needed by avr-lib build system.
138 |
139 | override CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
140 | override LDFLAGS = $(LDSECTIONS) -Wl,--relax -nostartfiles -nostdlib
141 | #-Wl,--gc-sections
142 |
143 | OBJCOPY = $(GCCROOT)avr-objcopy
144 | OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
145 |
146 | SIZE = $(GCCROOT)avr-size
147 |
148 | #
149 | # Make command-line Options.
150 | # Permit commands like "make atmega328 LED_START_FLASHES=10" to pass the
151 | # appropriate parameters ("-DLED_START_FLASHES=10") to gcc
152 | #
153 |
154 | #BAUD_RATE = 115200
155 |
156 | ifdef BAUD_RATE
157 | BAUD_RATE_CMD = -DBAUD_RATE=$(BAUD_RATE)
158 | else
159 | BAUD_RATE_CMD = -DBAUD_RATE=57600
160 | endif
161 |
162 | ifdef LED_START_FLASHES
163 | LED_START_FLASHES_CMD = -DLED_START_FLASHES=$(LED_START_FLASHES)
164 | else
165 | LED_START_FLASHES_CMD = -DLED_START_FLASHES=3
166 | endif
167 |
168 | # BIG_BOOT: Include extra features, up to 1K.
169 | ifdef BIGBOOT
170 | BIGBOOT_CMD = -DBIGBOOT=1
171 | endif
172 |
173 | ifdef SOFT_UART
174 | SOFT_UART_CMD = -DSOFT_UART=1
175 | endif
176 |
177 | ifdef LED_DATA_FLASH
178 | LED_DATA_FLASH_CMD = -DLED_DATA_FLASH=1
179 | endif
180 |
181 | ifdef LED
182 | LED_CMD = -DLED=$(LED)
183 | endif
184 |
185 | ifdef SINGLESPEED
186 | SS_CMD = -DSINGLESPEED=1
187 | endif
188 |
189 | COMMON_OPTIONS = $(BAUD_RATE_CMD) $(LED_START_FLASHES_CMD) $(BIGBOOT_CMD)
190 | COMMON_OPTIONS += $(SOFT_UART_CMD) $(LED_DATA_FLASH_CMD) $(LED_CMD) $(SS_CMD)
191 |
192 | #UART is handled separately and only passed for devices with more than one.
193 | ifdef UART
194 | UART_CMD = -DUART=$(UART)
195 | endif
196 |
197 | # Not supported yet
198 | # ifdef SUPPORT_EEPROM
199 | # SUPPORT_EEPROM_CMD = -DSUPPORT_EEPROM
200 | # dummy = FORCE
201 | # endif
202 |
203 | # Not supported yet
204 | # ifdef TIMEOUT_MS
205 | # TIMEOUT_MS_CMD = -DTIMEOUT_MS=$(TIMEOUT_MS)
206 | # dummy = FORCE
207 | # endif
208 | #
209 |
210 | #.PRECIOUS: %.elf
211 |
212 | #---------------------------------------------------------------------------
213 | # "Chip-level Platform" targets.
214 | # A "Chip-level Platform" compiles for a particular chip, but probably does
215 | # not have "standard" values for things like clock speed, LED pin, etc.
216 | # Makes for chip-level platforms should usually explicitly define their
217 | # options like: "make atmega1285 AVR_FREQ=16000000L LED=D0"
218 | #---------------------------------------------------------------------------
219 | #
220 | # Note about fuses:
221 | # the efuse should really be 0xf8; since, however, only the lower
222 | # three bits of that byte are used on the atmega168, avrdude gets
223 | # confused if you specify 1's for the higher bits, see:
224 | # http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
225 | #
226 | # similarly, the lock bits should be 0xff instead of 0x3f (to
227 | # unlock the bootloader section) and 0xcf instead of 0x2f (to
228 | # lock it), but since the high two bits of the lock byte are
229 | # unused, avrdude would get confused.
230 | #---------------------------------------------------------------------------
231 | #
232 |
233 | atmega328pb_20MHz: TARGET = atmega328pb
234 | atmega328pb_20MHz: MCU_TARGET = atmega328pb
235 | atmega328pb_20MHz: CFLAGS += $(COMMON_OPTIONS)
236 | atmega328pb_20MHz: AVR_FREQ ?= 20000000L
237 | atmega328pb_20MHz: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
238 | atmega328pb_20MHz: $(PROGRAM)_atmega328pb_20MHz.hex
239 | atmega328pb_20MHz: $(PROGRAM)_atmega328pb_20MHz.lst
240 |
241 | atmega328pb_20MHz_isp: atmega328_20MHz
242 | atmega328pb_20MHz_isp: TARGET = atmega328pb
243 | atmega328pb_20MHz_isp: MCU_TARGET = atmega328pb
244 | # 512 byte boot, SPIEN
245 | atmega328pb_20MHz_isp: HFUSE ?= DE
246 | # Low power xtal (16MHz) 16KCK/14CK+65ms
247 | atmega328pb_20MHz_isp: LFUSE ?= FF
248 | # 2.7V brownout
249 | atmega328pb_20MHz_isp: EFUSE ?= 05
250 | atmega328pb_20MHz_isp: isp
251 |
252 |
253 |
254 | atmega328pb_16MHz: TARGET = atmega328pb
255 | atmega328pb_16MHz: MCU_TARGET = atmega328pb
256 | atmega328pb_16MHz: CFLAGS += $(COMMON_OPTIONS)
257 | atmega328pb_16MHz: AVR_FREQ ?= 16000000L
258 | atmega328pb_16MHz: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
259 | atmega328pb_16MHz: $(PROGRAM)_atmega328pb_16MHz.hex
260 | atmega328pb_16MHz: $(PROGRAM)_atmega328pb_16MHz.lst
261 |
262 | atmega328pb_16MHz_isp: atmega328_16MHz_isp
263 | atmega328pb_16MHz_isp: TARGET = atmega328pb
264 | atmega328pb_16MHz_isp: MCU_TARGET = atmega328pb
265 | # 512 byte boot, SPIEN
266 | atmega328pb_16MHz_isp: HFUSE ?= DE
267 | # Low power xtal (16MHz) 16KCK/14CK+65ms
268 | atmega328pb_16MHz_isp: LFUSE ?= FF
269 | # 2.7V brownout
270 | atmega328pb_16MHz_isp: EFUSE ?= 05
271 | atmega328pb_16MHz_isp: isp
272 |
273 |
274 | #---------------------------------------------------------------------------
275 | #
276 | # Generic build instructions
277 | #
278 |
279 |
280 |
281 | isp: $(TARGET)
282 | $(MAKE) -f Makefile.isp isp TARGET=$(TARGET)
283 |
284 | isp-stk500: $(PROGRAM)_$(TARGET).hex
285 | $(STK500-1)
286 | $(STK500-2)
287 |
288 | %.elf: $(OBJ) $(dummy)
289 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
290 | $(SIZE) $@
291 |
292 | clean:
293 | rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.tmp.sh
294 |
295 | %.lst: %.elf
296 | $(OBJDUMP) -h -S $< > $@
297 |
298 | %.hex: %.elf
299 | $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
300 |
301 | %.srec: %.elf
302 | $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
303 |
304 | %.bin: %.elf
305 | $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@
306 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/Makefile.1284:
--------------------------------------------------------------------------------
1 | #
2 | # Makefile for 40-pin AVR chips, including ATmega644 and ATmega1284
3 | #
4 | # * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
5 | # * This software is licensed under version 2 of the Gnu Public Licence.
6 | # * See optiboot.c for details.
7 |
8 | # Chip level targets
9 | #
10 | atmega644p: TARGET = atmega644p
11 | atmega644p: MCU_TARGET = atmega644p
12 | atmega644p: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT
13 | atmega644p: AVR_FREQ ?= 16000000L
14 | atmega644p: LDSECTIONS = -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe
15 | atmega644p: CFLAGS += $(UART_CMD)
16 | atmega644p: $(PROGRAM)_atmega644p.hex
17 | atmega644p: $(PROGRAM)_atmega644p.lst
18 |
19 | atmega1284: TARGET = atmega1284p
20 | atmega1284: MCU_TARGET = atmega1284p
21 | atmega1284: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT
22 | atmega1284: AVR_FREQ ?= 16000000L
23 | atmega1284: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
24 | atmega1284: CFLAGS += $(UART_CMD)
25 | atmega1284: $(PROGRAM)_atmega1284p.hex
26 | atmega1284: $(PROGRAM)_atmega1284p.lst
27 |
28 | atmega1284p: atmega1284
29 |
30 | atmega1284_isp: atmega1284
31 | atmega1284_isp: TARGET = atmega1284p
32 | atmega1284_isp: MCU_TARGET = atmega1284p
33 | # 1024 byte boot
34 | atmega1284_isp: HFUSE ?= DE
35 | # Full Swing xtal (16MHz) 16KCK/14CK+65ms
36 | atmega1284_isp: LFUSE ?= F7
37 | # 2.7V brownout
38 | atmega1284_isp: EFUSE ?= FD
39 | atmega1284_isp: isp
40 |
41 | #
42 | # Board-level targets
43 | #
44 |
45 | # Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
46 | #
47 | sanguino: TARGET = $@
48 | sanguino: CHIP = atmega644p
49 | sanguino:
50 | $(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B0
51 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
52 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
53 |
54 | sanguino_isp: sanguino
55 | sanguino_isp: TARGET = sanguino
56 | sanguino_isp: MCU_TARGET = atmega644p
57 | # 1024 byte boot
58 | sanguino_isp: HFUSE ?= DE
59 | # Full swing xtal (16MHz) 16KCK/14CK+65ms
60 | sanguino_isp: LFUSE ?= F7
61 | # 2.7V brownout
62 | sanguino_isp: EFUSE ?= FD
63 | sanguino_isp: isp
64 |
65 | mighty1284: TARGET = $@
66 | mighty1284: CHIP = atmega1284p
67 | mighty1284:
68 | $(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B7
69 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
70 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
71 |
72 | mighty1284_isp: mighty1284
73 | mighty1284_isp: TARGET = mighty1284
74 | mighty1284_isp: MCU_TARGET = atmega1284p
75 | # 1024 byte boot
76 | mighty1284_isp: HFUSE ?= DE
77 | # Full swing xtal (16MHz) 16KCK/14CK+65ms
78 | mighty1284_isp: LFUSE ?= F7
79 | # 2.7V brownout
80 | mighty1284_isp: EFUSE ?= FD
81 | mighty1284_isp: isp
82 |
83 | bobuino: TARGET = $@
84 | bobuino: CHIP = atmega1284p
85 | bobuino:
86 | $(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B7
87 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
88 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
89 |
90 | bobuino_isp: bobuino
91 | bobuino_isp: TARGET = bobuino
92 | bobuino_isp: MCU_TARGET = atmega1284p
93 | # 1024 byte boot
94 | bobuino_isp: HFUSE ?= DE
95 | # Full swing xtal (16MHz) 16KCK/14CK+65ms
96 | bobuino_isp: LFUSE ?= F7
97 | # 2.7V brownout
98 | bobuino_isp: EFUSE ?= FD
99 | bobuino_isp: isp
100 |
101 | #
102 | # Wicked Devices "Wildfire" boards (1284 with wireless!)
103 | #
104 |
105 | wildfirev2: TARGET = $@
106 | wildfirev2: CHIP = atmega1284p
107 | wildfirev2:
108 | $(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B7 BAUD_RATE=1000000
109 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
110 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
111 |
112 | wildfirev2_isp: wildfirev2
113 | wildfirev2_isp: TARGET = wildfirev2
114 | wildfirev2_isp: MCU_TARGET = atmega1284p
115 | # 1024 byte boot
116 | wildfirev2_isp: HFUSE ?= DE
117 | # Full swing xtal (16MHz) 16KCK/14CK+65ms
118 | wildfirev2_isp: LFUSE ?= F7
119 | # 2.7V brownout
120 | wildfirev2_isp: EFUSE ?= FD
121 | wildfirev2_isp: isp
122 |
123 | wildfirev3: TARGET = $@
124 | wildfirev3: CHIP = atmega1284p
125 | wildfirev3:
126 | $(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B5
127 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
128 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
129 |
130 | wildfirev3_isp: wildfirev3
131 | wildfirev3_isp: TARGET = wildfirev3
132 | wildfirev3_isp: MCU_TARGET = atmega1284p
133 | # 1024 byte boot
134 | wildfirev3_isp: HFUSE ?= DE
135 | # Full swing xtal (16MHz) 16KCK/14CK+65ms
136 | wildfirev3_isp: LFUSE ?= F7
137 | # 2.7V brownout
138 | wildfirev3_isp: EFUSE ?= FD
139 | wildfirev3_isp: isp
140 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/Makefile.atmel:
--------------------------------------------------------------------------------
1 | # Diecimila, Duemilanove with m168, and NG use identical bootloaders
2 | # Call it "atmega168" for generality and clarity, keep "diecimila" for
3 | # backward compatibility of makefile
4 | #
5 | xplained168pb: TARGET = $@
6 | xplained168pb: CHIP = atmega168
7 | xplained168pb:
8 | $(MAKE) $(CHIP) AVR_FREQ=16000000L BAUD_RATE=57600
9 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
10 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
11 |
12 | xplained328pb: TARGET = $@
13 | xplained328pb: CHIP = atmega328
14 | xplained328pb:
15 | $(MAKE) $(CHIP) AVR_FREQ=16000000L BAUD_RATE=57600
16 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
17 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
18 |
19 | xplained328p: TARGET = $@
20 | xplained328p: CHIP = atmega328
21 | xplained328p:
22 | $(MAKE) $(CHIP) AVR_FREQ=16000000L BAUD_RATE=57600
23 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
24 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
25 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/Makefile.custom:
--------------------------------------------------------------------------------
1 | #
2 | # Makefile for "custom" platforms. Add your board here.
3 | #
4 | # * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
5 | # * This software is licensed under version 2 of the Gnu Public Licence.
6 | # * See optiboot.c for details.
7 |
8 |
9 | wildfire: TARGET = $@
10 | wildfire: CHIP = atmega1284p
11 | wildfire:
12 | $(MAKE) $(CHIP) AVR_FREQ=16000000L LED=B5
13 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
14 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
15 |
16 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/Makefile.extras:
--------------------------------------------------------------------------------
1 | #
2 | # Makefile for "other" implemented platforms.
3 | #
4 | # * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
5 | # * This software is licensed under version 2 of the Gnu Public Licence.
6 | # * See optiboot.c for details.
7 | #
8 |
9 | #
10 | # Extra chips (maybe) supported by optiboot
11 | # Note that these are usually only minimally tested.
12 | #
13 |
14 | #
15 | # ATmega88
16 | #
17 | atmega88: TARGET = atmega88
18 | atmega88: MCU_TARGET = atmega88
19 | atmega88: CFLAGS += $(COMMON_OPTIONS)
20 | atmega88: AVR_FREQ ?= 16000000L
21 | atmega88: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe -Wl,--gc-sections -Wl,--undefined=optiboot_version
22 | atmega88: $(PROGRAM)_atmega88.hex
23 | atmega88: $(PROGRAM)_atmega88.lst
24 |
25 | atmega88_isp: atmega88
26 | atmega88_isp: TARGET = atmega88
27 | atmega88_isp: MCU_TARGET = atmega88
28 | # 2.7V brownout
29 | atmega88_isp: HFUSE ?= DD
30 | # Low power xtal (16MHz) 16KCK/14CK+65ms
31 | atmega88_isp: LFUSE ?= FF
32 | # 512 byte boot
33 | atmega88_isp: EFUSE ?= 04
34 | atmega88_isp: isp
35 |
36 | atmega88p_isp: atmega88
37 | atmega88p_isp: TARGET = atmega88
38 | atmega88p_isp: MCU_TARGET = atmega88p
39 | # 2.7V brownout
40 | atmega88p_isp: HFUSE ?= DD
41 | # Low power xtal (16MHz) 16KCK/14CK+65ms
42 | atmega88p_isp: LFUSE ?= FF
43 | # 512 byte boot
44 | atmega88p_isp: EFUSE ?= 04
45 | atmega88p_isp: isp
46 |
47 | #
48 | # ATmega168p [QFN32]
49 | #
50 | atmega168p: TARGET = atmega168p
51 | atmega168p: MCU_TARGET = atmega168p
52 | atmega168p: CFLAGS += $(COMMON_OPTIONS)
53 | atmega168p: AVR_FREQ ?= 16000000L
54 | atmega168p: $(PROGRAM)_atmega168p_16MHz.hex
55 | atmega168p: $(PROGRAM)_atmega168p_16MHz.lst
56 |
57 | atmega168p_isp: atmega168p
58 | atmega168p_isp: TARGET = atmega168p
59 | # 2.7V brownout
60 | atmega168p_isp: HFUSE ?= DD
61 | # Low power xtal (16MHz) 16KCK/14CK+65ms
62 | atmega168p_isp: LFUSE ?= FF
63 | # 512 byte boot
64 | atmega168p_isp: EFUSE ?= 04
65 | atmega168p_isp: isp
66 |
67 | #
68 | # ATmega32
69 | #
70 | atmega32: TARGET = atmega32
71 | atmega32: MCU_TARGET = atmega32
72 | atmega32: CFLAGS += $(COMMON_OPTIONS)
73 | atmega32: AVR_FREQ ?= 11059200L
74 | atmega32: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
75 | atmega32: $(PROGRAM)_atmega32.hex
76 | atmega32: $(PROGRAM)_atmega32.lst
77 |
78 | atmega32_isp: atmega32
79 | atmega32_isp: TARGET = atmega32
80 | atmega32_isp: MCU_TARGET = atmega32
81 | # No OCD or JTAG, SPIEN, CKOPT (for full swing xtal), Bootsize=512B
82 | atmega32_isp: HFUSE ?= CE
83 | # 2.7V brownout, 16MHz Xtal, 16KCK/14CK+65ms
84 | atmega32_isp: LFUSE ?= BF
85 | atmega32_isp: isp
86 |
87 |
88 |
89 | #
90 | # ATtiny84
91 | #
92 | attiny84: TARGET = attiny84
93 | attiny84: MCU_TARGET = attiny84
94 | attiny84: CFLAGS += $(COMMON_OPTIONS) -DSOFT_UART -DVIRTUAL_BOOT_PARTITION -Dsave_vect_num=4
95 | attiny84: AVR_FREQ ?= 16000000L
96 | attiny84: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1ffe -Wl,--gc-sections -Wl,--undefined=optiboot_version
97 | attiny84: $(PROGRAM)_attiny84.hex
98 | attiny84: $(PROGRAM)_attiny84.lst
99 |
100 |
101 |
102 | # 1MHz clocked platforms/boards
103 | #
104 | # These are capable of 9600 baud
105 | #
106 |
107 | luminet: TARGET = $@
108 | luminet: CHIP = attiny84
109 | luminet:
110 | $(MAKE) $(CHIP) AVR_FREQ=1000000L LED_START_FLASHES=0 BAUD_RATE=9600
111 | mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
112 | mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
113 |
114 | luminet_isp: luminet
115 | luminet_isp: TARGET = luminet
116 | luminet_isp: MCU_TARGET = attiny84
117 | # Brownout disabled
118 | luminet_isp: HFUSE ?= DF
119 | # 1MHz internal oscillator, slowly rising power
120 | luminet_isp: LFUSE ?= 62
121 | # Self-programming enable
122 | luminet_isp: EFUSE ?= FE
123 | luminet_isp: isp
124 |
125 |
126 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/Makefile.isp:
--------------------------------------------------------------------------------
1 | # Makefile.isp for Optiboot
2 | # Bill Westfield (WestfW@yahoo.com) March, 2013
3 | # $Id$
4 | #
5 | # Instructions:
6 | #
7 | # This is a "daughter" Makefile that burns the bootloader using a ISP
8 | # device programmer. It is designed to inherit assorted variables from
9 | # the parent optiboot "Makefile"... Using a daughter makefile makes
10 | # certain variable manipulations more obvious.
11 | #
12 | # To burn bootloader .hex file, invoke the main Makefile using:
13 | # make diecimila_isp
14 | # make lilypad_isp
15 | # make ng_isp
16 | # etc...
17 | #
18 | #
19 | # Note: inherit paths/etc from parent Makefile.
20 | #
21 | #---------------------------------------------------------------------------
22 | #
23 | # * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
24 | # * This software is licensed under version 2 of the Gnu Public Licence.
25 | # * See optiboot.c for details.
26 | #
27 | #---------------------------------------------------------------------------
28 |
29 | # enter the parameters for the avrdude isp tool -b19200
30 | #
31 |
32 | # Inherit avrdude paths from top-level makefile
33 | AVRDUDE_ROOT ?= $(GCCROOT)
34 | AVRDUDE_CONF ?= -C$(TOOLROOT)/avr/etc/avrdude.conf
35 |
36 | # These are the parameters for a usb-based STK500v2 programmer.
37 | # Exact type unknown. (historical Makefile values.)
38 | #ISPTOOL = stk500v2
39 | #ISPPORT = usb
40 | #ISPSPEED = -b 115200
41 | #
42 | #
43 | # These are parameters for using an Arduino with the ArduinoISP sketch
44 | # as the programmer. On a mac, for a particular Uno as programmer.
45 | ISPTOOL ?= stk500v1
46 | ISPPORT ?= /dev/tty.usbserial-FTD61T6Q
47 | ISPSPEED ?= -b19200
48 |
49 |
50 |
51 | # Not all chips have EFUSE.
52 |
53 | ifdef EFUSE
54 | EFUSE_CMD= -U efuse:w:0x$(EFUSE):m
55 | endif
56 |
57 | #
58 | # avrdude commands to erase chip, unlock memory, and program fuses.
59 | #
60 | ISPFUSES = -e -u -U lock:w:0x3f:m $(EFUSE_CMD) \
61 | -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
62 |
63 |
64 | #
65 | # avrdude commands to program the new bootloader, and protect the bootloader
66 | # space from accidental SPM writes. Note: "2f" allows boot section to be read
67 | # by the application, which is different than the arduino default.
68 | #
69 | ISPFLASH = -U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
70 |
71 | # There are certain complicated caused by the fact that the default state
72 | # of a fuse is a "1" rather than a "0", especially with respect to fuse bits
73 | # that have not been implemented. Those would normally not be included, but
74 | # unimplemented fuses still default to being "1"
75 | #
76 | # the efuse should really be 0xf8; since, however, only the lower
77 | # three bits of that byte are used on the atmega168, avrdude gets
78 | # confused if you specify 1's for the higher bits, see:
79 | # http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
80 | #
81 | # similarly, the lock bits should be 0xff instead of 0x3f (to
82 | # unlock the bootloader section) and 0xcf instead of 0x2f (to
83 | # lock it), but since the high two bits of the lock byte are
84 | # unused, avrdude would get confused.
85 |
86 | isp: $(PROGRAM)_$(TARGET).hex
87 | $(AVRDUDE_ROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
88 | -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
89 | $(ISPFUSES) \
90 | $(ISPFLASH)
91 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/README.TXT:
--------------------------------------------------------------------------------
1 | This directory contains the Optiboot small bootloader for AVR
2 | microcontrollers, somewhat modified specifically for the Arduino
3 | environment.
4 |
5 | Optiboot is more fully described here: http://github.com/Optiboot/optiboot
6 | and is the work of Peter Knight (aka Cathedrow), building on work of Jason P
7 | Kyle, Spiff, and Ladyada. More recent maintenance and modifications are by
8 | Bill Westfield (aka WestfW)
9 |
10 | Arduino-specific issues are tracked as part of the Arduino project
11 | at http://github.com/arduino/Arduino
12 |
13 |
14 | Most of the information in this file is superceeded by the wiki content at
15 | https://github.com/Optiboot/optiboot/wiki
16 |
17 | It's till here "just in case."
18 |
19 | ------------------------------------------------------------
20 |
21 | Building optiboot for Arduino.
22 |
23 | Production builds of optiboot for Arduino are done on a Mac in "unix mode"
24 | using CrossPack-AVR-20100115. CrossPack tracks WINAVR (for windows), which
25 | is just a package of avr-gcc and related utilities, so similar builds should
26 | work on Windows or Linux systems.
27 |
28 | One of the Arduino-specific changes is modifications to the makefile to
29 | allow building optiboot using only the tools installed as part of the
30 | Arduino environment, or the Arduino source development tree. All three
31 | build procedures should yield identical binaries (.hex files) (although
32 | this may change if compiler versions drift apart between CrossPack and
33 | the Arduino IDE.)
34 |
35 |
36 | Building Optiboot in the Arduino IDE Install.
37 |
38 | Work in the .../hardware/arduino/bootloaders/optiboot/ and use the
39 | "omake " command, which just generates a command that uses
40 | the arduino-included "make" utility with a command like:
41 | make OS=windows ENV=arduino
42 | or make OS=macosx ENV=arduino
43 | On windows, this assumes you're using the windows command shell. If
44 | you're using a cygwin or mingw shell, or have one of those in your
45 | path, the build will probably break due to slash vs backslash issues.
46 | On a Mac, if you have the developer tools installed, you can use the
47 | Apple-supplied version of make.
48 | The makefile uses relative paths ("../../../tools/" and such) to find
49 | the programs it needs, so you need to work in the existing optiboot
50 | directory (or something created at the same "level") for it to work.
51 |
52 |
53 | Building Optiboot in the Arduino Source Development Install.
54 |
55 | In this case, there is no special shell script, and you're assumed to
56 | have "make" installed somewhere in your path.
57 | Build the Arduino source ("ant build") to unpack the tools into the
58 | expected directory.
59 | Work in Arduino/hardware/arduino/bootloaders/optiboot and use
60 | make OS=windows ENV=arduinodev
61 | or make OS=macosx ENV=arduinodev
62 |
63 |
64 | Programming Chips Using the _isp Targets
65 |
66 | The CPU targets have corresponding ISP targets that will actuall
67 | program the bootloader into a chip. "atmega328_isp" for the atmega328,
68 | for example. These will set the fuses and lock bits as appropriate as
69 | well as uploading the bootloader code.
70 |
71 | ISP Targets in Version 5.0 and later:
72 |
73 | The isp targets are now built using a separate "Makefile.isp" makefile,
74 | which should make modification easier and more obvious. This also fixes
75 | the atmega8_isp target problem mentioned below. The default
76 | configuration assumes an ArduinoISP setup, but you will probably need to
77 | update at least the serial port, since those are different for each
78 | Arduino board and/or system/
79 |
80 |
81 | ISP Targets in Version 4.6 and earlier:
82 |
83 | The older makefiles default to using a USB programmer, but you can use a
84 | serial programmer like ArduinoISP by changing the appropriate variables
85 | when you invoke make:
86 |
87 | make ISPTOOL=stk500v1 ISPPORT=/dev/tty.usbserial-A20e1eAN \
88 | ISPSPEED=-b19200 atmega328_isp
89 |
90 | The "atmega8_isp" target does not currently work, because the mega8
91 | doesn't have the "extended" fuse that the generic ISP target wants to
92 | pass on to avrdude. You'll need to run avrdude manually.
93 |
94 |
95 | Standard Targets
96 |
97 | I've reduced the pre-built and source-version-controlled targets
98 | (.hex and .lst files included in the git repository) to just the
99 | three basic 16MHz targets: atmega8, atmega16, atmega328.
100 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/boot.h:
--------------------------------------------------------------------------------
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 : Bootloader Support Utilities
47 | \code
48 | #include
49 | #include
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
74 | #include
75 | #include
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
116 | #include
117 | #include
118 | #include
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 . */
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_ */
849 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/makeall:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | make clean
3 | #
4 | # buildable platforms of somewhat questionable support level
5 | make lilypad
6 | make pro8
7 | make pro16
8 | make pro20
9 | make atmega328_pro8
10 | make sanguino
11 | make mega1280
12 | make luminet
13 | make diecimila
14 | make bobuino
15 | make mighty1284
16 | make wildfire
17 | make wildfirev2
18 | make wildfirev3
19 | make atmega1284
20 | make atmega16
21 | make atmega32
22 | make atmega88
23 | make atmega168p
24 | make atmega644p
25 | make atmega1280
26 | make atmega1284p
27 | make attiny84
28 | make virboot328
29 | make virboot8
30 |
31 | #
32 | # Atmel development board targets
33 | make xplained168pb
34 | make xplained328p
35 | make xplained328pb
36 |
37 | #
38 | # The "big three" standard bootloaders.
39 | # These need to be built AFTER the platforms, or they'll get renamed
40 | make atmega8
41 | make atmega168
42 | make atmega328
43 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/omake:
--------------------------------------------------------------------------------
1 | #%/bin/bash
2 | if [ -d ../../../tools ]; then
3 | mypath=../../../tools/avr/bin
4 | else
5 | mypath=../../../../tools/avr/bin
6 | fi
7 |
8 | echo $mypath/make OS=macosx ENV=arduino $*
9 | $mypath/make OS=macosx ENV=arduino $*
10 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/omake.bat:
--------------------------------------------------------------------------------
1 | ..\..\..\tools\avr\utils\bin\make OS=windows ENV=arduino %*
2 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/optiboot_atmega328pb_20MHz.hex:
--------------------------------------------------------------------------------
1 | :107E00001F92CDB7DEB7112484B714BE982F9D7092
2 | :107E100009F0D7D085E08093810082E08093C00094
3 | :107E200088E18093C10086E08093C20085E1809361
4 | :107E3000C4008EE0B1D0259A86E02CE33BEF91E0C0
5 | :107E4000309385002093840096BBB09BFECF1D9A93
6 | :107E5000A8958150A9F7812C912C13E001E025E031
7 | :107E6000F22E31E1E32E8CD0813479F489D08983EC
8 | :107E700099D08981823811F482E005C0813811F4EB
9 | :107E800086E001C083E075D071C0823411F484E1D2
10 | :107E900003C0853419F485E08DD068C0853549F478
11 | :107EA0006FD0D82E6DD08D2C912C982A880C991CCF
12 | :107EB0005CC0863521F484E07DD080E0E4CF843658
13 | :107EC00009F036C05DD05CD0D82E5AD0C82EA12C77
14 | :107ED000BB24B39455D0F50181935F01DE12FACF34
15 | :107EE00061D0F5E4CF1201C0FFCFF40117BFE895D0
16 | :107EF00007B600FCFDCFA401A0E0B1E02C911296E2
17 | :107F0000CD010197FC01808130E0382BFA01090195
18 | :107F100007BFE89511244E5F5F4FDA12EFCFF401EF
19 | :107F2000F7BEE89507B600FCFDCFE7BEE8951EC09A
20 | :107F3000843771F425D024D0D82E22D033D05401E8
21 | :107F4000F50185915F0115D0DA94D110F9CF0EC0FB
22 | :107F5000853739F427D08EE10CD085E90AD086E147
23 | :107F600092CF813511F488E017D01CD080E101D088
24 | :107F70007ACF9091C00095FFFCCF8093C600089502
25 | :107F80008091C00087FFFCCF8091C00084FD01C0BC
26 | :107F9000A8958091C6000895E0E6F0E098E190830E
27 | :107FA00080830895EDDF803219F088E0F5DFFFCFA0
28 | :107FB00084E1DFCFCF93C82FE3DFC150E9F7CF9142
29 | :0E7FC000F1CF282E80E0E8DFE0E0FF270994F3
30 | :027FFE00020679
31 | :0400000300007E007B
32 | :00000001FF
33 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/optiboot_atmega328pb_20MHz.lst:
--------------------------------------------------------------------------------
1 |
2 | optiboot_atmega328pb_20MHz.elf: file format elf32-avr
3 |
4 | Sections:
5 | Idx Name Size VMA LMA File off Algn
6 | 0 .data 00000000 00800100 00007fce 00000262 2**0
7 | CONTENTS, ALLOC, LOAD, DATA
8 | 1 .text 000001ce 00007e00 00007e00 00000094 2**1
9 | CONTENTS, ALLOC, LOAD, READONLY, CODE
10 | 2 .version 00000002 00007ffe 00007ffe 00000262 2**0
11 | CONTENTS, ALLOC, LOAD, READONLY, DATA
12 | 3 .comment 00000030 00000000 00000000 00000264 2**0
13 | CONTENTS, READONLY
14 | 4 .debug_aranges 00000028 00000000 00000000 00000294 2**0
15 | CONTENTS, READONLY, DEBUGGING
16 | 5 .debug_info 00000593 00000000 00000000 000002bc 2**0
17 | CONTENTS, READONLY, DEBUGGING
18 | 6 .debug_abbrev 0000024b 00000000 00000000 0000084f 2**0
19 | CONTENTS, READONLY, DEBUGGING
20 | 7 .debug_line 00000321 00000000 00000000 00000a9a 2**0
21 | CONTENTS, READONLY, DEBUGGING
22 | 8 .debug_frame 00000094 00000000 00000000 00000dbc 2**2
23 | CONTENTS, READONLY, DEBUGGING
24 | 9 .debug_str 000001d6 00000000 00000000 00000e50 2**0
25 | CONTENTS, READONLY, DEBUGGING
26 | 10 .debug_loc 000003ee 00000000 00000000 00001026 2**0
27 | CONTENTS, READONLY, DEBUGGING
28 | 11 .debug_ranges 00000078 00000000 00000000 00001414 2**0
29 | CONTENTS, READONLY, DEBUGGING
30 |
31 | Disassembly of section .text:
32 |
33 | 00007e00 :
34 | #define appstart_vec (0)
35 | #endif // VIRTUAL_BOOT_PARTITION
36 |
37 |
38 | /* main program starts here */
39 | int main(void) {
40 | 7e00: 1f 92 push r1
41 | 7e02: cd b7 in r28, 0x3d ; 61
42 | 7e04: de b7 in r29, 0x3e ; 62
43 | // SP points to RAMEND
44 | // r1 contains zero
45 | //
46 | // If not, uncomment the following instructions:
47 | // cli();
48 | asm volatile ("clr __zero_reg__");
49 | 7e06: 11 24 eor r1, r1
50 | * Pass the reset reason to app. Also, it appears that an Uno poweron
51 | * can leave multiple reset flags set; we only want the bootloader to
52 | * run on an 'external reset only' status
53 | */
54 | #if !defined(__AVR_ATmega16__)
55 | ch = MCUSR;
56 | 7e08: 84 b7 in r24, 0x34 ; 52
57 | MCUSR = 0;
58 | 7e0a: 14 be out 0x34, r1 ; 52
59 | #else
60 | ch = MCUCSR;
61 | MCUCSR = 0;
62 | #endif
63 | if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
64 | 7e0c: 98 2f mov r25, r24
65 | 7e0e: 9d 70 andi r25, 0x0D ; 13
66 | 7e10: 09 f0 breq .+2 ; 0x7e14
67 | appStart(ch);
68 | 7e12: d7 d0 rcall .+430 ; 0x7fc2
69 |
70 | #if LED_START_FLASHES > 0
71 | // Set up Timer 1 for timeout counter
72 | TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
73 | 7e14: 85 e0 ldi r24, 0x05 ; 5
74 | 7e16: 80 93 81 00 sts 0x0081, r24
75 | UCSRA = _BV(U2X); //Double speed mode USART
76 | UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
77 | UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
78 | UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
79 | #else
80 | UART_SRA = _BV(U2X0); //Double speed mode USART0
81 | 7e1a: 82 e0 ldi r24, 0x02 ; 2
82 | 7e1c: 80 93 c0 00 sts 0x00C0, r24
83 | UART_SRB = _BV(RXEN0) | _BV(TXEN0);
84 | 7e20: 88 e1 ldi r24, 0x18 ; 24
85 | 7e22: 80 93 c1 00 sts 0x00C1, r24
86 | UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
87 | 7e26: 86 e0 ldi r24, 0x06 ; 6
88 | 7e28: 80 93 c2 00 sts 0x00C2, r24
89 | UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
90 | 7e2c: 85 e1 ldi r24, 0x15 ; 21
91 | 7e2e: 80 93 c4 00 sts 0x00C4, r24
92 | #endif
93 | #endif
94 |
95 | // Set up watchdog to trigger after 1s
96 | watchdogConfig(WATCHDOG_1S);
97 | 7e32: 8e e0 ldi r24, 0x0E ; 14
98 | 7e34: b1 d0 rcall .+354 ; 0x7f98
99 |
100 | #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
101 | /* Set LED pin as output */
102 | LED_DDR |= _BV(LED);
103 | 7e36: 25 9a sbi 0x04, 5 ; 4
104 | 7e38: 86 e0 ldi r24, 0x06 ; 6
105 | }
106 |
107 | #if LED_START_FLASHES > 0
108 | void flash_led(uint8_t count) {
109 | do {
110 | TCNT1 = -(F_CPU/(1024*16));
111 | 7e3a: 2c e3 ldi r18, 0x3C ; 60
112 | 7e3c: 3b ef ldi r19, 0xFB ; 251
113 | TIFR1 = _BV(TOV1);
114 | 7e3e: 91 e0 ldi r25, 0x01 ; 1
115 | }
116 |
117 | #if LED_START_FLASHES > 0
118 | void flash_led(uint8_t count) {
119 | do {
120 | TCNT1 = -(F_CPU/(1024*16));
121 | 7e40: 30 93 85 00 sts 0x0085, r19
122 | 7e44: 20 93 84 00 sts 0x0084, r18
123 | TIFR1 = _BV(TOV1);
124 | 7e48: 96 bb out 0x16, r25 ; 22
125 | while(!(TIFR1 & _BV(TOV1)));
126 | 7e4a: b0 9b sbis 0x16, 0 ; 22
127 | 7e4c: fe cf rjmp .-4 ; 0x7e4a
128 | #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
129 | LED_PORT ^= _BV(LED);
130 | #else
131 | LED_PIN |= _BV(LED);
132 | 7e4e: 1d 9a sbi 0x03, 5 ; 3
133 | }
134 | #endif
135 |
136 | // Watchdog functions. These are only safe with interrupts turned off.
137 | void watchdogReset() {
138 | __asm__ __volatile__ (
139 | 7e50: a8 95 wdr
140 | 7e52: 81 50 subi r24, 0x01 ; 1
141 | LED_PORT ^= _BV(LED);
142 | #else
143 | LED_PIN |= _BV(LED);
144 | #endif
145 | watchdogReset();
146 | } while (--count);
147 | 7e54: a9 f7 brne .-22 ; 0x7e40
148 | 7e56: 81 2c mov r8, r1
149 | 7e58: 91 2c mov r9, r1
150 | * Start the page erase and wait for it to finish. There
151 | * used to be code to do this while receiving the data over
152 | * the serial link, but the performance improvement was slight,
153 | * and we needed the space back.
154 | */
155 | __boot_page_erase_short((uint16_t)(void*)address);
156 | 7e5a: 13 e0 ldi r17, 0x03 ; 3
157 | */
158 | do {
159 | uint16_t a;
160 | a = *bufPtr++;
161 | a |= (*bufPtr++) << 8;
162 | __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
163 | 7e5c: 01 e0 ldi r16, 0x01 ; 1
164 | } while (len -= 2);
165 |
166 | /*
167 | * Actually Write the buffer to flash (and wait for it to finish.)
168 | */
169 | __boot_page_write_short((uint16_t)(void*)address);
170 | 7e5e: 25 e0 ldi r18, 0x05 ; 5
171 | 7e60: f2 2e mov r15, r18
172 | boot_spm_busy_wait();
173 | #if defined(RWWSRE)
174 | // Reenable read access to flash
175 | boot_rww_enable();
176 | 7e62: 31 e1 ldi r19, 0x11 ; 17
177 | 7e64: e3 2e mov r14, r19
178 | #endif
179 |
180 | /* Forever loop: exits by causing WDT reset */
181 | for (;;) {
182 | /* get character from UART */
183 | ch = getch();
184 | 7e66: 8c d0 rcall .+280 ; 0x7f80
185 |
186 | if(ch == STK_GET_PARAMETER) {
187 | 7e68: 81 34 cpi r24, 0x41 ; 65
188 | 7e6a: 79 f4 brne .+30 ; 0x7e8a
189 | unsigned char which = getch();
190 | 7e6c: 89 d0 rcall .+274 ; 0x7f80
191 | verifySpace();
192 | 7e6e: 89 83 std Y+1, r24 ; 0x01
193 | 7e70: 99 d0 rcall .+306 ; 0x7fa4
194 | /*
195 | * Send optiboot version as "SW version"
196 | * Note that the references to memory are optimized away.
197 | */
198 | if (which == 0x82) {
199 | 7e72: 89 81 ldd r24, Y+1 ; 0x01
200 | 7e74: 82 38 cpi r24, 0x82 ; 130
201 | 7e76: 11 f4 brne .+4 ; 0x7e7c
202 | putch(optiboot_version & 0xFF);
203 | 7e78: 82 e0 ldi r24, 0x02 ; 2
204 | 7e7a: 05 c0 rjmp .+10 ; 0x7e86
205 | } else if (which == 0x81) {
206 | 7e7c: 81 38 cpi r24, 0x81 ; 129
207 | 7e7e: 11 f4 brne .+4 ; 0x7e84
208 | putch(optiboot_version >> 8);
209 | 7e80: 86 e0 ldi r24, 0x06 ; 6
210 | 7e82: 01 c0 rjmp .+2 ; 0x7e86
211 | } else {
212 | /*
213 | * GET PARAMETER returns a generic 0x03 reply for
214 | * other parameters - enough to keep Avrdude happy
215 | */
216 | putch(0x03);
217 | 7e84: 83 e0 ldi r24, 0x03 ; 3
218 | 7e86: 75 d0 rcall .+234 ; 0x7f72
219 | 7e88: 71 c0 rjmp .+226 ; 0x7f6c
220 | }
221 | }
222 | else if(ch == STK_SET_DEVICE) {
223 | 7e8a: 82 34 cpi r24, 0x42 ; 66
224 | 7e8c: 11 f4 brne .+4 ; 0x7e92
225 | // SET DEVICE is ignored
226 | getNch(20);
227 | 7e8e: 84 e1 ldi r24, 0x14 ; 20
228 | 7e90: 03 c0 rjmp .+6 ; 0x7e98
229 | }
230 | else if(ch == STK_SET_DEVICE_EXT) {
231 | 7e92: 85 34 cpi r24, 0x45 ; 69
232 | 7e94: 19 f4 brne .+6 ; 0x7e9c
233 | // SET DEVICE EXT is ignored
234 | getNch(5);
235 | 7e96: 85 e0 ldi r24, 0x05 ; 5
236 | 7e98: 8d d0 rcall .+282 ; 0x7fb4
237 | 7e9a: 68 c0 rjmp .+208 ; 0x7f6c
238 | }
239 | else if(ch == STK_LOAD_ADDRESS) {
240 | 7e9c: 85 35 cpi r24, 0x55 ; 85
241 | 7e9e: 49 f4 brne .+18 ; 0x7eb2
242 | // LOAD ADDRESS
243 | uint16_t newAddress;
244 | newAddress = getch();
245 | 7ea0: 6f d0 rcall .+222 ; 0x7f80
246 | 7ea2: d8 2e mov r13, r24
247 | newAddress = (newAddress & 0xff) | (getch() << 8);
248 | 7ea4: 6d d0 rcall .+218 ; 0x7f80
249 | 7ea6: 8d 2c mov r8, r13
250 | 7ea8: 91 2c mov r9, r1
251 | 7eaa: 98 2a or r9, r24
252 | #ifdef RAMPZ
253 | // Transfer top bit to RAMPZ
254 | RAMPZ = (newAddress & 0x8000) ? 1 : 0;
255 | #endif
256 | newAddress += newAddress; // Convert from word address to byte address
257 | 7eac: 88 0c add r8, r8
258 | 7eae: 99 1c adc r9, r9
259 | 7eb0: 5c c0 rjmp .+184 ; 0x7f6a
260 | address = newAddress;
261 | verifySpace();
262 | }
263 | else if(ch == STK_UNIVERSAL) {
264 | 7eb2: 86 35 cpi r24, 0x56 ; 86
265 | 7eb4: 21 f4 brne .+8 ; 0x7ebe
266 | // UNIVERSAL command is ignored
267 | getNch(4);
268 | 7eb6: 84 e0 ldi r24, 0x04 ; 4
269 | 7eb8: 7d d0 rcall .+250 ; 0x7fb4
270 | putch(0x00);
271 | 7eba: 80 e0 ldi r24, 0x00 ; 0
272 | 7ebc: e4 cf rjmp .-56 ; 0x7e86
273 | }
274 | /* Write memory, length is big endian and is in bytes */
275 | else if(ch == STK_PROG_PAGE) {
276 | 7ebe: 84 36 cpi r24, 0x64 ; 100
277 | 7ec0: 09 f0 breq .+2 ; 0x7ec4
278 | 7ec2: 36 c0 rjmp .+108 ; 0x7f30
279 | // PROGRAM PAGE - we support flash programming only, not EEPROM
280 | uint8_t desttype;
281 | uint8_t *bufPtr;
282 | pagelen_t savelength;
283 |
284 | GETLENGTH(length);
285 | 7ec4: 5d d0 rcall .+186 ; 0x7f80
286 | 7ec6: 5c d0 rcall .+184 ; 0x7f80
287 | 7ec8: d8 2e mov r13, r24
288 | savelength = length;
289 | desttype = getch();
290 | 7eca: 5a d0 rcall .+180 ; 0x7f80
291 | 7ecc: c8 2e mov r12, r24
292 | 7ece: a1 2c mov r10, r1
293 | 7ed0: bb 24 eor r11, r11
294 | 7ed2: b3 94 inc r11
295 |
296 | // read a page worth of contents
297 | bufPtr = buff;
298 | do *bufPtr++ = getch();
299 | 7ed4: 55 d0 rcall .+170 ; 0x7f80
300 | 7ed6: f5 01 movw r30, r10
301 | 7ed8: 81 93 st Z+, r24
302 | 7eda: 5f 01 movw r10, r30
303 | while (--length);
304 | 7edc: de 12 cpse r13, r30
305 | 7ede: fa cf rjmp .-12 ; 0x7ed4
306 |
307 | // Read command terminator, start reply
308 | verifySpace();
309 | 7ee0: 61 d0 rcall .+194 ; 0x7fa4
310 | * void writebuffer(memtype, buffer, address, length)
311 | */
312 | static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
313 | uint16_t address, pagelen_t len)
314 | {
315 | switch (memtype) {
316 | 7ee2: f5 e4 ldi r31, 0x45 ; 69
317 | 7ee4: cf 12 cpse r12, r31
318 | 7ee6: 01 c0 rjmp .+2 ; 0x7eea
319 | 7ee8: ff cf rjmp .-2 ; 0x7ee8
320 | * Start the page erase and wait for it to finish. There
321 | * used to be code to do this while receiving the data over
322 | * the serial link, but the performance improvement was slight,
323 | * and we needed the space back.
324 | */
325 | __boot_page_erase_short((uint16_t)(void*)address);
326 | 7eea: f4 01 movw r30, r8
327 | 7eec: 17 bf out 0x37, r17 ; 55
328 | 7eee: e8 95 spm
329 | boot_spm_busy_wait();
330 | 7ef0: 07 b6 in r0, 0x37 ; 55
331 | 7ef2: 00 fc sbrc r0, 0
332 | 7ef4: fd cf rjmp .-6 ; 0x7ef0
333 | 7ef6: a4 01 movw r20, r8
334 | 7ef8: a0 e0 ldi r26, 0x00 ; 0
335 | 7efa: b1 e0 ldi r27, 0x01 ; 1
336 | /*
337 | * Copy data from the buffer into the flash write buffer.
338 | */
339 | do {
340 | uint16_t a;
341 | a = *bufPtr++;
342 | 7efc: 2c 91 ld r18, X
343 | 7efe: 12 96 adiw r26, 0x02 ; 2
344 | 7f00: cd 01 movw r24, r26
345 | 7f02: 01 97 sbiw r24, 0x01 ; 1
346 | a |= (*bufPtr++) << 8;
347 | 7f04: fc 01 movw r30, r24
348 | 7f06: 80 81 ld r24, Z
349 | 7f08: 30 e0 ldi r19, 0x00 ; 0
350 | 7f0a: 38 2b or r19, r24
351 | __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
352 | 7f0c: fa 01 movw r30, r20
353 | 7f0e: 09 01 movw r0, r18
354 | 7f10: 07 bf out 0x37, r16 ; 55
355 | 7f12: e8 95 spm
356 | 7f14: 11 24 eor r1, r1
357 | addrPtr += 2;
358 | 7f16: 4e 5f subi r20, 0xFE ; 254
359 | 7f18: 5f 4f sbci r21, 0xFF ; 255
360 | } while (len -= 2);
361 | 7f1a: da 12 cpse r13, r26
362 | 7f1c: ef cf rjmp .-34 ; 0x7efc
363 |
364 | /*
365 | * Actually Write the buffer to flash (and wait for it to finish.)
366 | */
367 | __boot_page_write_short((uint16_t)(void*)address);
368 | 7f1e: f4 01 movw r30, r8
369 | 7f20: f7 be out 0x37, r15 ; 55
370 | 7f22: e8 95 spm
371 | boot_spm_busy_wait();
372 | 7f24: 07 b6 in r0, 0x37 ; 55
373 | 7f26: 00 fc sbrc r0, 0
374 | 7f28: fd cf rjmp .-6 ; 0x7f24
375 | #if defined(RWWSRE)
376 | // Reenable read access to flash
377 | boot_rww_enable();
378 | 7f2a: e7 be out 0x37, r14 ; 55
379 | 7f2c: e8 95 spm
380 | 7f2e: 1e c0 rjmp .+60 ; 0x7f6c
381 | writebuffer(desttype, buff, address, savelength);
382 |
383 |
384 | }
385 | /* Read memory block mode, length is big endian. */
386 | else if(ch == STK_READ_PAGE) {
387 | 7f30: 84 37 cpi r24, 0x74 ; 116
388 | 7f32: 71 f4 brne .+28 ; 0x7f50
389 | uint8_t desttype;
390 | GETLENGTH(length);
391 | 7f34: 25 d0 rcall .+74 ; 0x7f80
392 | 7f36: 24 d0 rcall .+72 ; 0x7f80
393 | 7f38: d8 2e mov r13, r24
394 |
395 | desttype = getch();
396 | 7f3a: 22 d0 rcall .+68 ; 0x7f80
397 |
398 | verifySpace();
399 | 7f3c: 33 d0 rcall .+102 ; 0x7fa4
400 | 7f3e: 54 01 movw r10, r8
401 | __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
402 | #else
403 | // read a Flash byte and increment the address
404 | __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
405 | #endif
406 | putch(ch);
407 | 7f40: f5 01 movw r30, r10
408 | 7f42: 85 91 lpm r24, Z+
409 | 7f44: 5f 01 movw r10, r30
410 | 7f46: 15 d0 rcall .+42 ; 0x7f72
411 | } while (--length);
412 | 7f48: da 94 dec r13
413 | 7f4a: d1 10 cpse r13, r1
414 | 7f4c: f9 cf rjmp .-14 ; 0x7f40
415 | 7f4e: 0e c0 rjmp .+28 ; 0x7f6c
416 |
417 | read_mem(desttype, address, length);
418 | }
419 |
420 | /* Get device signature bytes */
421 | else if(ch == STK_READ_SIGN) {
422 | 7f50: 85 37 cpi r24, 0x75 ; 117
423 | 7f52: 39 f4 brne .+14 ; 0x7f62
424 | // READ SIGN - return what Avrdude wants to hear
425 | verifySpace();
426 | 7f54: 27 d0 rcall .+78 ; 0x7fa4
427 | putch(SIGNATURE_0);
428 | 7f56: 8e e1 ldi r24, 0x1E ; 30
429 | 7f58: 0c d0 rcall .+24 ; 0x7f72
430 | putch(SIGNATURE_1);
431 | 7f5a: 85 e9 ldi r24, 0x95 ; 149
432 | 7f5c: 0a d0 rcall .+20 ; 0x7f72
433 | putch(SIGNATURE_2);
434 | 7f5e: 86 e1 ldi r24, 0x16 ; 22
435 | 7f60: 92 cf rjmp .-220 ; 0x7e86
436 | }
437 | else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
438 | 7f62: 81 35 cpi r24, 0x51 ; 81
439 | 7f64: 11 f4 brne .+4 ; 0x7f6a
440 | // Adaboot no-wait mod
441 | watchdogConfig(WATCHDOG_16MS);
442 | 7f66: 88 e0 ldi r24, 0x08 ; 8
443 | 7f68: 17 d0 rcall .+46 ; 0x7f98
444 | verifySpace();
445 | }
446 | else {
447 | // This covers the response to commands like STK_ENTER_PROGMODE
448 | verifySpace();
449 | 7f6a: 1c d0 rcall .+56 ; 0x7fa4
450 | }
451 | putch(STK_OK);
452 | 7f6c: 80 e1 ldi r24, 0x10 ; 16
453 | 7f6e: 01 d0 rcall .+2 ; 0x7f72
454 | }
455 | 7f70: 7a cf rjmp .-268 ; 0x7e66
456 |
457 | 00007f72 :
458 | }
459 |
460 | void putch(char ch) {
461 | #ifndef SOFT_UART
462 | while (!(UART_SRA & _BV(UDRE0)));
463 | 7f72: 90 91 c0 00 lds r25, 0x00C0
464 | 7f76: 95 ff sbrs r25, 5
465 | 7f78: fc cf rjmp .-8 ; 0x7f72
466 | UART_UDR = ch;
467 | 7f7a: 80 93 c6 00 sts 0x00C6, r24
468 | 7f7e: 08 95 ret
469 |
470 | 00007f80 :
471 | [uartBit] "I" (UART_RX_BIT)
472 | :
473 | "r25"
474 | );
475 | #else
476 | while(!(UART_SRA & _BV(RXC0)))
477 | 7f80: 80 91 c0 00 lds r24, 0x00C0
478 | 7f84: 87 ff sbrs r24, 7
479 | 7f86: fc cf rjmp .-8 ; 0x7f80
480 | ;
481 | if (!(UART_SRA & _BV(FE0))) {
482 | 7f88: 80 91 c0 00 lds r24, 0x00C0
483 | 7f8c: 84 fd sbrc r24, 4
484 | 7f8e: 01 c0 rjmp .+2 ; 0x7f92
485 | }
486 | #endif
487 |
488 | // Watchdog functions. These are only safe with interrupts turned off.
489 | void watchdogReset() {
490 | __asm__ __volatile__ (
491 | 7f90: a8 95 wdr
492 | * don't care that an invalid char is returned...)
493 | */
494 | watchdogReset();
495 | }
496 |
497 | ch = UART_UDR;
498 | 7f92: 80 91 c6 00 lds r24, 0x00C6
499 | LED_PIN |= _BV(LED);
500 | #endif
501 | #endif
502 |
503 | return ch;
504 | }
505 | 7f96: 08 95 ret
506 |
507 | 00007f98 :
508 | "wdr\n"
509 | );
510 | }
511 |
512 | void watchdogConfig(uint8_t x) {
513 | WDTCSR = _BV(WDCE) | _BV(WDE);
514 | 7f98: e0 e6 ldi r30, 0x60 ; 96
515 | 7f9a: f0 e0 ldi r31, 0x00 ; 0
516 | 7f9c: 98 e1 ldi r25, 0x18 ; 24
517 | 7f9e: 90 83 st Z, r25
518 | WDTCSR = x;
519 | 7fa0: 80 83 st Z, r24
520 | 7fa2: 08 95 ret
521 |
522 | 00007fa4 :
523 | do getch(); while (--count);
524 | verifySpace();
525 | }
526 |
527 | void verifySpace() {
528 | if (getch() != CRC_EOP) {
529 | 7fa4: ed df rcall .-38 ; 0x7f80
530 | 7fa6: 80 32 cpi r24, 0x20 ; 32
531 | 7fa8: 19 f0 breq .+6 ; 0x7fb0
532 | watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
533 | 7faa: 88 e0 ldi r24, 0x08 ; 8
534 | 7fac: f5 df rcall .-22 ; 0x7f98
535 | while (1) // and busy-loop so that WD causes
536 | ; // a reset and app start.
537 | 7fae: ff cf rjmp .-2 ; 0x7fae
538 | }
539 | putch(STK_INSYNC);
540 | 7fb0: 84 e1 ldi r24, 0x14 ; 20
541 | 7fb2: df cf rjmp .-66 ; 0x7f72
542 |
543 | 00007fb4 :
544 | ::[count] "M" (UART_B_VALUE)
545 | );
546 | }
547 | #endif
548 |
549 | void getNch(uint8_t count) {
550 | 7fb4: cf 93 push r28
551 | 7fb6: c8 2f mov r28, r24
552 | do getch(); while (--count);
553 | 7fb8: e3 df rcall .-58 ; 0x7f80
554 | 7fba: c1 50 subi r28, 0x01 ; 1
555 | 7fbc: e9 f7 brne .-6 ; 0x7fb8
556 | verifySpace();
557 | }
558 | 7fbe: cf 91 pop r28
559 | }
560 | #endif
561 |
562 | void getNch(uint8_t count) {
563 | do getch(); while (--count);
564 | verifySpace();
565 | 7fc0: f1 cf rjmp .-30 ; 0x7fa4
566 |
567 | 00007fc2 :
568 |
569 | void appStart(uint8_t rstFlags) {
570 | // save the reset flags in the designated register
571 | // This can be saved in a main program by putting code in .init0 (which
572 | // executes before normal c init code) to save R2 to a global variable.
573 | __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
574 | 7fc2: 28 2e mov r2, r24
575 |
576 | watchdogConfig(WATCHDOG_OFF);
577 | 7fc4: 80 e0 ldi r24, 0x00 ; 0
578 | 7fc6: e8 df rcall .-48 ; 0x7f98
579 | // Note that appstart_vec is defined so that this works with either
580 | // real or virtual boot partitions.
581 | __asm__ __volatile__ (
582 | 7fc8: e0 e0 ldi r30, 0x00 ; 0
583 | 7fca: ff 27 eor r31, r31
584 | 7fcc: 09 94 ijmp
585 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/optiboot_m328pb_autobaud.hex:
--------------------------------------------------------------------------------
1 | :107E00001F92CDB7DEB7112484B714BE982F9D7092
2 | :107E100009F0E6D082E08093C00088E18093C10041
3 | :107E200086E08093C20080E18093C4008EE0C3D0DE
4 | :107E300010928500109284004899FECF489BFECF97
5 | :107E400081E0809381004899FECF109281002091BB
6 | :107E50008400822F20918500922F089644E0969509
7 | :107E600087954A95E1F701978093C40098D08033B5
8 | :107E7000E9F7A7D0812C912C13E001E025E0F22E48
9 | :107E800031E1E32E8CD0813479F489D0898399D083
10 | :107E90008981823811F482E005C0813811F486E0CE
11 | :107EA00001C083E075D071C0823411F484E103C055
12 | :107EB000853419F485E08DD068C0853549F46FD0DC
13 | :107EC000D82E6DD08D2C912C982A880C991C5CC0D2
14 | :107ED000863521F484E07DD080E0E4CF843609F05B
15 | :107EE00036C05DD05CD0D82E5AD0C82EA12CBB2471
16 | :107EF000B39455D0F50181935F01DE12FACF61D0C2
17 | :107F0000F5E4CF1201C0FFCFF40117BFE89507B623
18 | :107F100000FCFDCFA401A0E0B1E02C911296CD01B0
19 | :107F20000197FC01808130E0382BFA01090107BF7D
20 | :107F3000E89511244E5F5F4FDA12EFCFF401F7BEE0
21 | :107F4000E89507B600FCFDCFE7BEE8951EC0843774
22 | :107F500071F425D024D0D82E22D033D05401F5018D
23 | :107F600085915F0115D0DA94D110F9CF0EC0853715
24 | :107F700039F427D08EE10CD085E90AD086E192CF82
25 | :107F8000813511F488E017D01CD080E101D07ACF80
26 | :107F90009091C00095FFFCCF8093C600089580911A
27 | :107FA000C00087FFFCCF8091C00084FD01C0A89570
28 | :107FB0008091C6000895E0E6F0E098E19083808328
29 | :107FC0000895EDDF803219F088E0F5DFFFCF84E11E
30 | :107FD000DFCFCF93C82FE3DFC150E9F7CF91F1CFC7
31 | :0C7FE000282E80E0E8DFE0E0FF27099495
32 | :0400000300007E007B
33 | :00000001FF
34 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/pin_defs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * pin_defs.h
3 | * optiboot helper defining the default pin assignments (LED, SOFT_UART)
4 | * for the various chips that are supported. This also has some ugly macros
5 | * for selecting among various UARTs and LED possibilities using command-line
6 | * defines like "UART=2 LED=B5"
7 | *
8 | * Copyright 2013-2015 by Bill Westfield.
9 | * Copyright 2010 by Peter Knight.
10 | * This software is licensed under version 2 of the Gnu Public Licence.
11 | * See optiboot.c for details.
12 | */
13 |
14 | /*------------------------------------------------------------------------ */
15 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
16 | /*------------------------------------------------------------------------ */
17 |
18 | /* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove
19 | */
20 | #if !defined(LED)
21 | #define LED B5
22 | #endif
23 |
24 | /* Ports for soft UART */
25 | #ifdef SOFT_UART
26 | #define UART_PORT PORTD
27 | #define UART_PIN PIND
28 | #define UART_DDR DDRD
29 | #define UART_TX_BIT 1
30 | #define UART_RX_BIT 0
31 | #endif
32 | #endif
33 |
34 | /*
35 | * Handle devices with up to 4 uarts (eg m1280.) Rather inelegantly.
36 | * Note that mega8/m32 still needs special handling, because ubrr is handled
37 | * differently.
38 | */
39 | #if UART == 0
40 | # define UART_SRA UCSR0A
41 | # define UART_SRB UCSR0B
42 | # define UART_SRC UCSR0C
43 | # define UART_SRL UBRR0L
44 | # define UART_UDR UDR0
45 | #elif UART == 1
46 | #if !defined(UDR1)
47 | #error UART == 1, but no UART1 on device
48 | #endif
49 | # define UART_SRA UCSR1A
50 | # define UART_SRB UCSR1B
51 | # define UART_SRC UCSR1C
52 | # define UART_SRL UBRR1L
53 | # define UART_UDR UDR1
54 | #elif UART == 2
55 | #if !defined(UDR2)
56 | #error UART == 2, but no UART2 on device
57 | #endif
58 | # define UART_SRA UCSR2A
59 | # define UART_SRB UCSR2B
60 | # define UART_SRC UCSR2C
61 | # define UART_SRL UBRR2L
62 | # define UART_UDR UDR2
63 | #elif UART == 3
64 | #if !defined(UDR1)
65 | #error UART == 3, but no UART3 on device
66 | #endif
67 | # define UART_SRA UCSR3A
68 | # define UART_SRB UCSR3B
69 | # define UART_SRC UCSR3C
70 | # define UART_SRL UBRR3L
71 | # define UART_UDR UDR3
72 | #endif
73 |
74 | #if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
75 | //Name conversion R.Wiersma
76 | #define UCSR0A UCSRA
77 | #define UDR0 UDR
78 | #define UDRE0 UDRE
79 | #define RXC0 RXC
80 | #define FE0 FE
81 | #define TIFR1 TIFR
82 | #define WDTCSR WDTCR
83 | #endif
84 | #if defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
85 | #define WDCE WDTOE
86 | #endif
87 |
88 | /* Luminet support */
89 | /*------------------------------------------------------------------------ */
90 | #if defined(__AVR_ATtiny84__)
91 | /*------------------------------------------------------------------------ */
92 | /* Red LED is connected to pin PA4 */
93 | #if !defined(LED)
94 | #define LED A4
95 | #endif
96 |
97 | /* Ports for soft UART - left port only for now. TX/RX on PA2/PA3 */
98 | #ifdef SOFT_UART
99 | #define UART_PORT PORTA
100 | #define UART_PIN PINA
101 | #define UART_DDR DDRA
102 | #define UART_TX_BIT 2
103 | #define UART_RX_BIT 3
104 | #endif
105 | #endif
106 |
107 | /*------------------------------------------------------------------------ */
108 | /* Sanguino support (and other 40pin DIP cpus) */
109 | #if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega32__) || defined (__AVR_ATmega16__)
110 | /*------------------------------------------------------------------------ */
111 | /* Onboard LED is connected to pin PB0 on Sanguino */
112 | #if !defined(LED)
113 | #define LED B0
114 | #endif
115 |
116 | /* Ports for soft UART */
117 | #ifdef SOFT_UART
118 | #define UART_PORT PORTD
119 | #define UART_PIN PIND
120 | #define UART_DDR DDRD
121 | #define UART_TX_BIT 1
122 | #define UART_RX_BIT 0
123 | #endif
124 | #endif
125 |
126 | /*------------------------------------------------------------------------ */
127 | /* Mega support */
128 | #if defined(__AVR_ATmega1280__)
129 | /*------------------------------------------------------------------------ */
130 | /* Onboard LED is connected to pin PB7 on Arduino Mega */
131 | #if !defined(LED)
132 | #define LED B7
133 | #endif
134 |
135 | /* Ports for soft UART */
136 | #ifdef SOFT_UART
137 | #define UART_PORT PORTE
138 | #define UART_PIN PINE
139 | #define UART_DDR DDRE
140 | #define UART_TX_BIT 1
141 | #define UART_RX_BIT 0
142 | #endif
143 | #endif
144 |
145 | /*
146 | * ------------------------------------------------------------------------
147 | * A bunch of macros to enable the LED to be specifed as "B5" for bit 5
148 | * of port B, and similar.
149 | */
150 |
151 | #define A0 0x100
152 | #define A1 0x101
153 | #define A2 0x102
154 | #define A3 0x103
155 | #define A4 0x104
156 | #define A5 0x105
157 | #define A6 0x106
158 | #define A7 0x107
159 |
160 | #define B0 0x200
161 | #define B1 0x201
162 | #define B2 0x202
163 | #define B3 0x203
164 | #define B4 0x204
165 | #define B5 0x205
166 | #define B6 0x206
167 | #define B7 0x207
168 |
169 | #define C0 0x300
170 | #define C1 0x301
171 | #define C2 0x302
172 | #define C3 0x303
173 | #define C4 0x304
174 | #define C5 0x305
175 | #define C6 0x306
176 | #define C7 0x307
177 |
178 | #define D0 0x400
179 | #define D1 0x401
180 | #define D2 0x402
181 | #define D3 0x403
182 | #define D4 0x404
183 | #define D5 0x405
184 | #define D6 0x406
185 | #define D7 0x407
186 |
187 | #define E0 0x500
188 | #define E1 0x501
189 | #define E2 0x502
190 | #define E3 0x503
191 | #define E4 0x504
192 | #define E5 0x505
193 | #define E6 0x506
194 | #define E7 0x507
195 |
196 | #define F0 0x600
197 | #define F1 0x601
198 | #define F2 0x602
199 | #define F3 0x603
200 | #define F4 0x604
201 | #define F5 0x605
202 | #define F6 0x606
203 | #define F7 0x607
204 |
205 | #define G0 0x700
206 | #define G1 0x701
207 | #define G2 0x702
208 | #define G3 0x703
209 | #define G4 0x704
210 | #define G5 0x705
211 | #define G6 0x706
212 | #define G7 0x707
213 |
214 | #define H0 0x800
215 | #define H1 0x801
216 | #define H2 0x802
217 | #define H3 0x803
218 | #define H4 0x804
219 | #define H5 0x805
220 | #define H6 0x806
221 | #define H7 0x807
222 |
223 | #define J0 0xA00
224 | #define J1 0xA01
225 | #define J2 0xA02
226 | #define J3 0xA03
227 | #define J4 0xA04
228 | #define J5 0xA05
229 | #define J6 0xA06
230 | #define J7 0xA07
231 |
232 | #define K0 0xB00
233 | #define K1 0xB01
234 | #define K2 0xB02
235 | #define K3 0xB03
236 | #define K4 0xB04
237 | #define K5 0xB05
238 | #define K6 0xB06
239 | #define K7 0xB07
240 |
241 | #define L0 0xC00
242 | #define L1 0xC01
243 | #define L2 0xC02
244 | #define L3 0xC03
245 | #define L4 0xC04
246 | #define L5 0xC05
247 | #define L6 0xC06
248 | #define L7 0xC07
249 |
250 |
251 |
252 | #if LED == B0
253 | #undef LED
254 | #define LED_DDR DDRB
255 | #define LED_PORT PORTB
256 | #define LED_PIN PINB
257 | #define LED PINB0
258 | #elif LED == B1
259 | #undef LED
260 | #define LED_DDR DDRB
261 | #define LED_PORT PORTB
262 | #define LED_PIN PINB
263 | #define LED PINB1
264 | #elif LED == B2
265 | #undef LED
266 | #define LED_DDR DDRB
267 | #define LED_PORT PORTB
268 | #define LED_PIN PINB
269 | #define LED PINB2
270 | #elif LED == B3
271 | #undef LED
272 | #define LED_DDR DDRB
273 | #define LED_PORT PORTB
274 | #define LED_PIN PINB
275 | #define LED PINB3
276 | #elif LED == B4
277 | #undef LED
278 | #define LED_DDR DDRB
279 | #define LED_PORT PORTB
280 | #define LED_PIN PINB
281 | #define LED PINB4
282 | #elif LED == B5
283 | #undef LED
284 | #define LED_DDR DDRB
285 | #define LED_PORT PORTB
286 | #define LED_PIN PINB
287 | #define LED PINB5
288 | #elif LED == B6
289 | #undef LED
290 | #define LED_DDR DDRB
291 | #define LED_PORT PORTB
292 | #define LED_PIN PINB
293 | #define LED PINB6
294 | #elif LED == B7
295 | #undef LED
296 | #define LED_DDR DDRB
297 | #define LED_PORT PORTB
298 | #define LED_PIN PINB
299 | #define LED PINB7
300 |
301 | #elif LED == C0
302 | #undef LED
303 | #define LED_DDR DDRC
304 | #define LED_PORT PORTC
305 | #define LED_PIN PINC
306 | #define LED PINC0
307 | #elif LED == C1
308 | #undef LED
309 | #define LED_DDR DDRC
310 | #define LED_PORT PORTC
311 | #define LED_PIN PINC
312 | #define LED PINC1
313 | #elif LED == C2
314 | #undef LED
315 | #define LED_DDR DDRC
316 | #define LED_PORT PORTC
317 | #define LED_PIN PINC
318 | #define LED PINC2
319 | #elif LED == C3
320 | #undef LED
321 | #define LED_DDR DDRC
322 | #define LED_PORT PORTC
323 | #define LED_PIN PINC
324 | #define LED PINC3
325 | #elif LED == C4
326 | #undef LED
327 | #define LED_DDR DDRC
328 | #define LED_PORT PORTC
329 | #define LED_PIN PINC
330 | #define LED PINC4
331 | #elif LED == C5
332 | #undef LED
333 | #define LED_DDR DDRC
334 | #define LED_PORT PORTC
335 | #define LED_PIN PINC
336 | #define LED PINC5
337 | #elif LED == C6
338 | #undef LED
339 | #define LED_DDR DDRC
340 | #define LED_PORT PORTC
341 | #define LED_PIN PINC
342 | #define LED PINC6
343 | #elif LED == C7
344 | #undef LED
345 | #define LED_DDR DDRC
346 | #define LED_PORT PORTC
347 | #define LED_PIN PINC
348 | #define LED PINC7
349 |
350 | #elif LED == D0
351 | #undef LED
352 | #define LED_DDR DDRD
353 | #define LED_PORT PORTD
354 | #define LED_PIN PIND
355 | #define LED PIND0
356 | #elif LED == D1
357 | #undef LED
358 | #define LED_DDR DDRD
359 | #define LED_PORT PORTD
360 | #define LED_PIN PIND
361 | #define LED PIND1
362 | #elif LED == D2
363 | #undef LED
364 | #define LED_DDR DDRD
365 | #define LED_PORT PORTD
366 | #define LED_PIN PIND
367 | #define LED PIND2
368 | #elif LED == D3
369 | #undef LED
370 | #define LED_DDR DDRD
371 | #define LED_PORT PORTD
372 | #define LED_PIN PIND
373 | #define LED PIND3
374 | #elif LED == D4
375 | #undef LED
376 | #define LED_DDR DDRD
377 | #define LED_PORT PORTD
378 | #define LED_PIN PIND
379 | #define LED PIND4
380 | #elif LED == D5
381 | #undef LED
382 | #define LED_DDR DDRD
383 | #define LED_PORT PORTD
384 | #define LED_PIN PIND
385 | #define LED PIND5
386 | #elif LED == D6
387 | #undef LED
388 | #define LED_DDR DDRD
389 | #define LED_PORT PORTD
390 | #define LED_PIN PIND
391 | #define LED PIND6
392 | #elif LED == D7
393 | #undef LED
394 | #define LED_DDR DDRD
395 | #define LED_PORT PORTD
396 | #define LED_PIN PIND
397 | #define LED PIND7
398 |
399 | #elif LED == E0
400 | #undef LED
401 | #define LED_DDR DDRE
402 | #define LED_PORT PORTE
403 | #define LED_PIN PINE
404 | #define LED PINE0
405 | #elif LED == E1
406 | #undef LED
407 | #define LED_DDR DDRE
408 | #define LED_PORT PORTE
409 | #define LED_PIN PINE
410 | #define LED PINE1
411 | #elif LED == E2
412 | #undef LED
413 | #define LED_DDR DDRE
414 | #define LED_PORT PORTE
415 | #define LED_PIN PINE
416 | #define LED PINE2
417 | #elif LED == E3
418 | #undef LED
419 | #define LED_DDR DDRE
420 | #define LED_PORT PORTE
421 | #define LED_PIN PINE
422 | #define LED PINE3
423 | #elif LED == E4
424 | #undef LED
425 | #define LED_DDR DDRE
426 | #define LED_PORT PORTE
427 | #define LED_PIN PINE
428 | #define LED PINE4
429 | #elif LED == E5
430 | #undef LED
431 | #define LED_DDR DDRE
432 | #define LED_PORT PORTE
433 | #define LED_PIN PINE
434 | #define LED PINE5
435 | #elif LED == E6
436 | #undef LED
437 | #define LED_DDR DDRE
438 | #define LED_PORT PORTE
439 | #define LED_PIN PINE
440 | #define LED PINE6
441 | #elif LED == E7
442 | #undef LED
443 | #define LED_DDR DDRE
444 | #define LED_PORT PORTE
445 | #define LED_PIN PINE
446 | #define LED PINE7
447 |
448 | #elif LED == F0
449 | #undef LED
450 | #define LED_DDR DDRF
451 | #define LED_PORT PORTF
452 | #define LED_PIN PINF
453 | #define LED PINF0
454 | #elif LED == F1
455 | #undef LED
456 | #define LED_DDR DDRF
457 | #define LED_PORT PORTF
458 | #define LED_PIN PINF
459 | #define LED PINF1
460 | #elif LED == F2
461 | #undef LED
462 | #define LED_DDR DDRF
463 | #define LED_PORT PORTF
464 | #define LED_PIN PINF
465 | #define LED PINF2
466 | #elif LED == F3
467 | #undef LED
468 | #define LED_DDR DDRF
469 | #define LED_PORT PORTF
470 | #define LED_PIN PINF
471 | #define LED PINF3
472 | #elif LED == F4
473 | #undef LED
474 | #define LED_DDR DDRF
475 | #define LED_PORT PORTF
476 | #define LED_PIN PINF
477 | #define LED PINF4
478 | #elif LED == F5
479 | #undef LED
480 | #define LED_DDR DDRF
481 | #define LED_PORT PORTF
482 | #define LED_PIN PINF
483 | #define LED PINF5
484 | #elif LED == F6
485 | #undef LED
486 | #define LED_DDR DDRF
487 | #define LED_PORT PORTF
488 | #define LED_PIN PINF
489 | #define LED PINF6
490 | #elif LED == F7
491 | #undef LED
492 | #define LED_DDR DDRF
493 | #define LED_PORT PORTF
494 | #define LED_PIN PINF
495 | #define LED PINF7
496 |
497 | #elif LED == G0
498 | #undef LED
499 | #define LED_DDR DDRG
500 | #define LED_PORT PORTG
501 | #define LED_PIN PING
502 | #define LED PING0
503 | #elif LED == G1
504 | #undef LED
505 | #define LED_DDR DDRG
506 | #define LED_PORT PORTG
507 | #define LED_PIN PING
508 | #define LED PING1
509 | #elif LED == G2
510 | #undef LED
511 | #define LED_DDR DDRG
512 | #define LED_PORT PORTG
513 | #define LED_PIN PING
514 | #define LED PING2
515 | #elif LED == G3
516 | #undef LED
517 | #define LED_DDR DDRG
518 | #define LED_PORT PORTG
519 | #define LED_PIN PING
520 | #define LED PING3
521 | #elif LED == G4
522 | #undef LED
523 | #define LED_DDR DDRG
524 | #define LED_PORT PORTG
525 | #define LED_PIN PING
526 | #define LED PING4
527 | #elif LED == G5
528 | #undef LED
529 | #define LED_DDR DDRG
530 | #define LED_PORT PORTG
531 | #define LED_PIN PING
532 | #define LED PING5
533 | #elif LED == G6
534 | #undef LED
535 | #define LED_DDR DDRG
536 | #define LED_PORT PORTG
537 | #define LED_PIN PING
538 | #define LED PING6
539 | #elif LED == G7
540 | #undef LED
541 | #define LED_DDR DDRG
542 | #define LED_PORT PORTG
543 | #define LED_PIN PING
544 | #define LED PING7
545 |
546 | #elif LED == H0
547 | #undef LED
548 | #define LED_DDR DDRH
549 | #define LED_PORT PORTH
550 | #define LED_PIN PINH
551 | #define LED PINH0
552 | #elif LED == H1
553 | #undef LED
554 | #define LED_DDR DDRH
555 | #define LED_PORT PORTH
556 | #define LED_PIN PINH
557 | #define LED PINH1
558 | #elif LED == H2
559 | #undef LED
560 | #define LED_DDR DDRH
561 | #define LED_PORT PORTH
562 | #define LED_PIN PINH
563 | #define LED PINH2
564 | #elif LED == H3
565 | #undef LED
566 | #define LED_DDR DDRH
567 | #define LED_PORT PORTH
568 | #define LED_PIN PINH
569 | #define LED PINH3
570 | #elif LED == H4
571 | #undef LED
572 | #define LED_DDR DDRH
573 | #define LED_PORT PORTH
574 | #define LED_PIN PINH
575 | #define LED PINH4
576 | #elif LED == H5
577 | #undef LED
578 | #define LED_DDR DDRH
579 | #define LED_PORT PORTH
580 | #define LED_PIN PINH
581 | #define LED PINH5
582 | #elif LED == H6
583 | #undef LED
584 | #define LED_DDR DDRH
585 | #define LED_PORT PORTH
586 | #define LED_PIN PINH
587 | #define LED PINH6
588 | #elif LED == H7
589 | #undef LED
590 | #define LED_DDR DDRH
591 | #define LED_PORT PORTH
592 | #define LED_PIN PINH
593 | #define LED PINH7
594 |
595 | #elif LED == J0
596 | #undef LED
597 | #define LED_DDR DDRJ
598 | #define LED_PORT PORTJ
599 | #define LED_PIN PINJ
600 | #define LED PINJ0
601 | #elif LED == J1
602 | #undef LED
603 | #define LED_DDR DDRJ
604 | #define LED_PORT PORTJ
605 | #define LED_PIN PINJ
606 | #define LED PINJ1
607 | #elif LED == J2
608 | #undef LED
609 | #define LED_DDR DDRJ
610 | #define LED_PORT PORTJ
611 | #define LED_PIN PINJ
612 | #define LED PINJ2
613 | #elif LED == J3
614 | #undef LED
615 | #define LED_DDR DDRJ
616 | #define LED_PORT PORTJ
617 | #define LED_PIN PINJ
618 | #define LED PINJ3
619 | #elif LED == J4
620 | #undef LED
621 | #define LED_DDR DDRJ
622 | #define LED_PORT PORTJ
623 | #define LED_PIN PINJ
624 | #define LED PINJ4
625 | #elif LED == J5
626 | #undef LED
627 | #define LED_DDR DDRJ
628 | #define LED_PORT PORTJ
629 | #define LED_PIN PINJ
630 | #define LED PINJ5
631 | #elif LED == J6
632 | #undef LED
633 | #define LED_DDR DDRJ
634 | #define LED_PORT PORTJ
635 | #define LED_PIN PINJ
636 | #define LED PINJ6
637 | #elif LED == J7
638 | #undef LED
639 | #define LED_DDR DDRJ
640 | #define LED_PORT PORTJ
641 | #define LED_PIN PINJ
642 | #define LED PINJ7
643 |
644 | #elif LED == K0
645 | #undef LED
646 | #define LED_DDR DDRK
647 | #define LED_PORT PORTK
648 | #define LED_PIN PINK
649 | #define LED PINK0
650 | #elif LED == K1
651 | #undef LED
652 | #define LED_DDR DDRK
653 | #define LED_PORT PORTK
654 | #define LED_PIN PINK
655 | #define LED PINK1
656 | #elif LED == K2
657 | #undef LED
658 | #define LED_DDR DDRK
659 | #define LED_PORT PORTK
660 | #define LED_PIN PINK
661 | #define LED PINK2
662 | #elif LED == K3
663 | #undef LED
664 | #define LED_DDR DDRK
665 | #define LED_PORT PORTK
666 | #define LED_PIN PINK
667 | #define LED PINK3
668 | #elif LED == K4
669 | #undef LED
670 | #define LED_DDR DDRK
671 | #define LED_PORT PORTK
672 | #define LED_PIN PINK
673 | #define LED PINK4
674 | #elif LED == K5
675 | #undef LED
676 | #define LED_DDR DDRK
677 | #define LED_PORT PORTK
678 | #define LED_PIN PINK
679 | #define LED PINK5
680 | #elif LED == K6
681 | #undef LED
682 | #define LED_DDR DDRK
683 | #define LED_PORT PORTK
684 | #define LED_PIN PINK
685 | #define LED PINK6
686 | #elif LED == K7
687 | #undef LED
688 | #define LED_DDR DDRK
689 | #define LED_PORT PORTK
690 | #define LED_PIN PINK
691 | #define LED PINK7
692 |
693 | #elif LED == L0
694 | #undef LED
695 | #define LED_DDR DDRL
696 | #define LED_PORT PORTL
697 | #define LED_PIN PINL
698 | #define LED PINL0
699 | #elif LED == L1
700 | #undef LED
701 | #define LED_DDR DDRL
702 | #define LED_PORT PORTL
703 | #define LED_PIN PINL
704 | #define LED PINL1
705 | #elif LED == L2
706 | #undef LED
707 | #define LED_DDR DDRL
708 | #define LED_PORT PORTL
709 | #define LED_PIN PINL
710 | #define LED PINL2
711 | #elif LED == L3
712 | #undef LED
713 | #define LED_DDR DDRL
714 | #define LED_PORT PORTL
715 | #define LED_PIN PINL
716 | #define LED PINL3
717 | #elif LED == L4
718 | #undef LED
719 | #define LED_DDR DDRL
720 | #define LED_PORT PORTL
721 | #define LED_PIN PINL
722 | #define LED PINL4
723 | #elif LED == L5
724 | #undef LED
725 | #define LED_DDR DDRL
726 | #define LED_PORT PORTL
727 | #define LED_PIN PINL
728 | #define LED PINL5
729 | #elif LED == L6
730 | #undef LED
731 | #define LED_DDR DDRL
732 | #define LED_PORT PORTL
733 | #define LED_PIN PINL
734 | #define LED PINL6
735 | #elif LED == L7
736 | #undef LED
737 | #define LED_DDR DDRL
738 | #define LED_PORT PORTL
739 | #define LED_PIN PINL
740 | #define LED PINL7
741 |
742 | #elif LED == A0
743 | #undef LED
744 | #define LED_DDR DDRA
745 | #define LED_PORT PORTA
746 | #define LED_PIN PINA
747 | #define LED PINA0
748 | #elif LED == A1
749 | #undef LED
750 | #define LED_DDR DDRA
751 | #define LED_PORT PORTA
752 | #define LED_PIN PINA
753 | #define LED PINA1
754 | #elif LED == A2
755 | #undef LED
756 | #define LED_DDR DDRA
757 | #define LED_PORT PORTA
758 | #define LED_PIN PINA
759 | #define LED PINA2
760 | #elif LED == A3
761 | #undef LED
762 | #define LED_DDR DDRA
763 | #define LED_PORT PORTA
764 | #define LED_PIN PINA
765 | #define LED PINA3
766 | #elif LED == A4
767 | #undef LED
768 | #define LED_DDR DDRA
769 | #define LED_PORT PORTA
770 | #define LED_PIN PINA
771 | #define LED PINA4
772 | #elif LED == A5
773 | #undef LED
774 | #define LED_DDR DDRA
775 | #define LED_PORT PORTA
776 | #define LED_PIN PINA
777 | #define LED PINA5
778 | #elif LED == A6
779 | #undef LED
780 | #define LED_DDR DDRA
781 | #define LED_PORT PORTA
782 | #define LED_PIN PINA
783 | #define LED PINA6
784 | #elif LED == A7
785 | #undef LED
786 | #define LED_DDR DDRA
787 | #define LED_PORT PORTA
788 | #define LED_PIN PINA
789 | #define LED PINA7
790 |
791 | #else
792 | #error -------------------------------------------
793 | #error Unrecognized LED name. Should be like "B5"
794 | #error -------------------------------------------
795 | #endif
796 |
--------------------------------------------------------------------------------
/src/bootloaders/optiboot/stk500.h:
--------------------------------------------------------------------------------
1 | /* STK500 constants list, from AVRDUDE
2 | *
3 | * Trivial set of constants derived from Atmel App Note AVR061
4 | * Not copyrighted. Released to the public domain.
5 | */
6 |
7 | #define STK_OK 0x10
8 | #define STK_FAILED 0x11 // Not used
9 | #define STK_UNKNOWN 0x12 // Not used
10 | #define STK_NODEVICE 0x13 // Not used
11 | #define STK_INSYNC 0x14 // ' '
12 | #define STK_NOSYNC 0x15 // Not used
13 | #define ADC_CHANNEL_ERROR 0x16 // Not used
14 | #define ADC_MEASURE_OK 0x17 // Not used
15 | #define PWM_CHANNEL_ERROR 0x18 // Not used
16 | #define PWM_ADJUST_OK 0x19 // Not used
17 | #define CRC_EOP 0x20 // 'SPACE'
18 | #define STK_GET_SYNC 0x30 // '0'
19 | #define STK_GET_SIGN_ON 0x31 // '1'
20 | #define STK_SET_PARAMETER 0x40 // '@'
21 | #define STK_GET_PARAMETER 0x41 // 'A'
22 | #define STK_SET_DEVICE 0x42 // 'B'
23 | #define STK_SET_DEVICE_EXT 0x45 // 'E'
24 | #define STK_ENTER_PROGMODE 0x50 // 'P'
25 | #define STK_LEAVE_PROGMODE 0x51 // 'Q'
26 | #define STK_CHIP_ERASE 0x52 // 'R'
27 | #define STK_CHECK_AUTOINC 0x53 // 'S'
28 | #define STK_LOAD_ADDRESS 0x55 // 'U'
29 | #define STK_UNIVERSAL 0x56 // 'V'
30 | #define STK_PROG_FLASH 0x60 // '`'
31 | #define STK_PROG_DATA 0x61 // 'a'
32 | #define STK_PROG_FUSE 0x62 // 'b'
33 | #define STK_PROG_LOCK 0x63 // 'c'
34 | #define STK_PROG_PAGE 0x64 // 'd'
35 | #define STK_PROG_FUSE_EXT 0x65 // 'e'
36 | #define STK_READ_FLASH 0x70 // 'p'
37 | #define STK_READ_DATA 0x71 // 'q'
38 | #define STK_READ_FUSE 0x72 // 'r'
39 | #define STK_READ_LOCK 0x73 // 's'
40 | #define STK_READ_PAGE 0x74 // 't'
41 | #define STK_READ_SIGN 0x75 // 'u'
42 | #define STK_READ_OSCCAL 0x76 // 'v'
43 | #define STK_READ_FUSE_EXT 0x77 // 'w'
44 | #define STK_READ_OSCCAL_EXT 0x78 // 'x'
45 |
--------------------------------------------------------------------------------
/src/libraries/SPI/DigitalPotControlviaSPI0/DigitalPotControlviaSPI0.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Digital Pot Control
3 |
4 | This example controls an Analog Devices AD5206 digital potentiometer.
5 | The AD5206 has 6 potentiometer channels. Each channel's pins are labeled
6 | A - connect this to voltage
7 | W - this is the pot's wiper, which changes when you set it
8 | B - connect this to ground.
9 |
10 | The AD5206 is SPI-compatible,and to command it, you send two bytes,
11 | one with the channel number (0 - 5) and one with the resistance value for the
12 | channel (0 - 255).
13 |
14 | The circuit:
15 | * All A pins of AD5206 connected to +5V
16 | * All B pins of AD5206 connected to ground
17 | * An LED and a 220-ohm resisor in series connected from each W pin to ground
18 | * CS - to digital pin 10 (SS pin)
19 | * SDI - to digital pin 11 (MOSI pin)
20 | * CLK - to digital pin 13 (SCK pin)
21 |
22 | created 10 Aug 2010
23 | by Tom Igoe
24 |
25 | Thanks to Heather Dewey-Hagborg for the original tutorial, 2005
26 |
27 | */
28 |
29 |
30 | // inslude the SPI library:
31 | #include
32 |
33 |
34 | // set pin 10 as the slave select for the digital pot:
35 | const int slaveSelectPin = 10;
36 |
37 | void setup() {
38 | // set the slaveSelectPin as an output:
39 | pinMode (slaveSelectPin, OUTPUT);
40 | // initialize SPI:
41 | SPI.begin();
42 | }
43 |
44 | void loop() {
45 | // go through the six channels of the digital pot:
46 | for (int channel = 0; channel < 6; channel++) {
47 | // change the resistance on this channel from min to max:
48 | for (int level = 0; level < 255; level++) {
49 | digitalPotWrite(channel, level);
50 | delay(10);
51 | }
52 | // wait a second at the top:
53 | delay(100);
54 | // change the resistance on this channel from max to min:
55 | for (int level = 0; level < 255; level++) {
56 | digitalPotWrite(channel, 255 - level);
57 | delay(10);
58 | }
59 | }
60 |
61 | }
62 |
63 | void digitalPotWrite(int address, int value) {
64 | // take the SS pin low to select the chip:
65 | digitalWrite(slaveSelectPin, LOW);
66 | // send in the address and value via SPI:
67 | SPI.transfer(address);
68 | SPI.transfer(value);
69 | // take the SS pin high to de-select the chip:
70 | digitalWrite(slaveSelectPin, HIGH);
71 | }
72 |
--------------------------------------------------------------------------------
/src/libraries/SPI/DigitalPotiControlviaSPI1/DigitalPotiControlviaSPI1.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Digital Pot Control
3 |
4 | This example controls an Analog Devices AD5206 digital potentiometer.
5 | The AD5206 has 6 potentiometer channels. Each channel's pins are labeled
6 | A - connect this to voltage
7 | W - this is the pot's wiper, which changes when you set it
8 | B - connect this to ground.
9 |
10 | The AD5206 is SPI-compatible,and to command it, you send two bytes,
11 | one with the channel number (0 - 5) and one with the resistance value for the
12 | channel (0 - 255).
13 |
14 | The circuit:
15 | * All A pins of AD5206 connected to +5V
16 | * All B pins of AD5206 connected to ground
17 | * An LED and a 220-ohm resisor in series connected from each W pin to ground
18 | * CS - to digital pin 10 (SS pin)
19 | * SDI - to digital pin 11 (MOSI pin)
20 | * CLK - to digital pin 13 (SCK pin)
21 |
22 | created 10 Aug 2010
23 | by Tom Igoe
24 |
25 | Changed for SPI1 on Atmega328PB by Andre Moehl, 2016
26 |
27 | Thanks to Heather Dewey-Hagborg for the original tutorial, 2005
28 |
29 | */
30 |
31 |
32 | // include the SPI library:
33 | #include
34 |
35 |
36 | // set pin 10 as the slave select for the digital pot:
37 | const int slaveSelectPin = 10;
38 |
39 | void setup() {
40 | // set the slaveSelectPin as an output:
41 | pinMode (slaveSelectPin, OUTPUT);
42 | // initialize SPI:
43 | SPI1.begin();
44 | }
45 |
46 | void loop() {
47 | // go through the six channels of the digital pot:
48 | for (int channel = 0; channel < 6; channel++) {
49 | // change the resistance on this channel from min to max:
50 | for (int level = 0; level < 255; level++) {
51 | digitalPotWrite(channel, level);
52 | delay(10);
53 | }
54 | // wait a second at the top:
55 | delay(100);
56 | // change the resistance on this channel from max to min:
57 | for (int level = 0; level < 255; level++) {
58 | digitalPotWrite(channel, 255 - level);
59 | delay(10);
60 | }
61 | }
62 |
63 | }
64 |
65 | void digitalPotWrite(int address, int value) {
66 | // take the SS pin low to select the chip:
67 | digitalWrite(slaveSelectPin, LOW);
68 | // send in the address and value via SPI:
69 | SPI1.transfer(address);
70 | SPI1.transfer(value);
71 | // take the SS pin high to de-select the chip:
72 | digitalWrite(slaveSelectPin, HIGH);
73 | }
74 |
--------------------------------------------------------------------------------
/src/libraries/SPI/SPI.cpp:
--------------------------------------------------------------------------------
1 | #include "SPI.h"
2 |
3 |
4 | /*
5 | * Copyright (c) 2010 by Cristian Maglie
6 | * Copyright (c) 2014 by Paul Stoffregen (Transaction API)
7 | * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR)
8 | * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes)
9 | * Copyright (c) 2014 by Andre Moehl andre@ib-moehl.de (SPI1 Class, for Atmega3258PB Support)
10 | * SPI Master library for arduino.
11 | *
12 | * This file is free software; you can redistribute it and/or modify
13 | * it under the terms of either the GNU General Public License version 2
14 | * or the GNU Lesser General Public License version 2.1, both as
15 | * published by the Free Software Foundation.
16 | */
17 |
18 | #include "SPI.h"
19 |
20 | SPIClass SPI;
21 | #if defined(__AVR_ATmega328PB__)
22 | SPI1Class SPI1;
23 | #endif
24 |
25 |
26 | uint8_t SPIClass::initialized = 0;
27 | uint8_t SPIClass::interruptMode = 0;
28 | uint8_t SPIClass::interruptMask = 0;
29 | uint8_t SPIClass::interruptSave = 0;
30 | #ifdef SPI_TRANSACTION_MISMATCH_LED
31 | uint8_t SPIClass::inTransactionFlag = 0;
32 | #endif
33 |
34 | void SPIClass::begin()
35 | {
36 | uint8_t sreg = SREG;
37 | noInterrupts(); // Protect from a scheduler and prevent transactionBegin
38 | if (!initialized) {
39 | // Set SS to high so a connected chip will be "deselected" by default
40 | uint8_t port = digitalPinToPort(SS);
41 | uint8_t bit = digitalPinToBitMask(SS);
42 | volatile uint8_t *reg = portModeRegister(port);
43 |
44 | // if the SS pin is not already configured as an output
45 | // then set it high (to enable the internal pull-up resistor)
46 | if(!(*reg & bit)){
47 | digitalWrite(SS, HIGH);
48 | }
49 |
50 | // When the SS pin is set as OUTPUT, it can be used as
51 | // a general purpose output port (it doesn't influence
52 | // SPI operations).
53 | pinMode(SS, OUTPUT);
54 |
55 | // Warning: if the SS pin ever becomes a LOW INPUT then SPI
56 | // automatically switches to Slave, so the data direction of
57 | // the SS pin MUST be kept as OUTPUT.
58 | #if defined(__AVR_ATmega328PB__)
59 | SPCR0 |= _BV(MSTR0);
60 | SPCR0 |= _BV(SPE0);
61 | #else
62 | SPCR |= _BV(MSTR);
63 | SPCR |= _BV(SPE);
64 | #endif
65 |
66 | // Set direction register for SCK and MOSI pin.
67 | // MISO pin automatically overrides to INPUT.
68 | // By doing this AFTER enabling SPI, we avoid accidentally
69 | // clocking in a single bit since the lines go directly
70 | // from "input" to SPI control.
71 | // http://code.google.com/p/arduino/issues/detail?id=888
72 | pinMode(SCK, OUTPUT);
73 | pinMode(MOSI, OUTPUT);
74 | }
75 | initialized++; // reference count
76 | SREG = sreg;
77 | }
78 |
79 | void SPIClass::end() {
80 | uint8_t sreg = SREG;
81 | noInterrupts(); // Protect from a scheduler and prevent transactionBegin
82 | // Decrease the reference counter
83 | if (initialized)
84 | initialized--;
85 | // If there are no more references disable SPI
86 | if (!initialized)
87 | {
88 | #if defined(__AVR_ATmega328PB__)
89 | SPCR0 &= ~_BV(SPE0);
90 | #else
91 | SPCR &= ~_BV(SPE);
92 | #endif
93 | interruptMode = 0;
94 | #ifdef SPI_TRANSACTION_MISMATCH_LED
95 | inTransactionFlag = 0;
96 | #endif
97 | }
98 | SREG = sreg;
99 | }
100 |
101 | // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
102 | #if defined(__AVR_ATmega32U4__)
103 | #define SPI_INT0_MASK (1<
3 | * Copyright (c) 2014 by Paul Stoffregen (Transaction API)
4 | * Copyright (c) 2014 by Matthijs Kooijman (SPISettings AVR)
5 | * Copyright (c) 2014 by Andrew J. Kroll (atomicity fixes)
6 | * Copyright (c) 2014 by Andre Moehl andre@ib-moehl.de (SPI1 Class, for Atmega3258PB Support)
7 | * SPI Master library for arduino.
8 | *
9 | * This file is free software; you can redistribute it and/or modify
10 | * it under the terms of either the GNU General Public License version 2
11 | * or the GNU Lesser General Public License version 2.1, both as
12 | * published by the Free Software Foundation.
13 | */
14 |
15 | #ifndef _SPI_H_INCLUDED
16 | #define _SPI_H_INCLUDED
17 |
18 |
19 |
20 | #include
21 | #include "SPIDef.h"
22 |
23 | #define SPI0 SPI //alias, so you can use SPI0.begin() instead of SPI
24 |
25 |
26 | class SPISettings {
27 | public:
28 | SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
29 | {
30 | if (__builtin_constant_p(clock))
31 | {
32 | init_AlwaysInline(clock, bitOrder, dataMode);
33 | } else
34 | {
35 | init_MightInline(clock, bitOrder, dataMode);
36 | }
37 | }
38 |
39 | SPISettings()
40 | {
41 | init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
42 | }
43 |
44 | private:
45 | void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
46 | {
47 | init_AlwaysInline(clock, bitOrder, dataMode);
48 | }
49 |
50 | void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) __attribute__((__always_inline__))
51 | {
52 | // Clock settings are defined as follows. Note that this shows SPI2X
53 | // inverted, so the bits form increasing numbers. Also note that
54 | // fosc/64 appears twice
55 | // SPR1 SPR0 ~SPI2X Freq
56 | // 0 0 0 fosc/2
57 | // 0 0 1 fosc/4
58 | // 0 1 0 fosc/8
59 | // 0 1 1 fosc/16
60 | // 1 0 0 fosc/32
61 | // 1 0 1 fosc/64
62 | // 1 1 0 fosc/64
63 | // 1 1 1 fosc/128
64 |
65 | // We find the fastest clock that is less than or equal to the
66 | // given clock rate. The clock divider that results in clock_setting
67 | // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
68 | // slowest (128 == 2 ^^ 7, so clock_div = 6).
69 | uint8_t clockDiv;
70 |
71 | // When the clock is known at compiletime, use this if-then-else
72 | // cascade, which the compiler knows how to completely optimize
73 | // away. When clock is not known, use a loop instead, which generates
74 | // shorter code.
75 | if (__builtin_constant_p(clock)) {
76 | if (clock >= F_CPU / 2) {
77 | clockDiv = 0;
78 | } else if (clock >= F_CPU / 4) {
79 | clockDiv = 1;
80 | } else if (clock >= F_CPU / 8) {
81 | clockDiv = 2;
82 | } else if (clock >= F_CPU / 16) {
83 | clockDiv = 3;
84 | } else if (clock >= F_CPU / 32) {
85 | clockDiv = 4;
86 | } else if (clock >= F_CPU / 64) {
87 | clockDiv = 5;
88 | } else {
89 | clockDiv = 6;
90 | }
91 | } else {
92 | uint32_t clockSetting = F_CPU / 2;
93 | clockDiv = 0;
94 | while (clockDiv < 6 && clock < clockSetting) {
95 | clockSetting /= 2;
96 | clockDiv++;
97 | }
98 | }
99 |
100 | // Compensate for the duplicate fosc/64
101 | if (clockDiv == 6)
102 | clockDiv = 7;
103 |
104 | // Invert the SPI2X bit
105 | clockDiv ^= 0x1;
106 |
107 | // Pack into the SPISettings class
108 | #if defined(__AVR_ATmega328PB__)
109 | spcr = _BV(SPE0) | _BV(MSTR0) | ((bitOrder == LSBFIRST) ? _BV(DORD0) : 0) |
110 | (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
111 | #else
112 | spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
113 | (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
114 | spsr = clockDiv & SPI_2XCLOCK_MASK;
115 | #endif
116 | }
117 | uint8_t spcr;
118 | uint8_t spsr;
119 | friend class SPIClass;
120 | };
121 |
122 |
123 |
124 | class SPIClass
125 | {
126 | public:
127 | // Initialize the SPI library
128 | static void begin();
129 |
130 | // If SPI is used from within an interrupt, this function registers
131 | // that interrupt with the SPI library, so beginTransaction() can
132 | // prevent conflicts. The input interruptNumber is the number used
133 | // with attachInterrupt. If SPI is used from a different interrupt
134 | // (eg, a timer), interruptNumber should be 255.
135 | static void usingInterrupt(uint8_t interruptNumber);
136 | // And this does the opposite.
137 | static void notUsingInterrupt(uint8_t interruptNumber);
138 | // Note: the usingInterrupt and notUsingInterrupt functions should
139 | // not to be called from ISR context or inside a transaction.
140 | // For details see:
141 | // https://github.com/arduino/Arduino/pull/2381
142 | // https://github.com/arduino/Arduino/pull/2449
143 |
144 | // Before using SPI.transfer() or asserting chip select pins,
145 | // this function is used to gain exclusive access to the SPI bus
146 | // and configure the correct settings.
147 | inline static void beginTransaction(SPISettings settings) {
148 | if (interruptMode > 0) {
149 | uint8_t sreg = SREG;
150 | noInterrupts();
151 |
152 | #ifdef SPI_AVR_EIMSK
153 | if (interruptMode == 1) {
154 | interruptSave = SPI_AVR_EIMSK;
155 | SPI_AVR_EIMSK &= ~interruptMask;
156 | SREG = sreg;
157 | } else
158 | #endif
159 | {
160 | interruptSave = sreg;
161 | }
162 | }
163 |
164 | #ifdef SPI_TRANSACTION_MISMATCH_LED
165 | if (inTransactionFlag) {
166 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
167 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
168 | }
169 | inTransactionFlag = 1;
170 | #endif
171 |
172 | #if defined(__AVR_ATmega328PB__)
173 | SPCR0 = settings.spcr;
174 | #else
175 | SPSR = settings.spsr;
176 | #endif
177 | }
178 |
179 | // Write to the SPI bus (MOSI pin) and also receive (MISO pin)
180 | inline static uint8_t transfer(uint8_t data) {
181 | #if defined(__AVR_ATmega328PB__)
182 | SPDR0 = data;
183 | #else
184 | SPDR = data;
185 | #endif
186 | /*
187 | * The following NOP introduces a small delay that can prevent the wait
188 | * loop form iterating when running at the maximum speed. This gives
189 | * about 10% more speed, even if it seems counter-intuitive. At lower
190 | * speeds it is unnoticed.
191 | */
192 | asm volatile("nop");
193 | #if defined(__AVR_ATmega328PB__)
194 | while (!(SPSR0 & _BV(SPIF0))) ; // wait
195 | return SPDR0;
196 | #else
197 | while (!(SPSR & _BV(SPIF))) ; // wait
198 | return SPDR;
199 | #endif
200 | }
201 | inline static uint16_t transfer16(uint16_t data) {
202 | union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
203 | in.val = data;
204 | #if defined(__AVR_ATmega328PB__)
205 | if (!(SPCR0 & _BV(DORD0))) {
206 | SPDR0 = in.msb;
207 | asm volatile("nop"); // See transfer(uint8_t) function
208 | while (!(SPSR0 & _BV(SPIF0))) ;
209 | out.msb = SPDR0;
210 | SPDR0 = in.lsb;
211 | asm volatile("nop");
212 | while (!(SPSR0 & _BV(SPIF0))) ;
213 | out.lsb = SPDR0;
214 | } else {
215 | SPDR0 = in.lsb;
216 | asm volatile("nop");
217 | while (!(SPSR0 & _BV(SPIF0))) ;
218 | out.lsb = SPDR0;
219 | SPDR0 = in.msb;
220 | asm volatile("nop");
221 | while (!(SPSR0 & _BV(SPIF0))) ;
222 | out.msb = SPDR0;
223 | }
224 | #else
225 | if (!(SPCR & _BV(DORD))) {
226 | SPDR = in.msb;
227 | asm volatile("nop"); // See transfer(uint8_t) function
228 | while (!(SPSR & _BV(SPIF))) ;
229 | out.msb = SPDR;
230 | SPDR = in.lsb;
231 | asm volatile("nop");
232 | while (!(SPSR & _BV(SPIF))) ;
233 | out.lsb = SPDR;
234 | } else {
235 | SPDR = in.lsb;
236 | asm volatile("nop");
237 | while (!(SPSR & _BV(SPIF))) ;
238 | out.lsb = SPDR;
239 | SPDR = in.msb;
240 | asm volatile("nop");
241 | while (!(SPSR & _BV(SPIF))) ;
242 | out.msb = SPDR;
243 | }
244 | #endif
245 | return out.val;
246 | }
247 | inline static void transfer(void *buf, size_t count) {
248 | if (count == 0) return;
249 | uint8_t *p = (uint8_t *)buf;
250 | #if defined(__AVR_ATmega328PB__)
251 | SPDR0 = *p;
252 | while (--count > 0) {
253 | uint8_t out = *(p + 1);
254 | while (!(SPSR0 & _BV(SPIF0))) ;
255 | uint8_t in = SPDR0;
256 | SPDR0 = out;
257 | *p++ = in;
258 | }
259 | while (!(SPSR0 & _BV(SPIF0))) ;
260 | *p = SPDR0;
261 |
262 | #else
263 | SPDR = *p;
264 | while (--count > 0) {
265 | uint8_t out = *(p + 1);
266 | while (!(SPSR & _BV(SPIF))) ;
267 | uint8_t in = SPDR;
268 | SPDR = out;
269 | *p++ = in;
270 | }
271 | while (!(SPSR & _BV(SPIF))) ;
272 | *p = SPDR;
273 | #endif
274 | }
275 | // After performing a group of transfers and releasing the chip select
276 | // signal, this function allows others to access the SPI bus
277 | inline static void endTransaction(void) {
278 | #ifdef SPI_TRANSACTION_MISMATCH_LED
279 | if (!inTransactionFlag) {
280 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
281 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
282 | }
283 | inTransactionFlag = 0;
284 | #endif
285 |
286 | if (interruptMode > 0) {
287 | #ifdef SPI_AVR_EIMSK
288 | uint8_t sreg = SREG;
289 | #endif
290 | noInterrupts();
291 | #ifdef SPI_AVR_EIMSK
292 | if (interruptMode == 1) {
293 | SPI_AVR_EIMSK = interruptSave;
294 | SREG = sreg;
295 | } else
296 | #endif
297 | {
298 | SREG = interruptSave;
299 | }
300 | }
301 | }
302 |
303 | // Disable the SPI bus
304 | static void end();
305 |
306 | // This function is deprecated. New applications should use
307 | // beginTransaction() to configure SPI settings.
308 | inline static void setBitOrder(uint8_t bitOrder)
309 | {
310 | #if defined(__AVR_ATmega328PB__)
311 | if (bitOrder == LSBFIRST) SPCR0 |= _BV(DORD0);
312 | else SPCR0 &= ~(_BV(DORD0));
313 | #else
314 | if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);
315 | else SPCR &= ~(_BV(DORD));
316 | #endif
317 | }
318 | // This function is deprecated. New applications should use
319 | // beginTransaction() to configure SPI settings.
320 | inline static void setDataMode(uint8_t dataMode)
321 | {
322 | #if !defined(__AVR_ATmega328PB__)
323 | SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
324 | #endif
325 | }
326 | // This function is deprecated. New applications should use
327 | // beginTransaction() to configure SPI settings.
328 | inline static void setClockDivider(uint8_t clockDiv)
329 | {
330 | #if !defined(__AVR_ATmega328PB__)
331 | SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
332 | SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
333 | #endif
334 | }
335 | // These undocumented functions should not be used. SPI.transfer()
336 | // polls the hardware flag which is automatically cleared as the
337 | // AVR responds to SPI's interrupt
338 | #if defined(__AVR_ATmega328PB__)
339 | inline static void attachInterrupt() { SPCR0 |= _BV(SPIE0 ); }
340 | inline static void detachInterrupt() { SPCR0 &= ~_BV(SPIE0); }
341 | #else
342 | inline static void attachInterrupt() { SPCR |= _BV(SPIE); }
343 | inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
344 | #endif
345 |
346 | private:
347 | static uint8_t initialized;
348 | static uint8_t interruptMode; // 0=none, 1=mask, 2=global
349 | static uint8_t interruptMask; // which interrupts to mask
350 | static uint8_t interruptSave; // temp storage, to restore state
351 | #ifdef SPI_TRANSACTION_MISMATCH_LED
352 | static uint8_t inTransactionFlag;
353 | #endif
354 | };
355 |
356 |
357 |
358 |
359 | /* SPI 1 Class *****************************************************/
360 | #if defined(__AVR_ATmega328PB__)
361 | class SPI1Settings {
362 | public:
363 | SPI1Settings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
364 | {
365 | if (__builtin_constant_p(clock))
366 | {
367 | init_AlwaysInline(clock, bitOrder, dataMode);
368 | } else
369 | {
370 | init_MightInline(clock, bitOrder, dataMode);
371 | }
372 | }
373 |
374 | SPI1Settings()
375 | {
376 | init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
377 | }
378 |
379 | private:
380 | void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
381 | {
382 | init_AlwaysInline(clock, bitOrder, dataMode);
383 | }
384 |
385 | void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) __attribute__((__always_inline__))
386 | {
387 | // Clock settings are defined as follows. Note that this shows SPI2X
388 | // inverted, so the bits form increasing numbers. Also note that
389 | // fosc/64 appears twice
390 | // SPR1 SPR0 ~SPI2X Freq
391 | // 0 0 0 fosc/2
392 | // 0 0 1 fosc/4
393 | // 0 1 0 fosc/8
394 | // 0 1 1 fosc/16
395 | // 1 0 0 fosc/32
396 | // 1 0 1 fosc/64
397 | // 1 1 0 fosc/64
398 | // 1 1 1 fosc/128
399 |
400 | // We find the fastest clock that is less than or equal to the
401 | // given clock rate. The clock divider that results in clock_setting
402 | // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
403 | // slowest (128 == 2 ^^ 7, so clock_div = 6).
404 | uint8_t clockDiv;
405 |
406 | // When the clock is known at compiletime, use this if-then-else
407 | // cascade, which the compiler knows how to completely optimize
408 | // away. When clock is not known, use a loop instead, which generates
409 | // shorter code.
410 | if (__builtin_constant_p(clock)) {
411 | if (clock >= F_CPU / 2) {
412 | clockDiv = 0;
413 | } else if (clock >= F_CPU / 4) {
414 | clockDiv = 1;
415 | } else if (clock >= F_CPU / 8) {
416 | clockDiv = 2;
417 | } else if (clock >= F_CPU / 16) {
418 | clockDiv = 3;
419 | } else if (clock >= F_CPU / 32) {
420 | clockDiv = 4;
421 | } else if (clock >= F_CPU / 64) {
422 | clockDiv = 5;
423 | } else {
424 | clockDiv = 6;
425 | }
426 | } else {
427 | uint32_t clockSetting = F_CPU / 2;
428 | clockDiv = 0;
429 | while (clockDiv < 6 && clock < clockSetting) {
430 | clockSetting /= 2;
431 | clockDiv++;
432 | }
433 | }
434 |
435 | // Compensate for the duplicate fosc/64
436 | if (clockDiv == 6)
437 | clockDiv = 7;
438 |
439 | // Invert the SPI2X bit
440 | clockDiv ^= 0x1;
441 |
442 | // Pack into the SPI1Settings class
443 | //#if defined(__AVR_ATmega328PB__)
444 | spcr = _BV(SPE1) | _BV(MSTR1) | ((bitOrder == LSBFIRST) ? _BV(DORD1) : 0) |
445 | (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
446 | //#endif
447 | }
448 | uint8_t spcr;
449 | uint8_t spsr;
450 | friend class SPI1Class;
451 | };
452 |
453 |
454 |
455 | class SPI1Class
456 | {
457 | public:
458 | // Initialize the SPI library
459 | static void begin();
460 |
461 | // If SPI is used from within an interrupt, this function registers
462 | // that interrupt with the SPI library, so beginTransaction() can
463 | // prevent conflicts. The input interruptNumber is the number used
464 | // with attachInterrupt. If SPI is used from a different interrupt
465 | // (eg, a timer), interruptNumber should be 255.
466 | static void usingInterrupt(uint8_t interruptNumber);
467 | // And this does the opposite.
468 | static void notUsingInterrupt(uint8_t interruptNumber);
469 | // Note: the usingInterrupt and notUsingInterrupt functions should
470 | // not to be called from ISR context or inside a transaction.
471 | // For details see:
472 | // https://github.com/arduino/Arduino/pull/2381
473 | // https://github.com/arduino/Arduino/pull/2449
474 |
475 | // Before using SPI.transfer() or asserting chip select pins,
476 | // this function is used to gain exclusive access to the SPI bus
477 | // and configure the correct settings.
478 | inline static void beginTransaction(SPI1Settings settings) {
479 | if (interruptMode > 0) {
480 | uint8_t sreg = SREG;
481 | noInterrupts();
482 |
483 | #ifdef SPI_AVR_EIMSK
484 | if (interruptMode == 1) {
485 | interruptSave = SPI_AVR_EIMSK;
486 | SPI_AVR_EIMSK &= ~interruptMask;
487 | SREG = sreg;
488 | } else
489 | #endif
490 | {
491 | interruptSave = sreg;
492 | }
493 | }
494 |
495 | #ifdef SPI_TRANSACTION_MISMATCH_LED
496 | if (inTransactionFlag) {
497 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
498 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
499 | }
500 | inTransactionFlag = 1;
501 | #endif
502 |
503 | //#if defined(__AVR_ATmega328PB__)
504 | SPCR1 = settings.spcr;
505 | //#endif
506 | }
507 |
508 | // Write to the SPI bus (MOSI pin) and also receive (MISO pin)
509 | inline static uint8_t transfer(uint8_t data) {
510 | #if defined(__AVR_ATmega328PB__)
511 | SPDR1 = data;
512 | #endif
513 | /*
514 | * The following NOP introduces a small delay that can prevent the wait
515 | * loop form iterating when running at the maximum speed. This gives
516 | * about 10% more speed, even if it seems counter-intuitive. At lower
517 | * speeds it is unnoticed.
518 | */
519 | asm volatile("nop");
520 | //#if defined(__AVR_ATmega328PB__)
521 | while (!(SPSR1 & _BV(SPIF1))) ; // wait
522 | return SPDR1;
523 | //#endif
524 | }
525 |
526 | inline static uint16_t transfer16(uint16_t data)
527 | {
528 | union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
529 | in.val = data;
530 | //#if defined(__AVR_ATmega328PB__)
531 | if (!(SPCR1 & _BV(DORD1))) {
532 | SPDR1 = in.msb;
533 | asm volatile("nop"); // See transfer(uint8_t) function
534 | while (!(SPSR1 & _BV(SPIF1))) ;
535 | out.msb = SPDR1;
536 | SPDR1 = in.lsb;
537 | asm volatile("nop");
538 | while (!(SPSR1 & _BV(SPIF1))) ;
539 | out.lsb = SPDR1;
540 | } else {
541 | SPDR1 = in.lsb;
542 | asm volatile("nop");
543 | while (!(SPSR1 & _BV(SPIF1))) ;
544 | out.lsb = SPDR1;
545 | SPDR1 = in.msb;
546 | asm volatile("nop");
547 | while (!(SPSR1 & _BV(SPIF1))) ;
548 | out.msb = SPDR1;
549 | }
550 | //#endif
551 | return out.val;
552 | }
553 |
554 | inline static void transfer(void *buf, size_t count)
555 | {
556 | if (count == 0) return;
557 | uint8_t *p = (uint8_t *)buf;
558 | //#if defined(__AVR_ATmega328PB__)
559 | SPDR1 = *p;
560 | while (--count > 0) {
561 | uint8_t out = *(p + 1);
562 | while (!(SPSR1 & _BV(SPIF1))) ;
563 | uint8_t in = SPDR1;
564 | SPDR1 = out;
565 | *p++ = in;
566 | }
567 | while (!(SPSR1 & _BV(SPIF1))) ;
568 | *p = SPDR1;
569 |
570 | //#endif
571 | }
572 |
573 | // After performing a group of transfers and releasing the chip select
574 | // signal, this function allows others to access the SPI bus
575 | inline static void endTransaction(void)
576 | {
577 | #ifdef SPI_TRANSACTION_MISMATCH_LED
578 | if (!inTransactionFlag) {
579 | pinMode(SPI_TRANSACTION_MISMATCH_LED, OUTPUT);
580 | digitalWrite(SPI_TRANSACTION_MISMATCH_LED, HIGH);
581 | }
582 | inTransactionFlag = 0;
583 | #endif
584 |
585 | if (interruptMode > 0) {
586 | #ifdef SPI_AVR_EIMSK
587 | uint8_t sreg = SREG;
588 | #endif
589 | noInterrupts();
590 | #ifdef SPI_AVR_EIMSK
591 | if (interruptMode == 1) {
592 | SPI_AVR_EIMSK = interruptSave;
593 | SREG = sreg;
594 | } else
595 | #endif
596 | {
597 | SREG = interruptSave;
598 | }
599 | }
600 | }
601 |
602 | // Disable the SPI bus
603 | static void end();
604 |
605 | // This function is deprecated. New applications should use
606 | // beginTransaction() to configure SPI settings.
607 | inline static void setBitOrder(uint8_t bitOrder)
608 | {
609 | //#if defined(__AVR_ATmega328PB__)
610 | if (bitOrder == LSBFIRST) SPCR1 |= _BV(DORD1);
611 | else SPCR1 &= ~(_BV(DORD1));
612 | //#endif
613 | }
614 |
615 |
616 | // These undocumented functions should not be used. SPI.transfer()
617 | // polls the hardware flag which is automatically cleared as the
618 | // AVR responds to SPI's interrupt
619 | //#if defined(__AVR_ATmega328PB__)
620 | inline static void attachInterrupt() { SPCR1 |= _BV(SPIE1 ); }
621 | inline static void detachInterrupt() { SPCR1 &= ~_BV(SPIE1); }
622 | //#endif
623 |
624 | private:
625 | static uint8_t initialized;
626 | static uint8_t interruptMode; // 0=none, 1=mask, 2=global
627 | static uint8_t interruptMask; // which interrupts to mask
628 | static uint8_t interruptSave; // temp storage, to restore state
629 | #ifdef SPI_TRANSACTION_MISMATCH_LED
630 | static uint8_t inTransactionFlag;
631 | #endif
632 | };
633 |
634 |
635 | #endif
636 |
637 |
638 |
639 |
640 | extern SPIClass SPI;
641 | #if defined(__AVR_ATmega328PB__)
642 | extern SPI1Class SPI1;
643 | #endif
644 |
645 |
646 |
647 | #endif
648 |
--------------------------------------------------------------------------------
/src/libraries/SPI/SPIDef.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _SPIDEF_H
3 | #define _SPIDEF_H
4 |
5 | // SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
6 | // usingInterrupt(), and SPISetting(clock, bitOrder, dataMode)
7 | #define SPI_HAS_TRANSACTION 1
8 |
9 | // SPI_HAS_NOTUSINGINTERRUPT means that SPI has notUsingInterrupt() method
10 | #define SPI_HAS_NOTUSINGINTERRUPT 1
11 |
12 | // SPI_ATOMIC_VERSION means that SPI has atomicity fixes and what version.
13 | // This way when there is a bug fix you can check this define to alert users
14 | // of your code if it uses better version of this library.
15 | // This also implies everything that SPI_HAS_TRANSACTION as documented above is
16 | // available too.
17 | #define SPI_ATOMIC_VERSION 1
18 |
19 | // Uncomment this line to add detection of mismatched begin/end transactions.
20 | // A mismatch occurs if other libraries fail to use SPI.endTransaction() for
21 | // each SPI.beginTransaction(). Connect an LED to this pin. The LED will turn
22 | // on if any mismatch is ever detected.
23 | //#define SPI_TRANSACTION_MISMATCH_LED 5
24 |
25 | #ifndef LSBFIRST
26 | #define LSBFIRST 0
27 | #endif
28 | #ifndef MSBFIRST
29 | #define MSBFIRST 1
30 | #endif
31 |
32 | #define SPI_CLOCK_DIV4 0x00
33 | #define SPI_CLOCK_DIV16 0x01
34 | #define SPI_CLOCK_DIV64 0x02
35 | #define SPI_CLOCK_DIV128 0x03
36 | #define SPI_CLOCK_DIV2 0x04
37 | #define SPI_CLOCK_DIV8 0x05
38 | #define SPI_CLOCK_DIV32 0x06
39 |
40 | #define SPI_MODE0 0x00
41 | #define SPI_MODE1 0x04
42 | #define SPI_MODE2 0x08
43 | #define SPI_MODE3 0x0C
44 |
45 | #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
46 | #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
47 | #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
48 |
49 | // define SPI_AVR_EIMSK for AVR boards with external interrupt pins
50 | #if defined(EIMSK)
51 | #define SPI_AVR_EIMSK EIMSK
52 | #elif defined(GICR)
53 | #define SPI_AVR_EIMSK GICR
54 | #elif defined(GIMSK)
55 | #define SPI_AVR_EIMSK GIMSK
56 | #endif
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/src/libraries/SPI/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map SPI
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | SPI KEYWORD1
10 | SPI1 KEYWORD1
11 | SPI0 KEYWORD1
12 |
13 | #######################################
14 | # Methods and Functions (KEYWORD2)
15 | #######################################
16 | begin KEYWORD2
17 | end KEYWORD2
18 | transfer KEYWORD2
19 | setBitOrder KEYWORD2
20 | setDataMode KEYWORD2
21 | setClockDivider KEYWORD2
22 |
23 |
24 | #######################################
25 | # Constants (LITERAL1)
26 | #######################################
27 | SPI_CLOCK_DIV4 LITERAL1
28 | SPI_CLOCK_DIV16 LITERAL1
29 | SPI_CLOCK_DIV64 LITERAL1
30 | SPI_CLOCK_DIV128 LITERAL1
31 | SPI_CLOCK_DIV2 LITERAL1
32 | SPI_CLOCK_DIV8 LITERAL1
33 | SPI_CLOCK_DIV32 LITERAL1
34 | SPI_CLOCK_DIV64 LITERAL1
35 | SPI_MODE0 LITERAL1
36 | SPI_MODE1 LITERAL1
37 | SPI_MODE2 LITERAL1
38 | SPI_MODE3 LITERAL1
39 |
--------------------------------------------------------------------------------
/src/libraries/SPI/library.properties:
--------------------------------------------------------------------------------
1 | name=SPI
2 | version=1.2
3 | author=Arduino
4 | maintainer=Arduino
5 | sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. For all Arduino boards, BUT Arduino DUE.
6 | paragraph=
7 | category=Communication
8 | url=http://www.arduino.cc/en/Reference/SPI
9 | architectures=avr
10 |
11 |
--------------------------------------------------------------------------------
/src/platform.txt:
--------------------------------------------------------------------------------
1 |
2 | # Arduino AVR Core and platform.
3 | # ------------------------------
4 | #
5 | # For more info:
6 | # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification
7 |
8 | name=Atmega328PB Boards
9 | version=1.0.0
10 |
11 | # AVR compile variables
12 | # ---------------------
13 |
14 | compiler.warning_flags=-w
15 | compiler.warning_flags.none=-w
16 | compiler.warning_flags.default=
17 | compiler.warning_flags.more=-Wall
18 | compiler.warning_flags.all=-Wall -Wextra
19 |
20 | # Default "compiler.path" is correct, change only if you want to override the initial value
21 | compiler.path={runtime.tools.avr-gcc.path}/bin/
22 | compiler.c.cmd=avr-gcc
23 | compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects
24 | compiler.c.elf.flags={compiler.warning_flags} -Os -flto -fuse-linker-plugin -Wl,--gc-sections
25 | compiler.c.elf.cmd=avr-gcc
26 | compiler.S.flags=-c -g -x assembler-with-cpp -flto
27 | compiler.cpp.cmd=avr-g++
28 | compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -flto
29 | compiler.ar.cmd=avr-gcc-ar
30 | compiler.ar.flags=rcs
31 | compiler.objcopy.cmd=avr-objcopy
32 | compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
33 | compiler.elf2hex.flags=-O ihex -R .eeprom
34 | compiler.elf2hex.cmd=avr-objcopy
35 | compiler.ldflags=
36 | compiler.size.cmd=avr-size
37 |
38 | # This can be overridden in boards.txt
39 | #include the iom328pb.h via redefining D__AVR_DEV_LIB_NAME__, cause io.h doesn't know about atmega328pb
40 | build.extra_flags= "-I{runtime.platform.path}/tools/include" -D__AVR_DEV_LIB_NAME__=m328pb
41 |
42 | # These can be overridden in platform.local.txt
43 | compiler.c.extra_flags=
44 | compiler.c.elf.extra_flags=
45 | compiler.S.extra_flags=
46 | compiler.cpp.extra_flags=
47 | compiler.ar.extra_flags=
48 | compiler.objcopy.eep.extra_flags=
49 | compiler.elf2hex.extra_flags=
50 |
51 | # AVR compile patterns
52 | # --------------------
53 |
54 | ## Compile c files
55 | recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
56 |
57 | ## Compile c++ files
58 | recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
59 |
60 | ## Compile S files
61 | recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"
62 |
63 | ## Create archives
64 | # archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
65 | archive_file_path={build.path}/{archive_file}
66 | recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"
67 |
68 | ## Combine gc-sections, archives, and objects
69 | recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
70 |
71 | ## Create output files (.eep and .hex)
72 | recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep"
73 | recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"
74 |
75 | ## Save hex
76 | recipe.output.tmp_file={build.project_name}.hex
77 | recipe.output.save_file={build.project_name}.{build.variant}.hex
78 |
79 | ## Compute size
80 | recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
81 | recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).*
82 | recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).*
83 | recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*
84 |
85 |
86 | # Copy the startup and c runtime libs to the right folder / thx to elector
87 | recipe.hooks.linking.prelink.1.pattern="{compiler.path}{compiler.objcopy.cmd}" "{runtime.platform.path}/tools/lib/crtatmega328pb.o" "{runtime.tools.avr-gcc.path}/avr/lib/avr5/crtatmega328pb.o"
88 | recipe.hooks.linking.prelink.2.pattern="{compiler.path}{compiler.objcopy.cmd}" "{runtime.platform.path}/tools/lib/crtatmega328pb.o" "{runtime.tools.avr-gcc.path}/avr/lib/avr5/crtm328pb.o"
89 | recipe.hooks.linking.prelink.3.pattern="{compiler.path}{compiler.objcopy.cmd}" "{runtime.platform.path}/tools/lib/libatmega328pb.a" "{runtime.tools.avr-gcc.path}/avr/lib/avr5/libatmega328pb.a"
90 |
91 |
92 | ## Preprocessor
93 | preproc.includes.flags=-w -x c++ -M -MG -MP
94 | recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}"
95 |
96 | preproc.macros.flags=-w -x c++ -E -CC
97 | recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} {preproc.macros.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{preprocessed_file_path}"
98 |
99 | # AVR Uploader/Programmers tools
100 | # ------------------------------
101 |
102 | tools.avrdude.path={runtime.tools.avrdude.path}
103 | tools.avrdude.cmd.path={path}/bin/avrdude
104 | #tools.avrdude.config.path={path}/etc/avrdude.conf
105 | tools.avrdude.config.path={runtime.platform.path}/tools/etc/avrdude.conf
106 |
107 | tools.avrdude.upload.params.verbose=-v
108 | tools.avrdude.upload.params.quiet=-q -q
109 | # tools.avrdude.upload.verify is needed for backwards compatibility with IDE 1.6.8 or older, IDE 1.6.9 or newer overrides this value
110 | tools.avrdude.upload.verify=
111 | tools.avrdude.upload.params.noverify=-V
112 | tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} {upload.verify} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
113 |
114 | tools.avrdude.program.params.verbose=-v
115 | tools.avrdude.program.params.quiet=-q -q
116 | # tools.avrdude.program.verify is needed for backwards compatibility with IDE 1.6.8 or older, IDE 1.6.9 or newer overrides this value
117 | tools.avrdude.program.verify=
118 | tools.avrdude.program.params.noverify=-V
119 | tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i"
120 |
121 | tools.avrdude.erase.params.verbose=-v
122 | tools.avrdude.erase.params.quiet=-q -q
123 | tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Ulock:w:{bootloader.unlock_bits}:m -Uefuse:w:{bootloader.extended_fuses}:m -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m
124 |
125 | tools.avrdude.bootloader.params.verbose=-v
126 | tools.avrdude.bootloader.params.quiet=-q -q
127 | tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" -Ulock:w:{bootloader.lock_bits}:m
128 |
129 | tools.avrdude_remote.upload.pattern=/usr/bin/run-avrdude /tmp/sketch.hex {upload.verbose} -p{build.mcu}
130 |
131 | # USB Default Flags
132 | # Default blank usb manufacturer will be filled in at compile time
133 | # - from numeric vendor ID, set to Unknown otherwise
134 | build.usb_manufacturer="Unknown"
135 | build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'
136 |
--------------------------------------------------------------------------------
/src/tools/include/avr/iom328pb.h:
--------------------------------------------------------------------------------
1 | /*****************************************************************************
2 | *
3 | * Copyright (C) 2015 Atmel Corporation
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | *
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in
14 | * the documentation and/or other materials provided with the
15 | * distribution.
16 | *
17 | * * Neither the name of the copyright holders nor the names of
18 | * contributors may be used to endorse or promote products derived
19 | * from this software without specific prior written permission.
20 | *
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 | * POSSIBILITY OF SUCH DAMAGE.
32 | ****************************************************************************/
33 |
34 |
35 | #ifndef _AVR_ATMEGA328PB_H_INCLUDED
36 | #define _AVR_ATMEGA328PB_H_INCLUDED
37 |
38 |
39 | #ifndef _AVR_IO_H_
40 | # error "Include instead of this file."
41 | #endif
42 |
43 | #ifndef _AVR_IOXXX_H_
44 | # define _AVR_IOXXX_H_ "iom328pb.h"
45 | #else
46 | # error "Attempt to include more than one file."
47 | #endif
48 |
49 | /* Registers and associated bit numbers */
50 |
51 | #define PINB _SFR_IO8(0x03)
52 | #define PINB7 7
53 | #define PINB6 6
54 | #define PINB5 5
55 | #define PINB4 4
56 | #define PINB3 3
57 | #define PINB2 2
58 | #define PINB1 1
59 | #define PINB0 0
60 |
61 | #define DDRB _SFR_IO8(0x04)
62 | #define DDRB7 7
63 | // Inserted "DDB7" from "DDRB7" due to compatibility
64 | #define DDB7 7
65 | #define DDRB6 6
66 | // Inserted "DDB6" from "DDRB6" due to compatibility
67 | #define DDB6 6
68 | #define DDRB5 5
69 | // Inserted "DDB5" from "DDRB5" due to compatibility
70 | #define DDB5 5
71 | #define DDRB4 4
72 | // Inserted "DDB4" from "DDRB4" due to compatibility
73 | #define DDB4 4
74 | #define DDRB3 3
75 | // Inserted "DDB3" from "DDRB3" due to compatibility
76 | #define DDB3 3
77 | #define DDRB2 2
78 | // Inserted "DDB2" from "DDRB2" due to compatibility
79 | #define DDB2 2
80 | #define DDRB1 1
81 | // Inserted "DDB1" from "DDRB1" due to compatibility
82 | #define DDB1 1
83 | #define DDRB0 0
84 | // Inserted "DDB0" from "DDRB0" due to compatibility
85 | #define DDB0 0
86 |
87 | #define PORTB _SFR_IO8(0x05)
88 | #define PORTB7 7
89 | #define PORTB6 6
90 | #define PORTB5 5
91 | #define PORTB4 4
92 | #define PORTB3 3
93 | #define PORTB2 2
94 | #define PORTB1 1
95 | #define PORTB0 0
96 |
97 | #define PINC _SFR_IO8(0x06)
98 | #define PINC6 6
99 | #define PINC5 5
100 | #define PINC4 4
101 | #define PINC3 3
102 | #define PINC2 2
103 | #define PINC1 1
104 | #define PINC0 0
105 |
106 | #define DDRC _SFR_IO8(0x07)
107 | #define DDRC6 6
108 | // Inserted "DDC6" from "DDRC6" due to compatibility
109 | #define DDC6 6
110 | #define DDRC5 5
111 | // Inserted "DDC5" from "DDRC5" due to compatibility
112 | #define DDC5 5
113 | #define DDRC4 4
114 | // Inserted "DDC4" from "DDRC4" due to compatibility
115 | #define DDC4 4
116 | #define DDRC3 3
117 | // Inserted "DDC3" from "DDRC3" due to compatibility
118 | #define DDC3 3
119 | #define DDRC2 2
120 | // Inserted "DDC2" from "DDRC2" due to compatibility
121 | #define DDC2 2
122 | #define DDRC1 1
123 | // Inserted "DDC1" from "DDRC1" due to compatibility
124 | #define DDC1 1
125 | #define DDRC0 0
126 | // Inserted "DDC0" from "DDRC0" due to compatibility
127 | #define DDC0 0
128 |
129 | #define PORTC _SFR_IO8(0x08)
130 | #define PORTC6 6
131 | #define PORTC5 5
132 | #define PORTC4 4
133 | #define PORTC3 3
134 | #define PORTC2 2
135 | #define PORTC1 1
136 | #define PORTC0 0
137 |
138 | #define PIND _SFR_IO8(0x09)
139 | #define PIND7 7
140 | #define PIND6 6
141 | #define PIND5 5
142 | #define PIND4 4
143 | #define PIND3 3
144 | #define PIND2 2
145 | #define PIND1 1
146 | #define PIND0 0
147 |
148 | #define DDRD _SFR_IO8(0x0A)
149 | #define DDRD7 7
150 | // Inserted "DDD7" from "DDRD7" due to compatibility
151 | #define DDD7 7
152 | #define DDRD6 6
153 | // Inserted "DDD6" from "DDRD6" due to compatibility
154 | #define DDD6 6
155 | #define DDRD5 5
156 | // Inserted "DDD5" from "DDRD5" due to compatibility
157 | #define DDD5 5
158 | #define DDRD4 4
159 | // Inserted "DDD4" from "DDRD4" due to compatibility
160 | #define DDD4 4
161 | #define DDRD3 3
162 | // Inserted "DDD3" from "DDRD3" due to compatibility
163 | #define DDD3 3
164 | #define DDRD2 2
165 | // Inserted "DDD2" from "DDRD2" due to compatibility
166 | #define DDD2 2
167 | #define DDRD1 1
168 | // Inserted "DDD1" from "DDRD1" due to compatibility
169 | #define DDD1 1
170 | #define DDRD0 0
171 | // Inserted "DDD0" from "DDRD0" due to compatibility
172 | #define DDD0 0
173 |
174 | #define PORTD _SFR_IO8(0x0B)
175 | #define PORTD7 7
176 | #define PORTD6 6
177 | #define PORTD5 5
178 | #define PORTD4 4
179 | #define PORTD3 3
180 | #define PORTD2 2
181 | #define PORTD1 1
182 | #define PORTD0 0
183 |
184 | #define PINE _SFR_IO8(0x0C)
185 | #define PINE3 3
186 | #define PINE2 2
187 | #define PINE1 1
188 | #define PINE0 0
189 |
190 | #define DDRE _SFR_IO8(0x0D)
191 | #define DDRE3 3
192 | // Inserted "DDE3" from "DDRE3" due to compatibility
193 | #define DDE3 3
194 | #define DDRE2 2
195 | // Inserted "DDE2" from "DDRE2" due to compatibility
196 | #define DDE2 2
197 | #define DDRE1 1
198 | // Inserted "DDE1" from "DDRE1" due to compatibility
199 | #define DDE1 1
200 | #define DDRE0 0
201 | // Inserted "DDE0" from "DDRE0" due to compatibility
202 | #define DDE0 0
203 |
204 | #define PORTE _SFR_IO8(0x0E)
205 | #define PORTE3 3
206 | #define PORTE2 2
207 | #define PORTE1 1
208 | #define PORTE0 0
209 |
210 | /* Reserved [0x0F..0x14] */
211 |
212 | #define TIFR0 _SFR_IO8(0x15)
213 | #define TOV0 0
214 | #define OCF0A 1
215 | #define OCF0B 2
216 |
217 | #define TIFR1 _SFR_IO8(0x16)
218 | #define TOV1 0
219 | #define OCF1A 1
220 | #define OCF1B 2
221 | #define ICF1 5
222 |
223 | #define TIFR2 _SFR_IO8(0x17)
224 | #define TOV2 0
225 | #define OCF2A 1
226 | #define OCF2B 2
227 |
228 | #define TIFR3 _SFR_IO8(0x18)
229 | #define TOV3 0
230 | #define OCF3A 1
231 | #define OCF3B 2
232 | #define ICF3 5
233 |
234 | #define TIFR4 _SFR_IO8(0x19)
235 | #define TOV4 0
236 | #define OCF4A 1
237 | #define OCF4B 2
238 | #define ICF4 5
239 |
240 | /* Reserved [0x1A] */
241 |
242 | #define PCIFR _SFR_IO8(0x1B)
243 | #define PCIF0 0
244 | #define PCIF1 1
245 | #define PCIF2 2
246 | #define PCIF3 3
247 |
248 | #define EIFR _SFR_IO8(0x1C)
249 | #define INTF0 0
250 | #define INTF1 1
251 |
252 | #define EIMSK _SFR_IO8(0x1D)
253 | #define INT0 0
254 | #define INT1 1
255 |
256 | #define GPIOR0 _SFR_IO8(0x1E)
257 |
258 | #define EECR _SFR_IO8(0x1F)
259 | #define EERE 0
260 | #define EEPE 1
261 | #define EEMPE 2
262 | #define EERIE 3
263 | #define EEPM0 4
264 | #define EEPM1 5
265 |
266 | #define EEDR _SFR_IO8(0x20)
267 |
268 | /* Combine EEARL and EEARH */
269 | #define EEAR _SFR_IO16(0x21)
270 |
271 | #define EEARL _SFR_IO8(0x21)
272 | #define EEARH _SFR_IO8(0x22)
273 |
274 | #define GTCCR _SFR_IO8(0x23)
275 | #define PSRSYNC 0
276 | #define TSM 7
277 | #define PSRASY 1
278 |
279 | #define TCCR0A _SFR_IO8(0x24)
280 | #define WGM00 0
281 | #define WGM01 1
282 | #define COM0B0 4
283 | #define COM0B1 5
284 | #define COM0A0 6
285 | #define COM0A1 7
286 |
287 | #define TCCR0B _SFR_IO8(0x25)
288 | #define CS00 0
289 | #define CS01 1
290 | #define CS02 2
291 | #define WGM02 3
292 | #define FOC0B 6
293 | #define FOC0A 7
294 |
295 | #define TCNT0 _SFR_IO8(0x26)
296 |
297 | #define OCR0A _SFR_IO8(0x27)
298 |
299 | #define OCR0B _SFR_IO8(0x28)
300 |
301 | /* Reserved [0x29] */
302 |
303 | #define GPIOR1 _SFR_IO8(0x2A)
304 |
305 | #define GPIOR2 _SFR_IO8(0x2B)
306 |
307 | #define SPCR0 _SFR_IO8(0x2C)
308 | #define SPR00 0
309 | #define SPR01 1
310 | #define CPHA0 2
311 | #define CPOL0 3
312 | #define MSTR0 4
313 | #define DORD0 5
314 | #define SPE0 6
315 | #define SPIE0 7
316 |
317 | #define SPSR0 _SFR_IO8(0x2D)
318 | #define SPI2X0 0
319 | #define WCOL0 6
320 | #define SPIF0 7
321 |
322 | #define SPDR0 _SFR_IO8(0x2E)
323 |
324 | /* Reserved [0x2F] */
325 |
326 | #define ACSR _SFR_IO8(0x30)
327 | #define ACIS0 0
328 | #define ACIS1 1
329 | #define ACIC 2
330 | #define ACIE 3
331 | #define ACI 4
332 | #define ACO 5
333 | #define ACBG 6
334 | #define ACD 7
335 |
336 | /* Reserved [0x31..0x32] */
337 |
338 | #define SMCR _SFR_IO8(0x33)
339 | #define SE 0
340 | #define SM0 1
341 | #define SM1 2
342 | #define SM2 3
343 |
344 | #define MCUSR _SFR_IO8(0x34)
345 | #define PORF 0
346 | #define EXTRF 1
347 | #define BORF 2
348 | #define WDRF 3
349 |
350 | #define MCUCR _SFR_IO8(0x35)
351 | #define IVCE 0
352 | #define IVSEL 1
353 | #define PUD 4
354 | #define BODSE 5
355 | #define BODS 6
356 |
357 | /* Reserved [0x36] */
358 |
359 | #define SPMCSR _SFR_IO8(0x37)
360 | #define SPMEN 0
361 | #define PGERS 1
362 | #define PGWRT 2
363 | #define BLBSET 3
364 | #define RWWSRE 4
365 | #define SIGRD 5
366 | #define RWWSB 6
367 | #define SPMIE 7
368 |
369 | /* Reserved [0x38..0x3C] */
370 |
371 | /* SP [0x3D..0x3E] */
372 |
373 | /* SREG [0x3F] */
374 |
375 | #define WDTCSR _SFR_MEM8(0x60)
376 | #define WDE 3
377 | #define WDCE 4
378 | #define WDP0 0
379 | #define WDP1 1
380 | #define WDP2 2
381 | #define WDP3 5
382 | #define WDIE 6
383 | #define WDIF 7
384 |
385 | #define CLKPR _SFR_MEM8(0x61)
386 | #define CLKPS0 0
387 | #define CLKPS1 1
388 | #define CLKPS2 2
389 | #define CLKPS3 3
390 | #define CLKPCE 7
391 |
392 | #define XFDCSR _SFR_MEM8(0x62)
393 | #define XFDIE 0
394 | #define XFDIF 1
395 |
396 | /* Reserved [0x63] */
397 |
398 | #define PRR0 _SFR_MEM8(0x64)
399 | #define PRADC 0
400 | #define PRUSART0 1
401 | #define PRSPI0 2
402 | #define PRTIM1 3
403 | #define PRUSART1 4
404 | #define PRTIM0 5
405 | #define PRTIM2 6
406 | #define PRTWI0 7
407 |
408 | #define __AVR_HAVE_PRR0 ((1<
34 |
35 | #define NUM_DIGITAL_PINS 24
36 | #define NUM_ANALOG_INPUTS 8
37 |
38 |
39 | /*pins which can deliver PWM */
40 | #define digitalPinHasPWM(p) (((p) >= 0 && (p) <= 3) || ((p) >= 10 && (p)<= 13) || (p) == 6)
41 |
42 | /* First SPI */
43 | static const uint8_t SS = 12;
44 | static const uint8_t MOSI = 13;
45 | static const uint8_t MISO = 14;
46 | static const uint8_t SCK = 15;
47 |
48 | /* 2nd SPI */
49 | static const uint8_t SS1 = 16;
50 | static const uint8_t MOSI1 = 17;
51 | static const uint8_t MISO1 = 18;
52 | static const uint8_t SCK1 = 19;
53 |
54 |
55 | /* Default I2C is I2C1, because I2C0 is at the additionally pin header */
56 | static const uint8_t SDA = 8; // PE0
57 | static const uint8_t SCL = 7; // PE1
58 |
59 | static const uint8_t SDA0 = 21; //PC4
60 | static const uint8_t SCL0 = 20; //PC5
61 |
62 | /* Second I2C */
63 | static const uint8_t SDA1 = 8; // PE0
64 | static const uint8_t SCL1 = 7; // PE1
65 |
66 | #undef LED_BUILTIN
67 | #define LED_BUILTIN 15
68 |
69 |
70 |
71 |
72 | /*Pin Change Interrupt Control Register */
73 | #define digitalPinToPCICR(p) (((p) >= 0 && (p) <= NUM_DIGITAL_PINS) ? (&PCICR) : ((uint8_t *)0))
74 | #define digitalPinToPCICRbit(p) \
75 | ( \
76 | (p) == 0 ? 2 : \
77 | ((p) == 1 ? 2 : \
78 | ((p) == 2 ? 2 : \
79 | ((p) == 3 ? 2 : \
80 | ((p) == 4 ? 2 : \
81 | ((p) == 5 ? 0 : \
82 | ((p) == 6 ? 0 : \
83 | ((p) == 7 ? 3 : \
84 | ((p) == 8 ? 3 : \
85 | ((p) == 9 ? 2 : \
86 | ((p) == 10 ? 2 : \
87 | ((p) == 11 ? 2 : \
88 | ((p) == 12 ? 0 : \
89 | ((p) == 13 ? 0 : \
90 | ((p) == 14 ? 0 : \
91 | ((p) == 15 ? 0 : \
92 | ((p) == 16 ? 3 : \
93 | ((p) == 17 ? 3 : \
94 | ((p) == 18 ? 1 : \
95 | ((p) == 19 ? 1 : \
96 | ((p) == 20 ? 1 : \
97 | ((p) == 21 ? 1 : \
98 | ((p) == 22 ? 1 : \
99 | ((p) == 23 ? 1 : 0) \
100 | )))))))))))))))))))))))
101 |
102 | /* Pin Change Mask Register 0*/
103 | // Pin Change interrupts
104 | // PCINT0 - PCINT5 = PB0-PB5 PCMSK0
105 | // PCINT8 - PCINT13 = PC0-PC5 PCMSK1
106 | // PCINT16 - PCINT23 = PD0-PD7 PCMSK2
107 | // PCINT24 - PCINT27 = PE0-PE3 PCMSK3
108 |
109 | /* map digital pin to pin change mask register */
110 | #define digitalPinToPCMSK(p) (((p) == 5 || (p) == 6 || (p) == 13 || (p) == 14 || (p) == 15 || (p) == 16 ) ? &PCMSK0: \
111 | (((p) >= 18 && p <= 23) ? &PCMSK1 : \
112 | ((((p) >= 0 && (p) <= 4) || ((p) >= 9 && (p) <= 11)) ? &PCMSK2: \
113 | (((p) == 7 || (p) == 8 || (p) == 16 || (p) == 17 ) ? &PCMSK3: ((uint8_t *)0) \
114 | ))))
115 |
116 | /* map arduino pin to bit of the PCMSK Register */
117 | #define digitalPinToPCMSKbit(p) \
118 | ( \
119 | (p) == 0 ? 1 : \
120 | ((p) == 1 ? 0 : \
121 | ((p) == 2 ? 5 : \
122 | ((p) == 3 ? 6 : \
123 | ((p) == 4 ? 7 : \
124 | ((p) == 5 ? 0 : \
125 | ((p) == 6 ? 1 : \
126 | ((p) == 7 ? 1 : \
127 | ((p) == 8 ? 0 : \
128 | ((p) == 9 ? 4 : \
129 | ((p) == 10 ? 3 : \
130 | ((p) == 11 ? 2 : \
131 | ((p) == 12 ? 2 : \
132 | ((p) == 13 ? 3 : \
133 | ((p) == 14 ? 4 : \
134 | ((p) == 15 ? 5 : \
135 | ((p) == 16 ? 2 : \
136 | ((p) == 17 ? 3 : \
137 | ((p) == 18 ? 0 : \
138 | ((p) == 19 ? 1 : \
139 | ((p) == 20 ? 5 : \
140 | ((p) == 21 ? 4 : \
141 | ((p) == 22 ? 3 : \
142 | ((p) == 23 ? 2 : 0) \
143 | )))))))))))))))))))))))
144 |
145 |
146 | /* map arduino pins to external interrupt */
147 | #define digitalPinToInterrupt(p) ((p) == 11 ? 0 : ((p) == 10 ? 1 : NOT_AN_INTERRUPT))
148 |
149 |
150 | /* Analog Pins*/
151 | #define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + 16 : -1)
152 | static const uint8_t A0 = 0;
153 | static const uint8_t A1 = 1;
154 | static const uint8_t A2 = 2;
155 | static const uint8_t A3 = 3;
156 | static const uint8_t A4 = 4;
157 | static const uint8_t A5 = 5;
158 | static const uint8_t A6 = 6;
159 | static const uint8_t A7 = 7;
160 |
161 | /* Analog Channel Pin Assignment */
162 | extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
163 | #define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
164 |
165 | #ifdef ARDUINO_MAIN
166 |
167 |
168 | // these arrays map port names (e.g. port B) to the
169 | // appropriate addresses for various functions (e.g. reading
170 | // and writing)
171 | const uint16_t PROGMEM port_to_mode_PGM[] = {
172 | NOT_A_PORT,
173 | NOT_A_PORT,
174 | (uint16_t) &DDRB,
175 | (uint16_t) &DDRC,
176 | (uint16_t) &DDRD,
177 | (uint16_t) &DDRE,
178 | };
179 |
180 | const uint16_t PROGMEM port_to_output_PGM[] = {
181 | NOT_A_PORT,
182 | NOT_A_PORT,
183 | (uint16_t) &PORTB,
184 | (uint16_t) &PORTC,
185 | (uint16_t) &PORTD,
186 | (uint16_t) &PORTE,
187 | };
188 |
189 | const uint16_t PROGMEM port_to_input_PGM[] = {
190 | NOT_A_PORT,
191 | NOT_A_PORT,
192 | (uint16_t) &PINB,
193 | (uint16_t) &PINC,
194 | (uint16_t) &PIND,
195 | (uint16_t) &PINE,
196 | };
197 |
198 | /* Port Settings per externel IO Pin*/
199 | const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
200 | PD, // PD1 /* Left Side Top*/
201 | PD, // PD0
202 | PD, // PD5
203 | PD, // PD6
204 | PD, // PD7
205 | PB, // PB0
206 | PB, // PB1
207 | PE, // PE1
208 | PE, // PE0
209 | PD, // PD4
210 | PD, // PD3
211 | PD, // PD2 /* Left Side Bottom*/
212 | PB, // PB2 /* Right Side Bottom */
213 | PB, // PB3
214 | PB, // PB4
215 | PB, // PB5 // LED
216 | PE, // PE2
217 | PE, // PE3
218 | PC, // PC0
219 | PC, // PC1 /* Right Side Top */
220 | PC, // PC5 /* External Connector Left*/
221 | PC, // PC4
222 | PC, // PC3
223 | PC // PC2 /* External Connector Right*/
224 | };
225 |
226 | /* Pin - Port Setting*/
227 | const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
228 | _BV(1),
229 | _BV(0),
230 | _BV(5),
231 | _BV(6),
232 | _BV(7),
233 | _BV(0),
234 | _BV(1),
235 | _BV(1),
236 | _BV(0),
237 | _BV(4),
238 | _BV(3),
239 | _BV(2),
240 | _BV(2),
241 | _BV(3),
242 | _BV(4),
243 | _BV(5),
244 | _BV(2),
245 | _BV(3),
246 | _BV(0),
247 | _BV(1),
248 | _BV(5),
249 | _BV(4),
250 | _BV(3),
251 | _BV(2)
252 | };
253 |
254 | /* Pin-Timer Assignment */
255 | const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
256 | TIMER4A,
257 | TIMER3A,
258 | TIMER0B,
259 | TIMER0A,
260 | NOT_ON_TIMER,
261 | NOT_ON_TIMER,
262 | TIMER1A,
263 | NOT_ON_TIMER,
264 | NOT_ON_TIMER,
265 | NOT_ON_TIMER,
266 | TIMER2B,
267 | TIMER4B,
268 | TIMER1B,
269 | TIMER2A,
270 | NOT_ON_TIMER,
271 | NOT_ON_TIMER,
272 | NOT_ON_TIMER,
273 | NOT_ON_TIMER,
274 | NOT_ON_TIMER,
275 | NOT_ON_TIMER,
276 | NOT_ON_TIMER,
277 | NOT_ON_TIMER,
278 | NOT_ON_TIMER,
279 | NOT_ON_TIMER
280 | };
281 |
282 |
283 | const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
284 | 6, // A0 PE2 ADC6
285 | 7, // A1 PF3 ADC7
286 | 0, // A2 PC0 ADC0
287 | 1, // A3 PC1 ADC1
288 | 5, // A4 PC5 ADC5
289 | 4, // A5 PC4 ADC4
290 | 3, // A6 PC3 ADC3
291 | 2, // A7 PC2 ADC2
292 | };
293 |
294 |
295 | #endif /* ARDUINO_MAIN */
296 |
297 |
298 | #define SERIAL_PORT_MONITOR Serial
299 | #define SERIAL_PORT_HARDWARE Serial
300 | #define SERIAL_PORT_HARDWARE1 Serial1
301 | #define SERIAL_PORT_HARDWARE_OPEN Serial1
302 |
303 | #endif
304 |
--------------------------------------------------------------------------------
/src/variants/superstick/pins_arduino.h:
--------------------------------------------------------------------------------
1 | /*
2 | pins_arduino.h - Pin definition functions for Arduino
3 | Part of Arduino - http://www.arduino.cc/
4 |
5 | Copyright (c) 2007 David A. Mellis
6 |
7 | This library is free software; you can redistribute it and/or
8 | modify it under the terms of the GNU Lesser General Public
9 | License as published by the Free Software Foundation; either
10 | version 2.1 of the License, or (at your option) any later version.
11 |
12 | This library is distributed in the hope that it will be useful,
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | Lesser General Public License for more details.
16 |
17 | You should have received a copy of the GNU Lesser General
18 | Public License along with this library; if not, write to the
19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20 | Boston, MA 02111-1307 USA
21 |
22 | $Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
23 | */
24 |
25 |
26 | /* *uino Superstick Atmega328PB based Board with 20MHz
27 | * by A. Moehl, 2016
28 | */
29 |
30 | #ifndef Pins_Arduino_h
31 | #define Pins_Arduino_h
32 |
33 | #include
34 |
35 | #define NUM_DIGITAL_PINS 18
36 | #define NUM_ANALOG_INPUTS 6
37 |
38 |
39 | /*pins which can deliver PWM */
40 | #define digitalPinHasPWM(p) ((p) == 1 || (p) == 4 || (p) >= 12 || (p) == 14 || (p) == 16 || (p) == 17 || (p) == 18)
41 |
42 | /* First SPI */
43 | static const uint8_t MOSI = 1;
44 | static const uint8_t MISO = 2;
45 | static const uint8_t SCK = 3;
46 | static const uint8_t SS = 4;
47 |
48 | /* 2nd SPI */
49 | static const uint8_t MOSI1 = 5;
50 | static const uint8_t MISO1 = 8;
51 | static const uint8_t SCK1 = 7;
52 | static const uint8_t SS1 = 6;
53 |
54 | /* Default I2C is I2C1, because I2C0 isn't available on the *uino Superstick*/
55 | static const uint8_t SDA = 13; // PE0
56 | static const uint8_t SCL = 11; // PE1
57 |
58 | static const uint8_t SDA0 = 13; //PC4
59 | static const uint8_t SCL0 = 11; //PC5
60 |
61 | /* Second I2C */
62 | static const uint8_t SDA1 = 13; // PE0
63 | static const uint8_t SCL1 = 11; // PE1
64 |
65 | #undef LED_BUILTIN
66 | #define LED_BUILTIN 0 // PD7 - only for the LED
67 |
68 |
69 |
70 | /*Pin Change Interrupt Control Register */
71 | #define digitalPinToPCICR(p) (((p) >= 0 && (p) <= NUM_DIGITAL_PINS) ? (&PCICR) : ((uint8_t *)0))
72 | #define digitalPinToPCICRbit(p) \
73 | ( \
74 | (p) == 0 ? 2 : \
75 | ((p) == 1 ? 0 : \
76 | ((p) == 2 ? 0 : \
77 | ((p) == 3 ? 0 : \
78 | ((p) == 4 ? 0 : \
79 | ((p) == 5 ? 3 : \
80 | ((p) == 6 ? 3 : \
81 | ((p) == 7 ? 1 : \
82 | ((p) == 8 ? 2 : \
83 | ((p) == 9 ? 2 : \
84 | ((p) == 10 ? 1 : \
85 | ((p) == 11 ? 3 : \
86 | ((p) == 12 ? 2 : \
87 | ((p) == 13 ? 3 : \
88 | ((p) == 14 ? 2 : \
89 | ((p) == 15 ? 0 : \
90 | ((p) == 16 ? 1 : \
91 | ((p) == 17 ? 0 : \
92 | ((p) == 18 ? 1 : 0) \
93 | ))))))))))))))))))
94 |
95 | /* Pin Change Mask Register 0*/
96 | // Pin Change interrupts
97 | // PCINT0 - PCINT7 = PB0-PB7
98 | // PCINT8 - PCINT15 = PC0-PC7
99 | // PCINT16 - PCINT23 = PD0-PD7
100 | // PCINT24 - PCINT27 = PE0-PE3
101 |
102 | /* map digital pin to pin change mask register */
103 | #define digitalPinToPCMSK(p) (((p) == 1 || (p) == 2 || (p) == 3 || (p) == 4 || (p) == 15 || (p) == 17 ) ? &PCMSK0: \
104 | (((p) == 7 || (p) == 8 || (p) == 9 || (p) == 10 ) ? &PCMSK1 : \
105 | (((p) == 0 || (p) == 12 || (p) == 14 || (p) == 16 || (p) == 18 ) ? &PCMSK2: \
106 | (((p) == 5 || (p) == 6 || (p) == 11 || (p) == 13 ) ? &PCMSK3: ((uint8_t *)0) \
107 | ))))
108 |
109 | /* map arduino pin to bit of the PCMSK Register */
110 | #define digitalPinToPCMSKbit(p) \
111 | ( \
112 | (p) == 0 ? 7 : \
113 | ((p) == 1 ? 3 : \
114 | ((p) == 2 ? 4 : \
115 | ((p) == 3 ? 5 : \
116 | ((p) == 4 ? 2 : \
117 | ((p) == 5 ? 3 : \
118 | ((p) == 6 ? 2 : \
119 | ((p) == 7 ? 1 : \
120 | ((p) == 8 ? 0 : \
121 | ((p) == 9 ? 3 : \
122 | ((p) == 10 ? 2 : \
123 | ((p) == 11 ? 1 : \
124 | ((p) == 12 ? 2 : \
125 | ((p) == 13 ? 0 : \
126 | ((p) == 14 ? 1 : \
127 | ((p) == 15 ? 0 : \
128 | ((p) == 16 ? 0 : \
129 | ((p) == 17 ? 1 : \
130 | ((p) == 18 ? 6 : 0) \
131 | ))))))))))))))))))
132 |
133 |
134 |
135 |
136 | /* external interrupt */
137 | #define digitalPinToInterrupt(p) ((p) == 12 ? 0 : NOT_AN_INTERRUPT))
138 |
139 | /* Analog Pins*/
140 | #define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + 6 : -1)
141 | static const uint8_t A0 = 0;
142 | static const uint8_t A1 = 1;
143 | static const uint8_t A2 = 2;
144 | static const uint8_t A3 = 3;
145 | static const uint8_t A4 = 4;
146 | static const uint8_t A5 = 5;
147 |
148 |
149 | /* Analog Channel Pin Assignment */
150 | extern const uint8_t PROGMEM analog_pin_to_channel_PGM[];
151 | #define analogPinToChannel(P) ( pgm_read_byte( analog_pin_to_channel_PGM + (P) ) )
152 |
153 | #ifdef ARDUINO_MAIN
154 |
155 |
156 | // these arrays map port names (e.g. port B) to the
157 | // appropriate addresses for various functions (e.g. reading
158 | // and writing)
159 | const uint16_t PROGMEM port_to_mode_PGM[] = {
160 | NOT_A_PORT,
161 | NOT_A_PORT,
162 | (uint16_t) &DDRB,
163 | (uint16_t) &DDRC,
164 | (uint16_t) &DDRD,
165 | (uint16_t) &DDRE,
166 | };
167 |
168 | const uint16_t PROGMEM port_to_output_PGM[] = {
169 | NOT_A_PORT,
170 | NOT_A_PORT,
171 | (uint16_t) &PORTB,
172 | (uint16_t) &PORTC,
173 | (uint16_t) &PORTD,
174 | (uint16_t) &PORTE,
175 | };
176 |
177 | const uint16_t PROGMEM port_to_input_PGM[] = {
178 | NOT_A_PORT,
179 | NOT_A_PORT,
180 | (uint16_t) &PINB,
181 | (uint16_t) &PINC,
182 | (uint16_t) &PIND,
183 | (uint16_t) &PINE,
184 | };
185 |
186 | /* Port Settings per externel IO Pin*/
187 | const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
188 | PD, // PD7 - LED
189 | PB, // PB3
190 | PB, // PB4
191 | PB, // PB5
192 | PB, // PB6
193 | PE, // PE3
194 | PE, // PE2
195 | PC, // PC1
196 | PC, // PC0
197 | PC, // PC3
198 | PC, // PC2
199 | PE, // PE1
200 | PD, // PD2
201 | PE, // PE0
202 | PD, // PD1
203 | PB, // PB0
204 | PD, // PD0
205 | PB, // PB1
206 | PD // PD6
207 | };
208 |
209 | /* Pin - Port Setting*/
210 | const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
211 | _BV(7),
212 | _BV(3),
213 | _BV(4),
214 | _BV(5),
215 | _BV(6),
216 | _BV(3),
217 | _BV(2),
218 | _BV(1),
219 | _BV(0),
220 | _BV(3),
221 | _BV(2),
222 | _BV(1),
223 | _BV(2),
224 | _BV(0),
225 | _BV(1),
226 | _BV(0),
227 | _BV(0),
228 | _BV(1),
229 | _BV(6)
230 | };
231 |
232 | /* Pin-Timer Assignment */
233 | const uint8_t PROGMEM digital_pin_to_timer_PGM[] = {
234 | NOT_ON_TIMER,
235 | TIMER2A,
236 | NOT_ON_TIMER,
237 | TIMER1B,
238 | NOT_ON_TIMER,
239 | NOT_ON_TIMER,
240 | NOT_ON_TIMER,
241 | NOT_ON_TIMER,
242 | NOT_ON_TIMER,
243 | NOT_ON_TIMER,
244 | NOT_ON_TIMER,
245 | NOT_ON_TIMER,
246 | TIMER4B,
247 | NOT_ON_TIMER,
248 | TIMER4A,
249 | NOT_ON_TIMER,
250 | TIMER3A,
251 | TIMER1A,
252 | TIMER0A
253 | };
254 |
255 |
256 | const uint8_t PROGMEM analog_pin_to_channel_PGM[] = {
257 | 7, // A0 ADC7
258 | 6, // A1 ADC6
259 | 1, // A2 ADC1
260 | 0, // A3 ADC0
261 | 3, // A4 ADC3
262 | 2, // A5 ADC2
263 | };
264 |
265 |
266 |
267 | #endif /* ARDUINO_MAIN */
268 |
269 |
270 | #define SERIAL_PORT_MONITOR Serial
271 | #define SERIAL_PORT_HARDWARE Serial
272 | #define SERIAL_PORT_HARDWARE1 Serial1
273 | #define SERIAL_PORT_HARDWARE_OPEN Serial1
274 |
275 | #endif
276 |
--------------------------------------------------------------------------------
/uino_m328pb_pack_1.0.0.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/amoehl/uino-atmega328pb/8ba5e7fd5dfb7b1bf20849e24cff64a77afadc63/uino_m328pb_pack_1.0.0.zip
--------------------------------------------------------------------------------