├── 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 --------------------------------------------------------------------------------