diff --git a/.gitignore b/.gitignore
index e43b0f9..538c8c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
.DS_Store
+*~
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..0efd7bc
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,410 @@
+# This file is used to configure the Travis CI tests for MegaCoreX
+
+# Although sudo is no longer required by arduino-ci-script since the 1.0.0 release, for some reason setting "sudo: false" causes the Travis CI build time to significantly increase so this setting is left as "sudo: required"
+sudo: required
+
+
+env:
+ global:
+ # The Arduino IDE will be installed at APPLICATION_FOLDER/arduino
+ - APPLICATION_FOLDER="${HOME}/arduino-ide"
+ - SKETCHBOOK_FOLDER="${HOME}/Arduino"
+
+ # Use Arduino IDE version that supports the new AVRs
+ - IDE_VERSION_LIST_FULL='"1.8.12" "1.8.13"'
+
+
+ matrix:
+ # Compile every example sketch for every library included with MegaCoreX for every MCU, every board option, every installed IDE version
+ # Each line in the matrix will be run as a separate job in the Travis CI build
+
+ ## ATmega4809
+ # pinout=48pin_standard, resetpin=reset, BOD=2v6, clock=internal_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=40pin_standard, resetpin=gpio, BOD=4v3, clock=internal_20MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=40pin_standard,resetpin=gpio,BOD=4v3,clock=internal_20MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=uno_wifi, BOD=4v0, clock=internal_10MHz, bootloader=uart0_alternative
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=uno_wifi,resetpin=reset,BOD=4v0,clock=internal_10MHz,bootloader=uart0_alternative" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=nano_every, BOD=3v7, clock=internal_8MHz, bootloader=uart1_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=nano_every,resetpin=reset,BOD=3v7,clock=internal_8MHz,bootloader=uart1_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # BOD=3v3, clock=internal_5MHz, bootloader=uart1_alternative
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=3v3,clock=internal_5MHz,bootloader=uart1_alternative" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # BOD=2v9, clock=internal_4MHz, bootloader=uart2_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=2v9,clock=internal_4MHz,bootloader=uart2_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # BOD=2v1, clock=internal_2MHz, bootloader=uart2_alternative
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=2v1,clock=internal_2MHz,bootloader=uart2_alternative" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # BOD=1v8, clock=internal_1MHz, bootloader=uart3_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=1v8,clock=internal_1MHz,bootloader=uart3_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # BOD=disabled, clock=external_20MHz, bootloader=uart3_alternative
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=disabled,clock=external_20MHz,bootloader=uart3_alternative" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # clock=external_16MHz
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # clock=external_12MHz
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_12MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # clock=external_8MHz
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # clock=external_4MHz
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_4MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # clock=external_1MHz
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_1MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+
+ ## ATmega4808
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_10MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_5MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_4MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_2MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_1MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:4808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ ## ATmega3209
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_10MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_5MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_4MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_2MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_1MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3209:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ ## ATmega3208
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_10MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_5MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_4MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_2MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_1MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:3208:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ ## ATmega1609
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_10MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_5MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_4MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_2MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_1MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1609:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ ## ATmega1608
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_10MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_5MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_4MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_2MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_1MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries" BOARD_ID="MegaCoreX:megaavr:1608:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ ## ATmega809
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=48pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=48pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:809:pinout=48pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+
+ ## ATmega808
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Comparator" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/EEPROM" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Event" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Logic" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Servo" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SoftwareSerial" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/SPI" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+ # pinout=32pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=32pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=32pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_20MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_8MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=internal_16MHz, bootloader=uart0_default
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=internal_16MHz,bootloader=uart0_default" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+ # pinout=28pin_standard, clock=external_16MHz, bootloader=no_bootloader
+ - SKETCH_PATH="${SKETCHBOOK_FOLDER}/hardware/MegaCoreX/megaavr/libraries/Wire" BOARD_ID="MegaCoreX:megaavr:808:pinout=28pin_standard,resetpin=reset,BOD=2v6,clock=external_16MHz,bootloader=no_bootloader" ALLOW_FAILURE="false" IDE_VERSIONS="$IDE_VERSION_LIST_FULL"
+
+
+before_install:
+ # Check for tabs (excluding subtrees and keywords.txt files)
+ - find . -path './.git' -prune -or -path './megaavr/bootloaders/optiboot' -prune -or -path './megaavr/avrdude.conf' -prune -or -path './avr/travis-ci/arduino-ci-script' -prune -or \( -not -name 'keywords.txt' -and -type f \) -exec grep --with-filename --line-number --binary-files=without-match --regexp=$'\t' '{}' \; -exec echo 'Tab found.' \; -exec false '{}' +
+
+ # Check for non-Unix line endings (excluding subtrees)
+ - find . -path './.git' -prune -or -path './megaavr/bootloaders/optiboot' -prune -or -path './megaavr/avrdude.conf' -prune -or -path './avr/travis-ci/arduino-ci-script' -prune -or -type f -exec grep --files-with-matches --binary-files=without-match --regexp=$'\r$' '{}' \; -exec echo 'Non-Unix EOL detected.' \; -exec false '{}' +
+
+ # Install the script used to simplify use of Travis CI for testing Arduino projects
+ - source "${TRAVIS_BUILD_DIR}/megaavr/travis-ci/arduino-ci-script/arduino-ci-script.sh"
+
+ # These functions can be used to get verbose output for debugging the script
+ # set_script_verbosity can be set to values from 0 - 2 (verbosity off - maximum verbosity)
+ #- set_script_verbosity 1
+ # Setting set_verbose_output_during_compilation to true is the same as File > Preferences > Show verbose output during > compilation (check) in the Arduino IDE
+ #- set_verbose_output_during_compilation "true"
+
+ - set_application_folder "$APPLICATION_FOLDER"
+ - set_sketchbook_folder "$SKETCHBOOK_FOLDER"
+
+ # Check for board definition errors that don't affect compilation
+ - set_board_testing "true"
+
+ # Check for library issues that don't affect compilation
+ - set_library_testing "true"
+
+ # Install a version of Arduino IDE with an outdated bundled arduino:megaavr platform to force installation of latest arduino:avr
+ - install_ide "1.8.13"
+ # Install Arduino AVR Boards to get the AVR toolchain
+ - install_package "arduino:megaavr"
+ # Install MegaCoreX from the repository
+ - install_package
+
+ # Install all IDE version required by the job
+ - install_ide "$IDE_VERSIONS"
+
+
+script:
+ # Verify every sketch in SKETCH_PATH using the environment variables set in the matrix
+ - build_sketch "$SKETCH_PATH" "$BOARD_ID" "$ALLOW_FAILURE" "all"
+
+
+after_script:
+ # Determine user name and repository name from TRAVIS_REPO_SLUG so the configuration will automatically adjust to forks
+ - USER_NAME="$(echo "$TRAVIS_REPO_SLUG" | cut -d'/' -f 1)"
+ - REPOSITORY_NAME="$(echo "$TRAVIS_REPO_SLUG" | cut -d'/' -f 2)"
+ # Commit a report of the job results to a folder named with the build number in the MegaCoreX branch of the CI-reports repository
+ - publish_report_to_repository "$REPORT_GITHUB_TOKEN" "https://github.com/${USER_NAME}/CI-reports.git" "$REPOSITORY_NAME" "build_$(printf "%05d\n" "${TRAVIS_BUILD_NUMBER}")" "false"
+
+ # Print a tab separated report of all sketch verification results to the log
+ - display_report
+
+
+notifications:
+ email:
+ on_success: never
+ on_failure: always
diff --git a/Extended-API.md b/Extended-API.md
new file mode 100644
index 0000000..b5ea4a7
--- /dev/null
+++ b/Extended-API.md
@@ -0,0 +1,253 @@
+# Extended Arduino API
+
+MegaCoreX is Arduino compatible out of the box, but also includes extra functionality that's not available on the official Arduino "megaavr" core. This is functionality that I personally have been missing in the official Arduino API, and have added to MegaCoreX instead.
+
+My goal isn't to "Arduino wrap" all hardware functionality the megaAVR-0 series brings to the table, but to expose functionality advanced users may benefit from and actually use. If you have a very niche application that utilizes one of the more obscure features the chip has, you're probably better off writing the low-level code yourself. Very spesific needs for ADC readings? Obscure timer needs? Read the approperiate Microchip application note!
+
+
+## Table of contents
+* [Analog read resolution](#analog-read-resolution)
+* [Fast IO](#fast-io)
+* [Peripheral pin swapping](#peripheral-pin-swapping)
+* [pinConfigure](#pinConfigure---extended-pin-configuration)
+* [Printf support](#printf-support)
+* [pwmWrite](#pwmwrite---flexible-pwm-routing)
+* [pwmPrescaler](#pwmprescaler---pwm-frequency-setting)
+* [pwmSetResolution](#pwmsetresolution)
+
+
+## Analog read resolution
+The default analog read resolution for these chips is 10 bit, which gives you values between 0 - 1023. If you need lower resolution you can turn it down to 8 bits instead, which gives you values between 0 - 255.
+Simply call `analogReadResolution` like this:
+```c
+analogReadResolution(8); // Set resolution to 8 bits
+analogReadResolution(10); // Set resolution to 10 bits
+```
+
+
+## Fast IO
+For timing critical applications the standard `digitalRead()` and `digitalWrite()` functions may be too slow. To solve this, MegaCoreX also includes some improved variants that compiles down to a single instruction.
+Call `digitalReadFast(myPin)` or `digitalWriteFast(mypin, state)` to use these.
+**Note that the pin number and pin state has to be known at compile time!**
+
+### Declaration
+```c++
+uint8_t digitalReadFast(uint8_t pinNumber);
+void digitalWriteFast(uint8_t pinNumber, uint8_t state);
+```
+
+
+## Peripheral pin swapping
+The megaAVR-0 microcontrollers support alternative pin assignments for some of their built-in peripherals.
+This is specified by invoking the `swap()` or `pins()` method before `begin()` for the associated peripheral.
+They will return `true` if that swap or pin combination is supported.
+For `Serial` peripherals the method is `pins(tx,rx)`, for `Wire` it's `pins(sda,scl)` and for `SPI` it's `pins(mosi,miso,sck,ss)`.
+(Note that this is the same pin sequence as used for the ESP8266 `pins` method, but the opposite of the one SoftwareSerial uses.)
+
+Note that `swap()` and `pins()` do the exact same thing, but `swap()` is MUX swap oriented, while `pins()` is pin oriented.
+
+If you want to use this feature to implement communication with two different external devices connected to different pins using one internal peripheral,
+note that the proper way to switch is first to invoke `end()` to cleanly shut down, then `swap()` or `pins()` to switch assigned pins, and finally `begin()` to cleanly start again.
+
+`swap()` or `pins()` are called like this. **Use either `swap()` or `pins()`, not both!**
+
+``` c++
+// UART pin swapping
+Serial3.swap(1);
+Serial3.begin(9600);
+
+// Wire pin swapping
+Wire.swap(1);
+Wire.begin();
+
+// SPI pin swapping
+SPI.swap(1);
+SPI.begin();
+```
+
+Available pin combinations for the *48 pin standard* pinout are:
+
+| Peripheral | Default | Alternative 1 | Alternative 2 |
+|------------|------------------------------- |------------------------------------|------------------------------------|
+| Serial | swap(0) **or** pins(0,1) | swap(1) **or** pins(4,5) | |
+| Serial1 | swap(0) **or** pins(14,15) | swap(1) **or** pins(18,19) | |
+| Serial2 | swap(0) **or** pins(34,35) | swap(1) **or** pins(38,39) | |
+| Serial3 | swap(0) **or** pins(8,9) | swap(1) **or** pins(12,13) | |
+| Wire | swap(0) **or** pins(2,3) | swap(1) **or** pins(16,17) | |
+| SPI | swap(0) **or** pins(4,5,6,7) | swap(1) **or** pins(14,15,16,17) | swap(2) **or** pins(30,31,32,33) |
+
+Available pin combinations for the *28 pin* and *32 pin standard* pinouts are:
+
+| Peripheral | Default | Alternative |
+|------------|--------------------------------|----------------------------------|
+| Serial | swap(0) **or** pins(0,1) | swap(1) **or** pins(4,5) |
+| Serial1 | swap(0) **or** pins(8,9) | |
+| Serial2 | swap(0) **or** pins(20,21) | swap(1) **or** pins(24,25) |
+| Wire | swap(0) **or** pins(2,3) | swap(1) **or** pins(10,11) |
+| SPI | swap(0) **or** pins(4,5,6,7) | swap(1) **or** pins(8,9,10,11) |
+
+Available pin combinations for the *Uno WiFi* pinout are:
+
+| Peripheral | Default | Alternative |
+|------------|--------------------------------------------------------------|--------------------------------------------------------|
+| Serial | swap(0) **or** pins(27,26)
(connected to mEDBG) | swap(1) **or** pins(9,10) |
+| Serial1 | swap(0) **or** pins(1,0) | swap(1) **or** pins(32,33) (available on SPI header) |
+| Serial2 | swap(0) **or** pins(24,23)
(connected to Wifi module) | swap(1) **or** pins(2,7) |
+| Serial3 | swap(0) **or** pins(6,3) | swap(1) **or** pins(37,38) (not broken out) |
+
+Available pin combinations for the *Nano Every* pinout are:
+
+| Peripheral | Default | Alternative |
+|------------|------------------------------------------------------------------|-----------------------------------------------|
+| Serial | swap(0) **or** pins(25,24)
(connected to USB-serial chip) | swap(1) **or** pins(9,10) |
+| Serial1 | swap(0) **or** pins(1,0) | swap(1) **or** pins(34,35) (not broken out) |
+| Serial2 | swap(0) **or** pins(2,7) | swap(1) **or** pins(28,27) (not broken out) |
+| Serial3 | swap(0) **or** pins(6,3) | swap(1) **or** pins(37,38) (not broken out) |
+
+
+## pinConfigure - extended pin configuration
+pinConfigure is a template based function that exposes all functions that can be configured on a per-pin basis. The first argument is the Arduino pin number to configure, and the second to nth parameter are the configuration parameters. The order the arguments has does not matter. The function will set the pin functionality regardless if it "makes sense" or not. If you enable interupts on a pin and there's no interrupt handler in your code, the microcontroller will crash.
+
+### Declaration
+```c++
+template
+void pinConfigure(const uint8_t digital_pin, const pin_configure_t mode, const MODES&... modes);
+```
+
+### Example
+```c++
+// Set pin PA0 to output and drive the pin high
+pinConfigure(PIN_PA0, PIN_DIR_OUTPUT, PIN_OUT_HIGH);
+// Disable pin PA1 completely to save power
+pinConfigure(PIN_PA1, PIN_INPUT_DISABLE);
+```
+
+### Table of valid pin modes
+The following parameters ca be used to set the pinConfigure modes:
+| Functionality | Enable | Disable | Toggle |
+|---------------|-------|---------------------|--------------------|
+| Direction, pinMode() | `PIN_DIR_OUTPUT`
`PIN_DIR_OUT`
`PIN_DIRSET` | `PIN_DIR_INPUT`
`PIN_DIR_IN`
`PIN_DIRCLR` | `PIN_DIR_TOGGLE`
`PIN_DIRTGL` |
+| Pin output, `HIGH` or LOW | `PIN_OUT_HIGH`
`PIN_OUTSET` | `PIN_OUT_LOW`
`PIN_OUTCLR` | `PIN_OUT_TOGGLE`
`PIN_OUTTGL` |
+| Internal Pullup | `PIN_PULLUP_ON`
`PIN_PULLUP` | `PIN_PULLUP_OFF`
`PIN_NOPULLUP` | `PIN_PULLUP_TGL` |
+| Invert `HIGH` and LOW |`PIN_INVERT_ON` | `PIN_INVERT_OFF` | `PIN_INVERT_TGL` |
+| Digital input buffer | `PIN_INPUT_ENABLE` or
`PIN_ISC_ENABLE` | `PIN_ISC_DISABLE` or
`PIN_INPUT_DISABLE` | Not supported |
+| Interrupt on change | `PIN_ISC_ENABLE` or
`PIN_INPUT_ENABLE` | `PIN_ISC_ENABLE` or
`PIN_ISC_DISABLE` | Not applicable |
+| Interrupt on Rise | `PIN_ISC_RISE` or
`PIN_INT_RISE` | `PIN_ISC_ENABLE` or
`PIN_ISC_DISABLE` | Not applicable |
+| Interrupt on Fall | `PIN_ISC_FALL` or
`PIN_INT_FALL` | `PIN_ISC_ENABLE` or
`PIN_ISC_DISABLE` | Not applicable |
+| Interrupt on LOW | `PIN_ISC_LEVEL` or
`PIN_INT_LEVEL` | `PIN_ISC_ENABLE` or
`PIN_ISC_DISABLE` | Not applicable |
+
+
+## Printf support
+Unlike the official Arduino core, MegaCoreX has printf support out of the box. If you're not familiar with printf you should probably [read this first](https://www.tutorialspoint.com/c_standard_library/c_function_printf.htm). It's added to the Print class and will work with all libraries that inherit Print. Printf is a standard C function that lets you format text much easier than using Arduino's built-in print and println.
+
+Note that the default printf implementation will NOT print floats or doubles by default. This is a limitation of the avr-libc printf implementation on AVR microcontrollers, but can be enabled by setting a build flag. This can easily be done if you're using [PlatformIO](https://github.com/MCUdude/MegaCoreX/blob/master/PlatformIO.md).
+
+If you're using a serial port, simply use `Serial.printf("Milliseconds since start: %ld\n", millis());`. Other common libraries that inherit the Print class (and thus supports printf) are SoftwareSerial, the LiquidCrystal LCD library and the u8g2 graphical LCD library.
+
+
+## pwmWrite - flexible PWM routing
+The Arduino pinout definition and the `analogWrite` function have the PWM output pins pre-defined, and can't be moved or routed to different pins using the default Arduino API, even though the chip itself supports this. The `pwmWrite` function lets to use every supported PWM output pin, and you can route the PWM signals as you like. Note that the chip limits which timer output can be routed to which pins, and you also need to make sure you don't route the PWM signal to a pins that's used for something else, like UART or SPI. Also keep in mind that the timer used for millis/micros is occupied and can not be used for PWM generation. For the Nano Every 4809 and Uno Wifi Rev2 this means timer TCB2, and for all the other pinouts TCB2. Also note that low-pinout parts does not have timer TCB3 and all the routing pin options due to the lack of physical IO.
+
+### Declaration
+```c++
+void pwmWrite(pwm_timers_t pwmTimer, uint16_t val, timers_route_t timerRoute);
+```
+
+### Example
+```c++
+// Route timer TCB0 PWM output to pin PF4 and set the duty cycle to 50% (128/255)
+pwmWrite(TCB_0, 128, ROUTE_TCB0_PF4);
+// Set the timer TCB0 duty cycle to 30% but leave the routing as is
+pwmWrite(TCB_0, 76);
+// Route all TCA0 timer to PORTA, enable the 2nd TCA0 PWM output (PA2 in this case), and set dyty cycle to 50%
+pwmWrite(TCA0_2, 128, ROUTE_TCA0_PORTA);
+```
+
+### Table of valid options
+
+| Timer enums | Description |
+|-------------|----------------------------------|
+| `TCA0_0` | Identifier for TCA0 PWM output 0 |
+| `TCA0_1` | Identifier for TCA0 PWM output 1 |
+| `TCA0_2` | Identifier for TCA0 PWM output 2 |
+| `TCA0_3` | Identifier for TCA0 PWM output 3 |
+| `TCA0_4` | Identifier for TCA0 PWM output 4 |
+| `TCA0_5` | Identifier for TCA0 PWM output 5 |
+| `TCB_0` | Identifier for TCB0 PWM output |
+| `TCB_1` | Identifier for TCB1 PWM output |
+| `TCB_2` | Identifier for TCB2 PWM output |
+| `TCB_3` | Identifier for TCB3 PWM output |
+
+| PWM routing enums | Description |
+|--------------------|---------------------------------------------------------------------------------|
+| `ROUTE_TCA0_PORTA` | Route all six TCA0 PWM channels to PA0..PA5 |
+| `ROUTE_TCA0_PORTB` | Route all six TCA0 PWM channels to PB0..PB5 (not present on low pincount parts) |
+| `ROUTE_TCA0_PORTC` | Route all six TCA0 PWM channels to PC0..PC5 |
+| `ROUTE_TCA0_PORTD` | Route all six TCA0 PWM channels to PD0..PD5 |
+| `ROUTE_TCA0_PORTE` | Route all six TCA0 PWM channels to PE0..PE5 (not present on low pincount parts) |
+| `ROUTE_TCA0_PORTF` | Route all six TCA0 PWM channels to PF0..PF5 |
+| `ROUTE_TCB0_PA2` | Route the TCB0 PWM output to pin PA2 |
+| `ROUTE_TCB0_PF4` | Route the TCB0 PWM output to pin PF4 |
+| `ROUTE_TCB1_PA3` | Route the TCB1 PWM output to pin PA3 |
+| `ROUTE_TCB1_PF5` | Route the TCB1 PWM output to pin PF5 |
+| `ROUTE_TCB2_PC0` | Route the TCB2 PWM output to pin PC0 |
+| `ROUTE_TCB2_PB4` | Route the TCB2 PWM output to pin PB4 (not present on low pincount parts) |
+| `ROUTE_TCB3_PB5` | Route the TCB3 PWM output to pin PB5 (not present on low pincount parts) |
+| `ROUTE_TCB3_PC1` | Route the TCB3 PWM output to pin PC1 (not present on low pincount parts) |
+
+
+## pwmPrescaler - PWM frequency setting
+`pwmPrescaler` sets the clock source that drives timer. Timer TCA0 has the most options, while the TCB timers have fewer.
+The prescaler direcly affects the PWM frequency, and this is the formula that determines the frequency:
+`F_CPU / resolution / prescaler`. For instance, the default TCB PWM prescaler with a system clock of 16 MHz is 1/64, which results in a PWM frequency of just under 1 kHz.
+
+### Declaration
+```c++
+void pwmPrescaler(pwm_timers_t pwmTimer, timers_prescaler_t prescaler);
+```
+
+### Example
+```c++
+// Set the TCA0 timer prescaler to 1/64 of the system clock frequency
+pwmPrescaler(TCA0_0, TCA_DIV64);
+// Set timer TCB0 to run off the TCA0 clock
+pwmPrescaler(TCB_0, TCB_CLKTCA);
+// Set timer TCB1 prescaler to 1/2 of the system clock frequency
+pwmPrescaler(TCB_1, TCB_DIV2);
+```
+
+### Table of valid options
+
+| Prescaler | Timer | Description | Notes |
+|---------------|---------|----------------------------------------------------|-------------------------------------------------|
+| `TCB_DIV1` | TCB0..3 | Runs TCB at full system clock speed | |
+| `TCB_DIV2` | TCB0..3 | Runs TCB at 1/2 of the system clock | |
+| `TCB_CLKTCA` | TCB0..3 | Runs TCB at the same clock as TCA0 is running off | Default option for all TCB timers |
+| `TCA_DIV1` | TCA0 | Runs TCA0 full system clock speed | |
+| `TCA_DIV2` | TCA0 | Runs TCA0 at 1/2 of the system clock | |
+| `TCA_DIV4` | TCA0 | Runs TCA0 at 1/4 of the system clock | |
+| `TCA_DIV8` | TCA0 | Runs TCA0 at 1/8 of the system clock | |
+| `TCA_DIV16` | TCA0 | Runs TCA0 at 1/16 of the system clock | |
+| `TCA_DIV64` | TCA0 | Runs TCA0 at 1/64 of the system clock | Default option when using a 16 MHz system clock |
+| `TCA_DIV256` | TCA0 | Runs TCA0 at 1/256 of the system clock | |
+| `TCA_DIV1024` | TCA0 | Runs TCA0 at 1/1024 the system clock | |
+
+
+## pwmSetResolution
+This function lets you change the PWM resolution in favour of increased PWM frequency. The default PWM range is 0-255, but the upper limit can be set to anything between 1 and 254. The resolution also affects the PWM frequency. The frequency can be calculated using this formula:
+`F_CPU / resolution / prescaler`
+
+### Declaration
+```c++
+void pwmSetResolution(pwm_timers_t pwmTimer, uint8_t maxValue);
+```
+
+### Example
+```c++
+// Set TCA0 timer max value to 127
+pwmSetResolution(TCA0_0, 127);
+// Set TCB0 timer max value to 31
+pwmSetResolution(TCB_0, 31);
+// Set TCB1 timer max value to 99
+pwmSetResolution(TCB_1, 99);
+```
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..8000a6f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random
+ Hacker.
+
+ , 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/PlatformIO.md b/PlatformIO.md
new file mode 100644
index 0000000..17fc9fd
--- /dev/null
+++ b/PlatformIO.md
@@ -0,0 +1,479 @@
+# PlatformIO
+
+[PlatformIO](https://platformio.org) is an open-source ecosystem for embedded development.
+It has a built-in library manager and is Arduino-compatible. It supports most operating systems; Windows, MacOS, Linux 32 and 64-bit, ARM, and X86. And best of all, MegaCoreX is supported!
+
+* [What is PlatformIO?](http://docs.platformio.org/en/latest/what-is-platformio.html)
+* [PlatformIO IDE](https://platformio.org/platformio-ide)
+* Getting started with [PlatformIO IDE](https://docs.platformio.org/en/latest/integration/ide/visualstudio.html) or [PlatformIO command line interface](https://docs.platformio.org/en/latest/core/index.html)
+* [Advanced functionality](https://docs.platformio.org/en/latest/platforms/atmelmegaavr.html)
+* [Project Examples](https://docs.platformio.org/en/latest/platforms/atmelmegaavr.html#examples)
+
+
+## MegaCoreX + PlatformIO
+MegaCoreX and PlatformIO go great together. You can do serial uploads and upload using a dedicated UPDI programmer, but you can also let PlatformIO calculate the fuses and load the correct bootloader file, just like Arduino IDE does!
+
+PlatformIO uses the information provided in platformio.ini to calculate what fuse bits and what bootloader file to load.
+Simply provide enough information and run the following commands:
+
+```ini
+; Only set fuses
+pio run -t fuses -e fuses_bootloader
+; Set fuses and burn bootloader
+pio run -t bootloader -e fuses_bootloader
+; (where "fuses_bootloader" can be replaced with a different environment to match your build configuration)
+```
+
+You can find a platformio.ini template you can use when creating a project for a MegaCoreX-compatible device below.
+The most common functionality is available in this template. As you can see, the templated is divided into multiple environments.
+
+* The default build environment is defined under *[platformio]*.
+* All parameters that are common for all environments are defined under *[env]*.
+* Use the *[env:Upload_UPDI]* or *[env:Upload_UART]* to upload to your target.
+* Use *[env:fuses_bootloader]* to set the fuses or burn the bootloader.
+
+More information on what each line means can be found further down on this page.
+
+
+## platformio.ini templates
+All these templates are very similar, but I've created a few ones for different programmers to make it easier to get started
+
+
+ATmega4809, microUPDI / Xplained Mini programmer, optional bootloader
+
+```ini
+; PlatformIO template configuration file for MegaCoreX
+; https://github.com/MCUdude/MegaCoreX/
+;
+; Build options: build flags, source filter
+; Hardware options: oscillator type, BOD, UART number, EEPROM retain
+; Upload options: custom upload port, speed, and extra flags
+; Library options: dependencies, extra library storage
+; Advanced options: extra scripting
+;
+; Please visit documentation for the other options
+; https://github.com/MCUdude/MegaCoreX/blob/master/PlatformIO.md
+; https://docs.platformio.org/page/projectconf.html
+; https://docs.platformio.org/en/latest/platforms/atmelmegaavr.html
+
+[platformio]
+; Default build target
+default_envs = Upload_UPDI
+
+; Parameters used for all environments
+[env]
+platform = atmelmegaavr
+framework = arduino
+
+; Chip in use
+board = ATmega4809
+; Clock frequency in [Hz]
+board_build.f_cpu = 16000000L
+; Oscillator type (internal or external)
+board_hardware.oscillator = internal
+; Arduino pinout variant
+board_build.variant = 48pin-standard
+
+; Unflag build flags
+build_unflags =
+; Extra build flags
+build_flags =
+
+; Monitor port is auto detected. Override here
+;monitor_port =
+monitor_speed = 9600
+
+
+; Run the following command to upload with this environment
+; pio run -t upload
+[env:Upload_UPDI]
+; Upload protocol for UPDI upload
+upload_protocol = xplainedmini_updi
+upload_flags =
+
+
+; Run the following command to upload with this environment
+; pio run -e Upload_UART -t upload
+[env:Upload_UART]
+; Upload protocol for serial uploads (using Optiboot)
+upload_protocol = arduino
+upload_port = /dev/cu.usbserial*
+upload_flags =
+
+
+; run the following command to set fuses
+; pio run -e fuses_bootloader -t fuses
+; run the following command to set fuses + burn bootloader
+; pio run -e fuses_bootloader -t bootloader
+[env:fuses_bootloader]
+; Inherit upload settings from the Upload_UPDI environment
+extends = env:Upload_UPDI
+
+; Hardware settings
+board_hardware.bod = 2.7v
+board_hardware.eesave = yes
+board_hardware.uart = no_bootloader
+board_hardware.rstpin = reset
+
+```
+
+
+
+
+ATmega4809, SerialUPDI programmer, optional bootloader
+
+```ini
+; PlatformIO template configuration file for MegaCoreX
+; https://github.com/MCUdude/MegaCoreX/
+;
+; Build options: build flags, source filter
+; Hardware options: oscillator type, BOD, UART number, EEPROM retain
+; Upload options: custom upload port, speed, and extra flags
+; Library options: dependencies, extra library storage
+; Advanced options: extra scripting
+;
+; Please visit documentation for the other options
+; https://github.com/MCUdude/MegaCoreX/blob/master/PlatformIO.md
+; https://docs.platformio.org/page/projectconf.html
+; https://docs.platformio.org/en/latest/platforms/atmelmegaavr.html
+
+[platformio]
+; Default build target
+default_envs = Upload_UPDI
+
+; Parameters used for all environments
+[env]
+platform = atmelmegaavr
+framework = arduino
+
+; Chip in use
+board = ATmega4809
+; Clock frequency in [Hz]
+board_build.f_cpu = 16000000L
+; Oscillator type (internal or external)
+board_hardware.oscillator = internal
+; Arduino pinout variant
+board_build.variant = 48pin-standard
+
+; Unflag build flags
+build_unflags =
+; Extra build flags
+build_flags =
+
+; Monitor port is auto-detected. Override here
+;monitor_port = ${env:Upload_UPDI.upload_port}
+monitor_speed = 9600
+monitor_dtr = 0
+
+
+; Run the following command to upload with this environment
+; pio run -t upload
+[env:Upload_UPDI]
+; Upload protocol for UPDI upload
+upload_protocol = serialupdi
+upload_port = /dev/cu.usbserial*
+upload_speed = 115200
+upload_flags =
+ -xrtsdtr=high
+
+
+; Run the following command to upload with this environment
+; pio run -e Upload_UART -t upload
+[env:Upload_UART]
+; Upload protocol for serial uploads (using Optiboot)
+upload_protocol = arduino
+upload_port = /dev/cu.usbserial*
+upload_flags =
+
+
+; run the following command to set fuses
+; pio run -e fuses_bootloader -t fuses
+; run the following command to set fuses + burn bootloader
+; pio run -e fuses_bootloader -t bootloader
+[env:fuses_bootloader]
+; Inherit upload settings from the Upload_UPDI environment
+extends = env:Upload_UPDI
+
+; Hardware settings
+board_hardware.bod = 2.7v
+board_hardware.eesave = yes
+board_hardware.uart = no_bootloader
+board_hardware.rstpin = reset
+
+```
+
+
+
+
+ATmega4809, JTAG2UPDI programmer, optional bootloader
+
+```ini
+; PlatformIO template configuration file for MegaCoreX
+; https://github.com/MCUdude/MegaCoreX/
+;
+; Build options: build flags, source filter
+; Hardware options: oscillator type, BOD, UART number, EEPROM retain
+; Upload options: custom upload port, speed, and extra flags
+; Library options: dependencies, extra library storage
+; Advanced options: extra scripting
+;
+; Please visit documentation for the other options
+; https://github.com/MCUdude/MegaCoreX/blob/master/PlatformIO.md
+; https://docs.platformio.org/page/projectconf.html
+; https://docs.platformio.org/en/latest/platforms/atmelmegaavr.html
+
+[platformio]
+; Default build target
+default_envs = Upload_UPDI
+
+; Parameters used for all environments
+[env]
+platform = atmelmegaavr
+framework = arduino
+
+; Chip in use
+board = ATmega4809
+; Clock frequency in [Hz]
+board_build.f_cpu = 16000000L
+; Oscillator type (internal or external)
+board_hardware.oscillator = internal
+; Arduino pinout variant
+board_build.variant = 48pin-standard
+
+; Unflag build flags
+build_unflags =
+; Extra build flags
+build_flags =
+
+; Monitor port is auto-detected. Override here
+;monitor_port = ${env:Upload_UPDI.upload_port}
+monitor_speed = 9600
+monitor_dtr = 0
+
+
+; Run the following command to upload with this environment
+; pio run -t upload
+[env:Upload_UPDI]
+; Upload protocol for UPDI upload
+upload_protocol = jtag2updi
+upload_port = /dev/cu.usbserial*
+upload_speed = 115200
+upload_flags =
+
+
+; Run the following command to upload with this environment
+; pio run -e Upload_UART -t upload
+[env:Upload_UART]
+; Upload protocol for serial uploads (using Optiboot)
+upload_protocol = arduino
+upload_port = /dev/cu.usbserial*
+upload_flags =
+
+
+; run the following command to set fuses
+; pio run -e fuses_bootloader -t fuses
+; run the following command to set fuses + burn bootloader
+; pio run -e fuses_bootloader -t bootloader
+[env:fuses_bootloader]
+; Inherit upload settings from the Upload_UPDI environment
+extends = env:Upload_UPDI
+
+; Hardware settings
+board_hardware.bod = 2.7v
+board_hardware.eesave = yes
+board_hardware.uart = no_bootloader
+board_hardware.rstpin = reset
+
+```
+
+
+
+### `board`
+PlatformIO requires the `board` parameter to be present.
+The table below shows what board name should be used for each target
+| Board name |
+|---------------|
+| `ATmega4809` |
+| `ATmega4808` |
+| `ATmega3209` |
+| `ATmega3208` |
+| `ATmega1609` |
+| `ATmega1608` |
+| `ATmega809` |
+| `ATmega808` |
+
+
+### `board_build.f_cpu`
+Specifies the clock frequency in [Hz].
+Used to determine what oscillator option to choose. A capital *L* has to be added to the end of the frequency number.
+Below is a table with supported clocks for MegaCoreX. Defaults to 16 MHz internal if not specified.
+
+| Clock speed | Oscillator | board_build.f_cpu |
+|-------------|------------|-----------------------|
+| 20 MHz | Internal | `20000000L` |
+| 16 MHz | Internal | `16000000L` (default) |
+| 10 MHz | Internal | `10000000L` |
+| 8 MHz | Internal | `8000000L` |
+| 5 MHz | Internal | `5000000L` |
+| 4 MHz | Internal | `4000000L` |
+| 2 MHz | Internal | `2000000L` |
+| 1 MHz | Internal | `1000000L` |
+| 16 MHz | External | `16000000L` |
+| 12 MHz | External | `12000000L` |
+| 8 MHz | External | `8000000L` |
+| 4 MHz | External | `4000000L` |
+| 1 MHz | External | `1000000L` |
+
+
+### `board_hardware.oscillator`
+Specifies to use the internal or an external oscillator.
+
+| Oscillator option |
+|----------------------|
+| `internal` (default) |
+| `external` |
+
+
+### `board_hardware.uart`
+Specifies the hardware UART port used for serial upload. Use `no_bootloader` if you’re using a dedicated UPDI programmer, i.e not using a bootloader for serial upload.
+
+| Upload serial port option | Description |
+|---------------------------|------------------------------------------------|
+| `no_bootloader` (default) | |
+| `uart0` / `uart0_def` | Use UART0 default pins |
+| `uart0_alt` | Use UART0 alternative pins |
+| `uart1` / `uart1_def` | Use UART1 default pins |
+| `uart1_alt` | Use UART1 alternative pins |
+| `uart2` / `uart2_def` | Use UART2 default pins |
+| `uart2_alt` | Use UART2 alternative pins |
+| `uart3` / `uart3_def` | Use UART3 default pins (48-pin parts only) |
+| `uart3_alt` | Use UART3 alternative pins (48-pin parts only) |
+
+### `board_hardware.bod`
+Specifies the hardware brown-out detection. Use `disabled` to disable.
+
+| BOD |
+|------------------|
+| `4.3v` |
+| `2.6v` (default) |
+| `1.8v` |
+| `disabled` |
+
+
+### `board_hardware.eesave`
+Specifies if the EEPROM memory should be retained when uploading using a programmer. Use `no` to disable.
+
+| EEPROM retain |
+|-----------------|
+| `yes` (default) |
+| `no` |
+
+
+### `board_hardware.rstpin`
+Specifies what functionality the reset pin should have. Note that the option `reset` _will_ be selected regardless if you're using a bootloader.
+
+| Reset pin functionality |
+|---------------------------|
+| `reset` (default) |
+| `gpio` |
+
+
+### `board_build.variant`
+Holds the current pinout in use. PlatformIO automatically selects the *default* one if not specified.
+See [pinout pics](https://github.com/MCUdude/MegaCoreX#pinout) for more info.
+
+| Pinouts 48 pin parts | Pinouts 40 pin parts | Pinouts 32 pin parts | Pinouts 28 pin parts |
+|----------------------------|------------------------------------|----------------------------|----------------------------|
+| `48pin-standard` (default) | `40pin-standard` (must be defined) | `32pin-standard` (default) | `28pin-standard` (default) |
+| `nano-every` | | `nano-4808` | |
+| `uno-wifi` | | | |
+
+
+### `build_unflags`
+This parameter is used to unflag flags automatically set by the PlatformIO build environment.
+
+**Example:**
+```
+build_unflags =
+ -flto
+ -fpermissive
+```
+
+
+### `build_flags`
+This parameter is used to set compiler flags. This is useful if you want to for instance want to chage the serial RX or TX buffer. Here's a list of the current available core files flags:
+
+| Flag | Default size | Description |
+|-----------------------------|--------------|-----------------------------------------------------------|
+| -lprintf_flt | | Lets you print floats with printf (occupies ~1.5 kB) |
+| -Wall -Wextra | | Show on all compiler warnings |
+| -DSERIAL_RX_BUFFER_SIZE=128 | 64 bytes | Sets the serial RX buffer to 128 bytes |
+| -DSERIAL_TX_BUFFER_SIZE=128 | 64 bytes | Sets the serial TX buffer to 128 bytes |
+| -DTWI_BUFFER_SIZE=64 | 32 bytes | Sets the TWI (i2c) buffer to 64 bytes |
+
+**Example:**
+```
+build_flags =
+ -DSERIAL_RX_BUFFER_SIZE=128
+ -DSERIAL_TX_BUFFER_SIZE=128
+```
+
+
+### `upload_port`
+Holds the serial port used for uploading. Only needed if you're uploading using a SerialUPDI or JTAG2UPDI programmer or with a USB-to-serial adapter using the Optiboot bootloader. PlatformIO automatically detects the serial port. However, if you want to override this you can uncomment `upload_port`. Use `/dev/[port]` on Unix-compatible systems, and use `COMx` on Windows.
+
+
+### `upload_protocol`
+Programmer used for uploading.
+
+| Supported UPDI programmers in Avrdude | Notes |
+|---------------------------------------|------------------------------------------------------------------------------------------------------------------|
+| [`serialupdi`](https://www.tindie.com/products/mcudude/serialupdi-programmer/) | Requires upload serial port. Change the baud rate in `upload_speed` to increase or decrease upload speed |
+| `xplainedmini_updi` | Xplained Mini and [microUPDI](https://www.tindie.com/products/MCUdude/microupdi-programmer/) programmers |
+| `jtag2updi` | Requires serial upload port. Newer JTAG2UPDI firmware versions support baud rates higher than 115200 baud |
+| `arduino` | Used when uploading using the Optiboot bootloader. Requires upload port |
+| `pkobn_updi` | On-board Curiosity nano programmer |
+| `pickit4_updi` | PICkit4 programmer in UPDI mode |
+| `snap_updi` | MPLAB SNAP programmer in UPDI mode |
+| `atmelice_updi` | Atmel ICE programmer in UPDI mode |
+| `xplainedpro_updi` | Xplained Pro in UPDI mode |
+| `powerdebugger_updi` | Power Debugger in UPDI mode |
+
+
+### `upload_flags`
+Used to pass extra flags to Avrdude when uploading using a programmer.
+Typical parameters are `-qq` or `-v`. See the [Avrdude documentation](https://avrdudes.github.io/avrdude/) for more information.
+**Note that every flag has to be on its own line, and they have to be indented with two spaces:**
+```ini
+upload_flags =
+ -v
+```
+
+
+### `monitor_port`
+PlatformIO detects serial ports automatically. However, if you want to override this you can uncomment `monitor_port`. Use `/dev/[port]` on Unix-compatible systems, and use `COMx` on Windows.
+
+
+### `monitor_speed`
+Sets the serial monitor baud rate. Defaults to 9600 if not defined.
+
+
+## User-defined fuses
+Even though PlatformIO can calculate fuse values depending on the user-specified data in platformio.ini, there may be applications where the fuses have to be set to known values. This can be done like so:
+```ini
+; run the following command to set fuses
+; pio run -e custom_fuses -t fuses
+[env:custom_fuses]
+; Inherit upload settings from the Upload_UPDI environment
+extends = env:Upload_UPDI
+
+; Fuse settings
+board_fuses.wdtcfg = 0x00
+board_fuses.bodcfg = 0x00
+board_fuses.osccfg = 0x01
+board_fuses.tcd0cfg = 0x00
+board_fuses.syscfg0 = 0xC9
+board_fuses.syscfg1 = 0x06
+board_fuses.append = 0x00
+board_fuses.bootend = 0x00
+```
diff --git a/README.md b/README.md
index 5e3f1d0..830341e 100644
--- a/README.md
+++ b/README.md
@@ -1,60 +1,87 @@
# MegaCoreX
-An Arduino core for the new megaAVR series!
-ATmega3208, ATmega4808, ATmega3209 and ATmega4809.
-
-**TODO:**
-* ~~UART pin swap inegraion~~ **DONE! use Serial.swap()**
-* ~~Add printf to print class~~ **DONE! use Serial.printf()**
-* Get rid of nasty compiler warning when compiling a blank sketch (or any sketch really..)
-* Steal 20 MHz accurate timing from MCUdude_corefiles
-* SPI pin swap integration in libraries
-* I2C pin swap integration in libraries
-* Example (library?) for using the 32.768kHz cystal that can be found on Uno Wifi Rev2 and Curiosity Nano 4809
-* Add ArduinoAPI as subtree for easy maintainance (just need to get some PRs such as printf functionality merged first)
-* Readme
- - Need some good intro text at the beginning
- - Minimal setup schematics
-* Proper testing with updated toolchain (I'm experiencing trouble with the 32kB chips)
+An Arduino core for ATmega4809, ATmega4808, ATmega3209, ATmega3208, ATmega1609, ATmega1608, ATmega809 and ATmega808. This megaAVR-0 chip family offers lots of features and peripherals at an incredible price point. The largest one, the ATmega4809 can be found in products like the Arduino Uno WiFi Rev2 and the Arduino Nano Every. Some of their key features include multiple serial ports, SPI and i2c interfaces, built-in programmable logic, up to 16 analog input pins, and an analog comparator with a built-in programmable voltage reference and hysteresis and much more!
+Compared to older AVR families they also have more advanced and accurate internal oscillators which can provide base frequencies of 16 and 20 MHz. These can then be divided down internally to reduce the processor speed and power consumption. This means in most applications an external clock isn't necessary anymore. You can read more about clocks and clock frequencies in the [Supported clock frequencies](#supported-clock-frequencies) section.
+
+For programming, these chips use a UPDI programming interface. This is a bi-directional single wire interface and requires a programmer that supports UPDI. If you rather prefer uploading using a USB to serial adapter there is an option to use the Optiboot bootloader. Read more about UPDI and bootloaders in the [Programming](#programming) section below.
+
+#### UPDI programmers
+If you're looking for well-designed, reliable UPDI programmers that also acts as a USB to serial adapters, check out the [microUPDI](https://www.tindie.com/products/MCUdude/microupdi-programmer/) and the [SerialUPDI](https://www.tindie.com/products/mcudude/serialupdi-programmer/) programmers I sell on [Tindie](https://www.tindie.com/stores/mcudude/)!
+They're small programmers with excellent software support, and can be used with Arduino IDE or PlatformIO. The SerialUPDI programmer comes fully assembled (except for the 6-pin programming connector), but the microUPDI needs to be soldered to an Arduino Pro Micro board.
+
+| [microUPDI](https://www.tindie.com/products/MCUdude/microupdi-programmer/) | [SerialUPDI](https://www.tindie.com/products/mcudude/serialupdi-programmer/) | Pinout |
+|----------------------------------------------------------------------------|------------------------------------------------------------------------------|----------------------------------------------------------|
+|
|
|
|
+|
|
| |
# Table of contents
* [Supported microcontrollers](#supported-microcontrollers)
* [Programming](#programming)
+ - [Using a UPDI programmer](#using-a-updi-programmer)
+ - [SerialUPDI](#serialupdi)
+ - [Using a bootloader](#using-a-bootloader)
* [Supported clock frequencies](#supported-clock-frequencies)
* [BOD option](#bod-option)
+* [EEPROM retain option](#eeprom-option)
* [Reset pin](#reset-pin)
+* [Printf support](#printf-support)
+* [Fast IO](#fast-io)
+* [Flexible PWM setup and routing](#flexible-pwm-setup-and-routing)
+* [Pin macros](#pin-macros)
+* [Write to own flash](#write-to-own-flash)
+* [Memory-mapped flash](#memory-mapped-flash)
+* [Identifying MegaCoreX](#identifying-megacorex)
+* [Timer used for millis and micros](#timer-used-for-millis-and-micros)
* [Pinout](#pinout)
+* [Hardware features](#hardware-features)
+ - [PWM output](#pwm-output)
+ - [Configurable Custom Logic (CCL)](#configurable-custom-logic-ccl)
+ - [Analog Comparator (AC)](#analog-comparator-ac)
+ - [Event System (EVSYS)](#event-system-evsys)
+ - [Peripheral pin swapping](#peripheral-pin-swapping)
* [How to install](#how-to-install)
- [Boards Manager Installation](#boards-manager-installation)
- [Manual Installation](#manual-installation)
+ - [PlatformIO](#platformio)
+* [Minimal setup](#minimal-setup)
* [Getting your hardware working](#getting-your-hardware-working)
- [Arduino Uno WiFi Rev2](#arduino-uno-wifi-rev2)
+ - [Arduino Nano Every](#arduino-nano-every)
+ - [Nano 4808](#nano-4808)
- [Curiosity Nano](#curiosity-nano)
- [AVR-IOT-WG](#avr-iot-wg)
- [4809 Xplained Pro](#atmega4809-xplained-pro)
+
## Supported microcontrollers
-| | ATmega4809 | ATmega4808 | ATmega3209 | ATmega3208 |
-|------------------------|------------------|-----------------------------|------------------|-----------------------------|
-| **Flash** | 48 kB | 48 kB | 32 kB | 32 kB |
-| **RAM** | 6 kB | 6 kB | 4 kB | 4 kB |
-| **EEPROM** | 256 B | 256 B | 256 B | 256 B |
-| **Serial ports** | 4 | 3 | 4 | 3 |
-| **IO pins** | 40/41* | 26/27*
23†/24††| 40/41* | 26/27*
23†/24††|
-| **Available packages** | TQFP48
QFN48 | TQFP32
QFN32
SSOP28 | TQFP48
QFN48 | TQFP32
QFN32
SSOP28 |
+| | Mega4809 | Mega4808 | Mega3209 | Mega3208 | Mega1609 | Mega1608 | Mega809 | Mega808 |
+|------------------|----------------------------|-----------------------------------|-------------------|-----------------------------------|-------------------|-----------------------------------|-------------------|-----------------------------------|
+| **Flash** | 48 kiB | 48 kiB | 32 kiB | 32 kiB | 16 kiB | 16 kiB | 8 kiB | 8 kiB |
+| **RAM** | 6 kiB | 6 kiB | 4 kiB | 4 kiB | 2 kiB | 2 kiB | 1 kiB | 1 kiB |
+| **EEPROM** | 256 B +
64 B†| 256 B +
64 B†| 256 B +
64 B†| 256 B +
64 B†| 256 B +
64 B†| 256 B +
64 B†| 256 B +
64 B†| 256 B +
64 B†|
+| **Serial ports** | 4 | 3 | 4 | 3 | 4 | 3 | 4 | 3 |
+| **IO pins** | 41
33*** | 27*
24** | 41 | 27*
24** | 41 | 27*
24** | 41 | 27*
24** |
+| **Packages** | TQFP48
QFN48
DIP40 | TQFP32
QFN32
SSOP28 | TQFP48
QFN48 | TQFP32
QFN32
SSOP28 | TQFP48
QFN48 | TQFP32
QFN32
SSOP28 | TQFP48
QFN48 | TQFP32
QFN32
SSOP28 |
-* Physical reset pin is disabled
-†SSOP28 package
-††SSOP28 package and reset disabled
+†64 bytes of USERROW, accessible from address 256 to 319 using the EEPROM.h library
+* TQFP32/QFN32 package
+** SSOP28 package
+*** DIP40 package
## Programming
-Programming must be done with a UPDI compatible programmer, such as the JTAGICE 3 or any of the new EDBG chips that can be found on newer AVR explained and curoisity boards.
+### Using a UPDI programmer
+Programming must be done with a UPDI compatible programmer, such as the [microUPDI](https://github.com/MCUdude/microUPDI), [JTAG2UPDI](https://github.com/ElTangas/jtag2updi) SerialUPDI or an official Atmel/Microchip UPDI compatible programmer.
-Unlike the Arduino UNO WiFi Rev2 boards package MegaCoreX does not auto detect the programmer you're using. You'll have to select the correct programmer in the *Programmers*. If you're using an Arduino Uno Wifi Rev2 board, a Curiosity Nano or an Xplained pro board you'll have to choose mEDBG, nEDBG or EDBG.
+Unlike the *Arduino megaAVR boards* package, MegaCoreX does not auto-detect the programmer you're using. You'll have to select the correct programmer in the *Programmers* menu.
+#### SerialUPDI
+SerialUPDI is a programmer that utilize a simple serial connection. It uses a USB serial adapter which can be turned into a UPDI programmer by adding a few passive components. You can read more about the details on how the SerualUPDI works [here](https://github.com/SpenceKonde/AVR-Guidance/blob/master/UPDI/jtag2updi.md).
+
+### Using a bootloader
+Programming can also be done using the [Optiboot bootloader](https://github.com/optiboot/Optiboot). It is available for all megaAVR-0 chips and can be used with all hardware serial ports including alternative pin positions. Simply select what UART number to use, default/alternative pin position and click "Burn bootloader". The bootloader will flash an LED connected to PA7 (digital pin 7 on most pinouts) twice when a hardware reset occurs. The upload speed is 115200 baud. Note that that the reset pin cannot be used as a GPIO when using a bootloader. It doesn't matter if you have set the reset pin as GPIO in the tools menu or not; the bootloader option will override this setting.
## Supported clock frequencies
MegaCoreX lets you choose what clock frequency you want to run your microcontroller at.
@@ -63,20 +90,30 @@ MegaCoreX lets you choose what clock frequency you want to run your microcontrol
|-----------|---------------------|--------------------------|
| 20 MHz | Internal oscillator | |
| 16 MHz | Internal oscillator | **Default option** |
+| 10 MHz | Internal oscillator | Derived from 20 MHz osc. |
| 8 MHz | Internal oscillator | Derived from 16 MHz osc. |
+| 5 MHz | Internal oscillator | Derived from 20 MHz osc. |
| 4 MHz | Internal oscillator | Derived from 16 MHz osc. |
| 2 MHz | Internal oscillator | Derived from 16 MHz osc. |
| 1 MHz | Internal oscillator | Derived from 16 MHz osc. |
+| 20 MHz | External clock | |
+| 16 MHz | External clock | |
+| 12 MHz | External clock | |
+| 8 MHz | External clock | |
+| 1 MHz | External clock | |
+
+Note that unlike other AVRs **none of these chips can drive an external crystal or resonator**. If you need an external oscillator it has to be one with a driven clock output.
+The microcontroller will freeze if the external clock suddenly drops out. If not present on boot, it will automatically choose the 16 MHz internal oscillator instead.
-Note that unlike other AVRs none of these chips are able to drive an external crystal or resonator. If you need an external oscillator it has to be one with a driven clock output.
+Another thing to watch out for is the lowest possible baudrates when running at 16 or 20 MHz. At 16 MHz the lowest baud rate is 1200 baud. When running at 20 MHz the lowest is 2400 baud. This is caused by the way the internal baud rate generator works. If you need lower baud rates you'll either have to reduce the main clock speed or use the software serial library instead.
## BOD option
-Brown out detection, or BOD for short lets the microcontroller sense the input voltage and shut down if the voltage goes below the brown out setting. Below is a table that shows the available BOD options:
+Brownout detection or BOD for short lets the microcontroller sense the input voltage and shut down if the voltage goes below the brownout setting. Below is a table that shows the available BOD options:
-| |
+| BOD threshold |
|--------------------------------|
-| 4.2 V |
+| 4.3 V |
| 4.0 V |
| 3.7 V |
| 3.3 V |
@@ -87,55 +124,241 @@ Brown out detection, or BOD for short lets the microcontroller sense the input v
| Disabled |
+## EEPROM option
+If you want the EEPROM to be erased every time you burn the bootloader or upload using a programmer, you can turn off this option. A UPDI programmer is needed to enable or disable EEPROM retain. Note that when uploading using a bootloader, the EEPROM will always be retained.
+
+
## Reset pin
-None of the megaAVR-0 microcontrollers needs the reset line in order to be reprogrammed over the UPDI interface. This means that the reset pin can be used as a GPIO pin instead! There's no need for a high voltage programmer in order to turn that pin into a reset pin again either. If you have a development board you can instead use the reset button as a general purpose button for your project.
+None of the megaAVR-0 microcontrollers needs the reset line to be reprogrammed over the UPDI interface. This means that the reset pin can be used as a GPIO pin instead! There's no need for a high voltage programmer to turn that pin into a reset pin again either. If you have a development board you can instead use the reset button as a general-purpose button for your project. Note that the reset pin cannot be usd as a GPIO when using a bootloader.
+
+
+## Printf support
+Unlike the official Arduino core, MegaCoreX has printf support out of the box. If you're not familiar with printf you should probably [read this first](https://www.tutorialspoint.com/c_standard_library/c_function_printf.htm). It's added to the Print class and will work with all libraries that inherit Print. Printf is a standard C function that lets you format text much easier than using Arduino's built-in print and println.
+
+[**See the extended API documentation for more information!**](https://github.com/MCUdude/MegaCoreX/tree/master/Extended-API.md#printf-support)
+
+
+## Fast IO
+For timing critical applications the standard `digitalRead()` and `digitalWrite()` functions may be too slow. To solve this, MegaCoreX also incorporates `digitalReadFast(myPin)` and `digitalWriteFast(mypin, state)` which compiles down to a single instruction.
+
+[**See the extended API documentation for more information!**](https://github.com/MCUdude/MegaCoreX/tree/master/Extended-API.md#fast-io)
+
+
+## Flexible PWM setup and routing
+
+The various pinout this core provides are optimized to expose as many features on the available IO pins as possible. This is great where you want to have as many options as possible. For instance, I've tried my best to route various peripherals around so they don't share the same pins as other, frequencly used peripherals.
+By default, PWM pins can't be moved around using the Arduino framework. And the megaAVR-0 family of chips only allows you to route a PWM output to a few pin options. To overcome this limitation and provide greater flexibility, I've added a few functions that makes PWM setup and routing much easier! Here's an example of how you would re-route the PWM output from timer TCB0 to a different pin:
+
+```c
+// Route timer TCB0 PWM output to pin PF4 and set the duty cycle to 50% (128/255)
+pwmWrite(TCB_0, 128, ROUTE_TCB0_PF4);
+// Set the timer TCB0 duty cycle to 30% but leave the routing as is
+pwmWrite(TCB_0, 76);
+```
+
+[**See the PWM section in the extended API documentation for more information!**](https://github.com/MCUdude/MegaCoreX/tree/master/Extended-API.md#pwmwrite---flexible-pwm-routing)
+
+
+## Pin macros
+Note that you don't have to use the digital pin numbers to refer to the pins. You can also use some predefined macros that map "Arduino pins" to the port and port number.
+Note that all my Arduino cores have these macros if you prefer to use these rather than the default Arduino pin number.
+
+```c++
+// Use PIN_PA0 macro to refer to pin PA0 (Arduino pin 0)
+digitalWrite(PIN_PA0, HIGH);
+
+// Results in the exact same compiled code
+digitalWrite(0, HIGH);
+```
+
+
+## Write to own flash
+As an alternative for UPDI, MegaCoreX uses Optiboot Flash, a bootloader that supports flash writing within the running application, thanks to the work of [@majekw](https://github.com/majekw).
+This means that content from e.g. a sensor can be stored in the flash memory directly without the need of external memory. Flash memory is much faster than EEPROM, and can handle at least 10 000 write cycles before wear becomes an issue.
+For more information on how it works and how you can use this in you own application, check out the [Serial_read_write](https://github.com/MCUdude/MegaCoreX/blob/master/megaavr/libraries/Optiboot_flasher/examples/Serial_read_write/Serial_read_write.ino) for a simple proof-of-concept demo, and
+[Flash_put_get](https://github.com/MCUdude/MegaCoreX/blob/master/megaavr/libraries/Optiboot_flasher/examples/Flash_put_get/Flash_put_get.ino) + [Flash_iterate](https://github.com/MCUdude/MegaCoreX/blob/master/megaavr/libraries/Optiboot_flasher/examples/Flash_iterate/Flash_iterate.ino) for useful examples on how you can store strings, structs and variables to flash and retrieve then afterwards.
+
+
+## Memory-mapped flash
+Unlike classic AVRs, the flash memory on these parts is within the same address space as the main memory. This means that functions like `pgm_read_byte()` and `pgm_read_word()` is not needed to read directly from flash. Because of this, the compiler automatically puts any variable declared const into PROGMEM, and accesses it appropriately - you no longer need to explicitly declare them as PROGMEM!
+This also includes quoted strings, which means that the string in `Serial.print("Hello World");` won't consume any RAM. This means that the `F()` macro is not needed when working with MegaCoreX.
+
+If you explicitly declare a variable PROGMEM, you must still use the `pgm_read_byte()/pgm_read_word()` functions, just like on "classic" AVRs. Do note that declaring things PROGMEM or using the `F()` macro works fine, but it is slower and consumes more flash than simply declaring something `const` or omitting the `F()` macro.
+
+
+# Identifying MegaCoreX
+If you're writing code that has MegaCoreX specific code in it, you can identify this core and various pinouts with the list of macros below.
+
+
+| Core specific | Pinout specific | Chip family specific | Chip specific |
+|---------------------|----------------------------------|----------------------|----------------------|
+| `MEGACOREX` | `MEGACOREX_DEFAULT_48PIN_PINOUT` | `__AVR_ATmegax09__` | `__AVR_ATmega4809__` |
+| `MCUDUDE_MEGACOREX` | `MEGACOREX_DEFAULT_40PIN_PINOUT` | `__AVR_ATmegax08__` | `__AVR_ATmega4808__` |
+| | `MEGACOREX_DEFAULT_32PIN_PINOUT` | | `__AVR_ATmega3209__` |
+| | `MEGACOREX_DEFAULT_28PIN_PINOUT` | | `__AVR_ATmega3208__` |
+| | | | `__AVR_ATmega1609__` |
+| | | | `__AVR_ATmega1608__` |
+| | | | `__AVR_ATmega809__` |
+| | | | `__AVR_ATmega808__` |
+
+Usage:
+```c++
+#if defined(MEGACOREX)
+// Code
+#endif
+```
+
+
+# Timer used for millis and micros
+The 28 and 32 pin part have a total of three TCB timers, while the 40 and 48 pin parts have four. In order to create default pinouts with as may PWM output pins as possible, different pinout uses different timers for millis and micros.
+The default timer can be changed by adding `-DMILLIS_USE_TIMERBx` to the platformio.ini build flags, where *x* represents the TCB timer number from 0 to 3. Alternativey, the respective *pins_arduino.h* file can be modified if using Arduino IDE.
+
+| Pinout | Timer used for millis and micros |
+|-----------------|----------------------------------|
+| 48 pin standard | TCB3 |
+| 40 pin standard | TCB2 |
+| 32 pin standard | TCB2 |
+| 28 pin standard | TCB2 |
+| Uno WiFi | TCB3 |
+| Nano Every | TCB3 |
+| Nano Every 4808 | TCB2 |
## Pinout
This core provides several different Arduino pin mappings based on your current hardware
-- **Uno WiFi**: This pinout is 100% compatible with the Arduino Uno WiFi Rev2 hardware. If you have code that's written for the Uno WiFi Rev2 it will work without any modifications if you choose this pinout. Note that this pinout does pin swapping on serial interfaces and PWM pins by default, and some peripherals are renamed to match the original 328P Uno hardware better. Note that this pinout is only available on ATmega3209/ATmega4809.
-- **48 pin standard**: This pinout is much closer to the actual hardware than the Uno WiFi pinout. It will not be compatible with shields or anything like that, but it's much more clean and elegant from a hardware point of view. The only pin swap done by default is the PWM output pins. This is done to prevent them from "colliding" with other peripherals. Note that this pinout is only available on ATmega3209/ATmega4809.
+- **48 pin standard**: This pinout is much closer to the actual hardware than the Uno WiFi pinout. It will not be compatible with shields or anything like that, but it's much cleaner and elegant from a hardware point of view. The only pin swap done by default is the PWM output pins. This is done to prevent them from "colliding" with other peripherals. Note that this pinout is only available on ATmega3209/ATmega4809.
+- **40 pin standard**: This pinout is more or less identical to the 48 pin variant, but with a reduced pin number. Note that this pinout is only available on ATmega4809.
- **32 pin standard**: This is the pinout for the 32 pin version of the ATmega3208/4808. Again, it will not be compatible with shields or anything like that, but it's clean and elegant from a hardware point of view. The only pin swap done by default is the PWM output pins. This is done to prevent them from "colliding" with other peripherals.
-- **28 pin standard**: This is the pinout for the 28 pin version of the ATmega3208/4808. Will not be compatible with shields or anything like that, but it's still clean and elegant from a hardware point of view. Only pin swap done by default is the PWM output pins. This is done to prevent them from "colliding" with other peripherals.
+- **28 pin standard**: This is the pinout for the 28 pin version of the ATmega3208/4808. It will not be compatible with shields or anything like that, but it's still clean and elegant from a hardware point of view. Only pin swap done by default is the PWM output pins. This is done to prevent them from "colliding" with other peripherals.
+- **Uno WiFi**: This pinout is 100% compatible with the Arduino Uno WiFi Rev2 hardware. If you have code that's written for the Uno WiFi Rev2 it will work without any modifications if you choose this pinout. Note that this pinout does pin swapping on serial interfaces and PWM pins by default, and some peripherals are renamed to match the original 328P Uno hardware better. Note that this pinout is only available on ATmega3209/ATmega4809.
+- **Nano Every**: This pinout is 100% compatible with the Arduino Nano Every. If you have code that's written for the Nano Every it will work without any modifications if you choose this pinout. Note that this pinout does pin swapping on serial interfaces and PWM pins by default, and some peripherals are renamed to match the original 328P Uno hardware better. This pinout is only available when ATmega4809 is selected.
+- **Nano Every 4808**: This matches the "official" Thinary Nano Every pinout, and is compatible with the Thinary Nano Every Arduino core. Note that this pinout does pin swapping on serial interfaces and PWM pins by default. This pinout is only available when ATmega4808 is selected.
Please have a look at the pins_arduino.h files for detailed info.
-Click to enlarge:
+Click to enlarge:
+
+| **MegaCoreX ATmega809/1609/3209/4809 pinout** | **MegaCoreX ATmega808/1608/3208/4808 pinout** |
+|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+|

|

|
+
+
+## Hardware features
+Here's some hardware specific features that differ from the older AVR families.
+
+### Interrupt pins
+Unlike older AVRs the megaAVR-0 microcontrollers have fully featured interrupts on every pin.
+Supported states are *RISING*, *FALLING*, *CHANGE*, *HIGH* and *LOW*. This means there's no need to use the `digitalPinToInterrupt` macro. Simply call attachInterrupt like this:
+
+```c
+attachInterrupt(myPin, myInterruptFunction, RISING);
+```
+
+### PWM output
+PWM output, `analogWrite()`, is available for the following pins:
+
+| Pinout | Number of PWM pins | Available PWM pins |
+|-------------------|--------------------|------------------------------------|
+| *28 pin standard* | 8 | 2, 3, 12, 13, 14, 15, 16, 17 |
+| *32 pin standard* | 8 | 2, 3, 12, 13, 14, 15, 16, 17 |
+| *40 pin standard* | 8 | 8, 9, 10, 11, 12, 13, 30, 31 |
+| *48 pin standard* | 9 | 13, 14, 15, 16, 17, 18, 19, 38, 39 |
+| *Uno WiFi* | 6 | 3, 5, 6, 9, 10, 27 |
+| *Nano Every* | 5 | 3, 5, 6, 9, 10 |
+| *Nano Every 4808* | 8 | 4, 5, 14, 15, 16, 17, 22, 23 |
+
+The repeat frequency for the pulses on all PWM outputs can be changed with the new function `analogWriteFrequency(kHz)`, where
+`kHz` values of 1 (default), 4, 8, 16, 32 and 64 are supported. Note that these values are very approximate. The best effort within the constraints of the hardware will be made to match the request.
+
+Note also that tone() will use TCB1, so the corresponding PWM output is not available if it is used.
+
+### Configurable Custom Logic (CCL)
+The megaAVR-0 microcontrollers are equipped with four independent configurable logic blocks that can be used to improve speed and performance. The CCL pins are marked on all pinout diagrams in a dark blue/grey color. The logic blocks can be used independently from each other, connected together or generate an interrupt to the CPU. I've made a [light weight, high-level library](https://github.com/MCUdude/MegaCoreX/tree/master/megaavr/libraries/Logic) for easy integration with the CCL hardware.
-| **MegaCoreX ATmega3209/4809 pinout** | **MegaCoreX ATmega3208/4808 pinout** |
-|-------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
-|
|

|
+### Analog Comparator (AC)
+The megaAVR-0 microcontrollers are equipped with an analog comparator. It compares the voltage levels on two inputs and gives a digital output based on this comparison. The megAVR chip has four positive AC pins and three negative. There's also a configurable internal voltage reference that can be used on the negative comparator pin instead of an external voltage.
+Try out the [Comparator library](https://github.com/MCUdude/MegaCoreX/tree/master/megaavr/libraries/Comparator) for more information, library reference and examples.
+
+### Event System (EVSYS)
+The Event System (EVSYS) enables direct peripheral-to-peripheral signaling. It allows a change in one peripheral (the event generator) to trigger actions in other peripherals (the event users) through event channels, without using the CPU. It is designed to provide short and predictable response times between peripherals, allowing for autonomous peripheral control and interaction, and also for synchronized timing of actions in several peripheral modules. It is thus a powerful tool for reducing the complexity, size, and execution time of the software. Give the [Event library](https://github.com/MCUdude/MegaCoreX/tree/master/megaavr/libraries/Event) a try! Here you'll find documentation and useful library examples.
+
+### Peripheral pin swapping
+The megaAVR-0 microcontrollers support alternative pin assignments for some of their built-in peripherals.
+MegaCoreX currently supports pinswapping the SPI, i2c and UART peripheral pins.
+
+[**See the extended API documentation for more information!**](https://github.com/MCUdude/MegaCoreX/tree/master/Extended-API.md#peripheral-pin-swapping)
## How to install
#### Boards Manager Installation
-*Not yet implemented*
+* Open Arduino IDE.
+* Open the **File > Preferences** menu item.
+* Enter the following URL in **Additional Boards Manager URLs**:
+ ```
+ https://mcudude.github.io/MegaCoreX/package_MCUdude_MegaCoreX_index.json
+ ```
+* Separate the URLs using a comma ( **,** ) if you have more than one URL
+* Open the **Tools > Board > Boards Manager...** menu item.
+* Wait for the platform indexes to finish downloading.
+* Scroll down until you see the **MegaCoreX** entry and click on it.
+* Click **Install**.
+* After installation is complete close the **Boards Manager** window.
#### Manual Installation
Click on the "Download ZIP" button. Extract the ZIP file, and move the extracted folder to the location "**~/Documents/Arduino/hardware**". Create the "hardware" folder if it doesn't exist.
-Open Arduino IDE, and a new category in the boards menu called "MightyCoreX" will show up.
+Open Arduino IDE and a new category in the boards menu called "MightyCoreX" will show up.
+
+#### PlatformIO
+[PlatformIO](http://platformio.org) is an open source ecosystem for IoT development and supports MegaCoreX.
+**See [PlatformIO.md](https://github.com/MCUdude/MegaCoreX/blob/master/PlatformIO.md) for more information.**
+
+
+## Minimal setup
+Here are some simple schematics that show a minimal setup. The straight 6-pin header may in the future be used for serial uploads without having to use a UPDI programmer. As of today, we're still waiting for a stable version of Optiboot.
+Click to enlarge:
+
+| 48-pin *ATmega809/1609/3209/4809* | 40-pin *ATmega4809* | 32-pin *ATmega808/1608/3208/4808* |
+|-------------------------------------------------------|-------------------------------------------------------|-------------------------------------------------------|
+|
|
|
|
## Getting your hardware working
### Arduino Uno WiFi Rev2
-[The Arduino Uno WiFi Rev2](https://store.arduino.cc/usa/arduino-uno-wifi-rev2) is the easiest board out of these to get started with, because it's officially supported by Arduino. It uses an ATmega4809, and recommended pinout is *Uno WiFi*. Printing to the serial monitor on your PC is done by initializing `Serial.begin(baud)`. You'll also have to choose **Atmel mEDBG (ATmega32u4)** as your programmer in order to upload code. For more information about this board please see the product page and its schematic.
+[The Arduino Uno WiFi Rev2](https://store.arduino.cc/arduino-uno-wifi-rev2) is one of the few megaAVR-0 based boards that's officially supported by Arduino. It uses an ATmega4809 and the recommended pinout is *Uno WiFi*. Printing to the serial monitor on your PC is done by initializing `Serial.begin(baud)`. You'll also have to choose **microUPDI/Uno Wifi** as your programmer to upload code. Uno WiFi Rev2 does not support a bootloader, so select *No bootloader* in the tools menu. For more information about this board please see the product page and its schematic.
+
+Click to enlarge:
-Click to enlarge:
-
+
+
+### Arduino Nano Every
+[The Arduino Nano Every](https://store.arduino.cc/arduino-nano-every) is one of the few megaAVR-0 based boards that's officially supported by Arduino. It uses an ATmega4809 and the *only* supported pinout is *Nano Every*. Printing to the serial monitor on your PC is done by initializing `Serial.begin(baud)`. The Nano Every does not support a bootloader, so select *No bootloader* in the tools menu. Burning bootloader or upload using programmer will not work either. However, all fuses are set every time you upload our program. For more information about this board please see the product page and its schematic.
+
+Click to enlarge:
+
+
+
+### Nano 4808
+The Nano 4808, also known as the Thinary Nano 4808 a third-party Arduino compatible board with the Nano form factor. It uses an ATmega4808 and the *only* supported pinout is *Nano 4808*. Printing to the serial monitor on your PC is done by initializing `Serial.begin(baud)`. The Nano 4808 does not support a bootloader, so select *No bootloader* in the tools menu. The on-board JTAG2UPDI programmer is known to be difficult to enter programming mode when printing to the serial monitor. If you're having upload issues, connect a dedicated UPDI programmer to the UPDI pin, select it in the programmers menu and upload using the programmer.
+Click to enlarge:
+
+
### Curiosity Nano
-[The Curiosity Nano](https://www.microchip.com/developmenttools/ProductDetails/DM320115) uses an ATmega4809 but has a different pinout than the Uno Wifi Rev2. Recommended pinout for this board is *48 pin standard*. Use the `LED_BUILTIN` macro to control the onboard LED. Note that UART3 is connected to the nEDBG chip (often refered to as the debug serial port). This means you'll have to use `Serial3.begin(baud)` in order to print to the serial monitor. You'll also have to choose **Atmel nEDBG (ATSAMD21E18)** as your programmer in order to upload code. For more information about this board please refer to the userguide and its schematic.
+[The Curiosity Nano](https://www.microchip.com/developmenttools/ProductDetails/DM320115) uses an ATmega4809 but has a different pinout than the Uno Wifi Rev2. The recommended pinout for this board is *48 pin standard*. The on-board LED is connected t pin PF5 (digital pin 39). Note that UART3 is connected to the nEDBG chip (often referred to as the debug serial port). This means you'll have to use `Serial3.begin(baud)` to print to the serial monitor. You'll also have to choose **Curiosity Nano** as your programmer to upload code. For more information about this board please refer to the user guide and its schematic.
+
+Click to enlarge:
-Click to enlarge:
-
+
### AVR-IOT WG
-[The AVR-IOT WG](https://www.microchip.com/developmenttools/ProductDetails/AC164160) uses the ATmega4808 in a 32 pin package. *32 pin standard* is the correct pinout for this board. Use the `LED_BUILTIN` macro to control the onboard LED marked with *WIFI*. Note that UART2 is connected to the nEDBG chip (often refered to as the debug serial port). This means tou'll have to use `Serial2.begin(baud)` in order to print to the serial monitor. You'll also have to choose **Atmel nEDBG (ATSAMD21E18)** as your programmer in order to upload code. For more information about this board please refer to the userguide and its schematic.
+[The AVR-IOT WG](https://www.microchip.com/developmenttools/ProductDetails/AC164160) uses the ATmega4808 in a 32 pin package. *32 pin standard* is the correct pinout for this board. Note that UART2 is connected to the nEDBG chip (often referred to as the debug serial port). This means you'll have to use `Serial2.begin(baud)` to print to the serial monitor. You'll also have to choose **Curiosity Nano** as your programmer to upload code. For more information about this board please refer to the user guide and its schematic.
-Click to enlarge:
-
+Click to enlarge:
+
+
### ATmega4809 Xplained Pro
-[The ATmega4809 Xplained Pro](https://www.microchip.com/developmenttools/ProductDetails/atmega4809-xpro) uses an ATmega4809. Recommended pinout for this board is *48 pin standard*. Note that the UART1 is connected to the EDBG chip (often refered to as the debug serial port). This means you'll have to use `Serial1.begin(baud)` in order to print to the serial monitor. You'll also have to choose **Atmel EDBG (AT32UC3A4256)** as your programmer in order to upload code. For more information about this board please refer to the userguide and its schematic.
+[The ATmega4809 Xplained Pro](https://www.microchip.com/developmenttools/ProductDetails/atmega4809-xpro) uses an ATmega4809. The recommended pinout for this board is *48 pin standard*. Note that the UART1 is connected to the EDBG chip (often referred to as the debug serial port). This means you'll have to use `Serial1.begin(baud)` to print to the serial monitor. You'll also have to choose **Xplained Pro** as your programmer to upload code. For more information about this board please refer to the user guide and its schematic.
+
+Click to enlarge:
-Click to enlarge:
-
+
diff --git a/megaavr/avrdude.conf b/megaavr/avrdude.conf
deleted file mode 100644
index 1898252..0000000
--- a/megaavr/avrdude.conf
+++ /dev/null
@@ -1,15880 +0,0 @@
-# $Id$ -*- text -*-
-#
-# AVRDUDE Configuration File
-#
-# This file contains configuration data used by AVRDUDE which describes
-# the programming hardware pinouts and also provides part definitions.
-# AVRDUDE's "-C" command line option specifies the location of the
-# configuration file. The "-c" option names the programmer configuration
-# which must match one of the entry's "id" parameter. The "-p" option
-# identifies which part AVRDUDE is going to be programming and must match
-# one of the parts' "id" parameter.
-#
-# DO NOT MODIFY THIS FILE. Modifications will be overwritten the next
-# time a "make install" is run. For user-specific additions, use the
-# "-C +filename" commandline option.
-#
-# Possible entry formats are:
-#
-# programmer
-# parent # optional parent
-# id = [, [, ] ...] ; # are quoted strings
-# desc = ; # quoted string
-# type = ; # programmer type, quoted string
-# # supported programmer types can be listed by "-c ?type"
-# connection_type = parallel | serial | usb
-# baudrate = ; # baudrate for avr910-programmer
-# vcc = [, ... ] ; # pin number(s)
-# buff = [, ... ] ; # pin number(s)
-# reset = ; # pin number
-# sck = ; # pin number
-# mosi = ; # pin number
-# miso = ; # pin number
-# errled = ; # pin number
-# rdyled = ; # pin number
-# pgmled = ; # pin number
-# vfyled = ; # pin number
-# usbvid = ; # USB VID (Vendor ID)
-# usbpid = [, ...] # USB PID (Product ID) (1)
-# usbdev = ; # USB interface or other device info
-# usbvendor = ; # USB Vendor Name
-# usbproduct = ; # USB Product Name
-# usbsn = ; # USB Serial Number
-#
-# To invert a bit, use = ~ , the spaces are important.
-# For a pin list all pins must be inverted.
-# A single pin can be specified as usual = ~ , for lists
-# specify it as follows = ~ ( [, ... ] ) .
-#
-# (1) Not all programmer types can process a list of PIDs.
-# ;
-#
-# part
-# id = ; # quoted string
-# desc = ; # quoted string
-# has_jtag = ; # part has JTAG i/f
-# has_debugwire = ; # part has debugWire i/f
-# has_pdi = ; # part has PDI i/f
-# has_updi = ; # part has UPDI i/f
-# has_tpi = ; # part has TPI i/f
-# devicecode = ; # deprecated, use stk500_devcode
-# stk500_devcode = ; # numeric
-# avr910_devcode = ; # numeric
-# signature = ; # signature bytes
-# usbpid = ; # DFU USB PID
-# chip_erase_delay = ; # micro-seconds
-# reset = dedicated | io;
-# retry_pulse = reset | sck;
-# pgm_enable = ;
-# chip_erase = ;
-# chip_erase_delay = ; # chip erase delay (us)
-# # STK500 parameters (parallel programming IO lines)
-# pagel = ; # pin name in hex, i.e., 0xD7
-# bs2 = ; # pin name in hex, i.e., 0xA0
-# serial = ; # can use serial downloading
-# parallel = ; # can use par. programming
-# # STK500v2 parameters, to be taken from Atmel's XML files
-# timeout = ;
-# stabdelay = ;
-# cmdexedelay = ;
-# synchloops = ;
-# bytedelay = ;
-# pollvalue = ;
-# pollindex = ;
-# predelay = ;
-# postdelay = ;
-# pollmethod = ;
-# mode = ;
-# delay = ;
-# blocksize = ;
-# readsize = ;
-# hvspcmdexedelay = ;
-# # STK500v2 HV programming parameters, from XML
-# pp_controlstack = , , ...; # PP only
-# hvsp_controlstack = , , ...; # HVSP only
-# hventerstabdelay = ;
-# progmodedelay = ; # PP only
-# latchcycles = ;
-# togglevtg = ;
-# poweroffdelay = ;
-# resetdelayms = ;
-# resetdelayus = ;
-# hvleavestabdelay = ;
-# resetdelay = ;
-# synchcycles = ; # HVSP only
-# chiperasepulsewidth = ; # PP only
-# chiperasepolltimeout = ;
-# chiperasetime = ; # HVSP only
-# programfusepulsewidth = ; # PP only
-# programfusepolltimeout = ;
-# programlockpulsewidth = ; # PP only
-# programlockpolltimeout = ;
-# # JTAG ICE mkII parameters, also from XML files
-# allowfullpagebitstream = ;
-# enablepageprogramming = ;
-# idr = ; # IO addr of IDR (OCD) reg.
-# rampz = ; # IO addr of RAMPZ reg.
-# spmcr = ; # mem addr of SPMC[S]R reg.
-# eecr = ; # mem addr of EECR reg.
-# # (only when != 0x3c)
-# is_at90s1200 = ; # AT90S1200 part
-# is_avr32 = ; # AVR32 part
-#
-# memory
-# paged = ; # yes / no
-# size = ; # bytes
-# page_size = ; # bytes
-# num_pages = ; # numeric
-# min_write_delay = ; # micro-seconds
-# max_write_delay = ; # micro-seconds
-# readback_p1 = ; # byte value
-# readback_p2 = ; # byte value
-# pwroff_after_write = ; # yes / no
-# read = ;
-# write = ;
-# read_lo = ;
-# read_hi = ;
-# write_lo = ;
-# write_hi = ;
-# loadpage_lo = ;
-# loadpage_hi = ;
-# writepage = ;
-# ;
-# ;
-#
-# If any of the above parameters are not specified, the default value
-# of 0 is used for numerics or the empty string ("") for string
-# values. If a required parameter is left empty, AVRDUDE will
-# complain.
-#
-# Parts can also inherit parameters from previously defined parts
-# using the following syntax. In this case specified integer and
-# string values override parameter values from the parent part. New
-# memory definitions are added to the definitions inherited from the
-# parent.
-#
-# part parent # quoted string
-# id = ; # quoted string
-#
-# ;
-#
-# NOTES:
-# * 'devicecode' is the device code used by the STK500 (see codes
-# listed below)
-# * Not all memory types will implement all instructions.
-# * AVR Fuse bits and Lock bits are implemented as a type of memory.
-# * Example memory types are:
-# "flash", "eeprom", "fuse", "lfuse" (low fuse), "hfuse" (high
-# fuse), "signature", "calibration", "lock"
-# * The memory type specified on the avrdude command line must match
-# one of the memory types defined for the specified chip.
-# * The pwroff_after_write flag causes avrdude to attempt to
-# power the device off and back on after an unsuccessful write to
-# the affected memory area if VCC programmer pins are defined. If
-# VCC pins are not defined for the programmer, a message
-# indicating that the device needs a power-cycle is printed out.
-# This flag was added to work around a problem with the
-# at90s4433/2333's; see the at90s4433 errata at:
-#
-# http://www.atmel.com/dyn/resources/prod_documents/doc1280.pdf
-#
-# INSTRUCTION FORMATS
-#
-# Instruction formats are specified as a comma seperated list of
-# string values containing information (bit specifiers) about each
-# of the 32 bits of the instruction. Bit specifiers may be one of
-# the following formats:
-#
-# '1' = the bit is always set on input as well as output
-#
-# '0' = the bit is always clear on input as well as output
-#
-# 'x' = the bit is ignored on input and output
-#
-# 'a' = the bit is an address bit, the bit-number matches this bit
-# specifier's position within the current instruction byte
-#
-# 'aN' = the bit is the Nth address bit, bit-number = N, i.e., a12
-# is address bit 12 on input, a0 is address bit 0.
-#
-# 'i' = the bit is an input data bit
-#
-# 'o' = the bit is an output data bit
-#
-# Each instruction must be composed of 32 bit specifiers. The
-# instruction specification closely follows the instruction data
-# provided in Atmel's data sheets for their parts.
-#
-# See below for some examples.
-#
-#
-# The following are STK500 part device codes to use for the
-# "devicecode" field of the part. These came from Atmel's software
-# section avr061.zip which accompanies the application note
-# AVR061 available from:
-#
-# http://www.atmel.com/dyn/resources/prod_documents/doc2525.pdf
-#
-
-#define ATTINY10 0x10 /* the _old_ one that never existed! */
-#define ATTINY11 0x11
-#define ATTINY12 0x12
-#define ATTINY15 0x13
-#define ATTINY13 0x14
-
-#define ATTINY22 0x20
-#define ATTINY26 0x21
-#define ATTINY28 0x22
-#define ATTINY2313 0x23
-
-#define AT90S1200 0x33
-
-#define AT90S2313 0x40
-#define AT90S2323 0x41
-#define AT90S2333 0x42
-#define AT90S2343 0x43
-
-#define AT90S4414 0x50
-#define AT90S4433 0x51
-#define AT90S4434 0x52
-#define ATMEGA48 0x59
-
-#define AT90S8515 0x60
-#define AT90S8535 0x61
-#define AT90C8534 0x62
-#define ATMEGA8515 0x63
-#define ATMEGA8535 0x64
-
-#define ATMEGA8 0x70
-#define ATMEGA88 0x73
-#define ATMEGA168 0x86
-
-#define ATMEGA161 0x80
-#define ATMEGA163 0x81
-#define ATMEGA16 0x82
-#define ATMEGA162 0x83
-#define ATMEGA169 0x84
-
-#define ATMEGA323 0x90
-#define ATMEGA32 0x91
-
-#define ATMEGA64 0xA0
-
-#define ATMEGA103 0xB1
-#define ATMEGA128 0xB2
-#define AT90CAN128 0xB3
-#define AT90CAN64 0xB3
-#define AT90CAN32 0xB3
-
-#define AT86RF401 0xD0
-
-#define AT89START 0xE0
-#define AT89S51 0xE0
-#define AT89S52 0xE1
-
-# The following table lists the devices in the original AVR910
-# appnote:
-# |Device |Signature | Code |
-# +-------+----------+------+
-# |tiny12 | 1E 90 05 | 0x55 |
-# |tiny15 | 1E 90 06 | 0x56 |
-# | | | |
-# | S1200 | 1E 90 01 | 0x13 |
-# | | | |
-# | S2313 | 1E 91 01 | 0x20 |
-# | S2323 | 1E 91 02 | 0x48 |
-# | S2333 | 1E 91 05 | 0x34 |
-# | S2343 | 1E 91 03 | 0x4C |
-# | | | |
-# | S4414 | 1E 92 01 | 0x28 |
-# | S4433 | 1E 92 03 | 0x30 |
-# | S4434 | 1E 92 02 | 0x6C |
-# | | | |
-# | S8515 | 1E 93 01 | 0x38 |
-# | S8535 | 1E 93 03 | 0x68 |
-# | | | |
-# |mega32 | 1E 95 01 | 0x72 |
-# |mega83 | 1E 93 05 | 0x65 |
-# |mega103| 1E 97 01 | 0x41 |
-# |mega161| 1E 94 01 | 0x60 |
-# |mega163| 1E 94 02 | 0x64 |
-
-# Appnote AVR109 also has a table of AVR910 device codes, which
-# lists:
-# dev avr910 signature
-# ATmega8 0x77 0x1E 0x93 0x07
-# ATmega8515 0x3B 0x1E 0x93 0x06
-# ATmega8535 0x6A 0x1E 0x93 0x08
-# ATmega16 0x75 0x1E 0x94 0x03
-# ATmega162 0x63 0x1E 0x94 0x04
-# ATmega163 0x66 0x1E 0x94 0x02
-# ATmega169 0x79 0x1E 0x94 0x05
-# ATmega32 0x7F 0x1E 0x95 0x02
-# ATmega323 0x73 0x1E 0x95 0x01
-# ATmega64 0x46 0x1E 0x96 0x02
-# ATmega128 0x44 0x1E 0x97 0x02
-#
-# These codes refer to "BOOT" device codes which are apparently
-# different than standard device codes, for whatever reasons
-# (often one above the standard code).
-
-# There are several extended versions of AVR910 implementations around
-# in the Internet. These add the following codes (only devices that
-# actually exist are listed):
-
-# ATmega8515 0x3A
-# ATmega128 0x43
-# ATmega64 0x45
-# ATtiny26 0x5E
-# ATmega8535 0x69
-# ATmega32 0x72
-# ATmega16 0x74
-# ATmega8 0x76
-# ATmega169 0x78
-
-#
-# Overall avrdude defaults; suitable for ~/.avrduderc
-#
-default_parallel = "unknown";
-default_serial = "unknown";
-# default_bitclock = 2.5;
-
-# Turn off safemode by default
-#default_safemode = no;
-
-
-#
-# PROGRAMMER DEFINITIONS
-#
-
-# http://wiring.org.co/
-# Basically STK500v2 protocol, with some glue to trigger the
-# bootloader.
-programmer
- id = "wiring";
- desc = "Wiring";
- type = "wiring";
- connection_type = serial;
-;
-
-programmer
- id = "arduino";
- desc = "Arduino";
- type = "arduino";
- connection_type = serial;
-;
-# this will interface with the chips on these programmers:
-#
-# http://real.kiev.ua/old/avreal/en/adapters
-# http://www.amontec.com/jtagkey.shtml, jtagkey-tiny.shtml
-# http://www.olimex.com/dev/arm-usb-ocd.html, arm-usb-tiny.html
-# http://www.ethernut.de/en/hardware/turtelizer/index.html
-# http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html
-# http://dangerousprototypes.com/docs/FT2232_breakout_board
-# http://www.ftdichip.com/Products/Modules/DLPModules.htm,DLP-2232*,DLP-USB1232H
-# http://flashrom.org/FT2232SPI_Programmer
-#
-# The drivers will look for a specific device and use the first one found.
-# If you have mulitple devices, then look for unique information (like SN)
-# And fill that in here.
-#
-# Note that the pin numbers for the main ISP signals (reset, sck,
-# mosi, miso) are fixed and cannot be changed, since they must match
-# the way the Multi-Protocol Synchronous Serial Engine (MPSSE) of
-# these FTDI ICs has been designed.
-
-programmer
- id = "avrftdi";
- desc = "FT2232D based generic programmer";
- type = "avrftdi";
- connection_type = usb;
- usbvid = 0x0403;
- usbpid = 0x6010;
- usbvendor = "";
- usbproduct = "";
- usbdev = "A";
- usbsn = "";
-#ISP-signals - lower ADBUS-Nibble (default)
- reset = 3;
- sck = 0;
- mosi = 1;
- miso = 2;
-#LED SIGNALs - higher ADBUS-Nibble
-# errled = 4;
-# rdyled = 5;
-# pgmled = 6;
-# vfyled = 7;
-#Buffer Signal - ACBUS - Nibble
-# buff = 8;
-;
-# This is an implementation of the above with a buffer IC (74AC244) and
-# 4 LEDs directly attached, all active low.
-programmer
- id = "2232HIO";
- desc = "FT2232H based generic programmer";
- type = "avrftdi";
- connection_type = usb;
- usbvid = 0x0403;
-# Note: This PID is reserved for generic H devices and
-# should be programmed into the EEPROM
-# usbpid = 0x8A48;
- usbpid = 0x6010;
- usbdev = "A";
- usbvendor = "";
- usbproduct = "";
- usbsn = "";
-#ISP-signals
- reset = 3;
- sck = 0;
- mosi = 1;
- miso = 2;
- buff = ~4;
-#LED SIGNALs
- errled = ~ 11;
- rdyled = ~ 14;
- pgmled = ~ 13;
- vfyled = ~ 12;
-;
-
-#The FT4232H can be treated as FT2232H, but it has a different USB
-#device ID of 0x6011.
-programmer parent "avrftdi"
- id = "4232h";
- desc = "FT4232H based generic programmer";
- usbpid = 0x6011;
-;
-
-programmer
- id = "jtagkey";
- desc = "Amontec JTAGKey, JTAGKey-Tiny and JTAGKey2";
- type = "avrftdi";
- connection_type = usb;
- usbvid = 0x0403;
-# Note: This PID is used in all JTAGKey variants
- usbpid = 0xCFF8;
- usbdev = "A";
- usbvendor = "";
- usbproduct = "";
- usbsn = "";
-#ISP-signals => 20 - Pin connector on JTAGKey
- reset = 3; # TMS 7 violet
- sck = 0; # TCK 9 white
- mosi = 1; # TDI 5 green
- miso = 2; # TDO 13 orange
- buff = ~4;
-# VTG VREF 1 brown with red tip
-# GND GND 20 black
-# The colors are on the 20 pin breakout cable
-# from Amontec
-;
-
-# UM232H module from FTDI and Glyn.com.au.
-# See helix.air.net.au for detailed usage information.
-# J1: Connect pin 2 and 3 for USB power.
-# J2: Connect pin 2 and 3 for USB power.
-# J2: Pin 7 is SCK
-# : Pin 8 is MOSI
-# : Pin 9 is MISO
-# : Pin 11 is RST
-# : Pin 6 is ground
-# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get
-# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant.
-programmer
- id = "UM232H";
- desc = "FT232H based module from FTDI and Glyn.com.au";
- type = "avrftdi";
- usbvid = 0x0403;
-# Note: This PID is reserved for generic 232H devices and
-# should be programmed into the EEPROM
- usbpid = 0x6014;
- usbdev = "A";
- usbvendor = "";
- usbproduct = "";
- usbsn = "";
-#ISP-signals
- sck = 0;
- mosi = 1;
- miso = 2;
- reset = 3;
-;
-
-# C232HM module from FTDI and Glyn.com.au.
-# : Orange is SCK
-# : Yellow is MOSI
-# : Green is MISO
-# : Brown is RST
-# : Black is ground
-# Use the -b flag to set the SPI clock rate eg -b 3750000 is the fastest I could get
-# a 16MHz Atmega1280 to program reliably. The 232H is conveniently 5V tolerant.
-programmer
- id = "C232HM";
- desc = "FT232H based module from FTDI and Glyn.com.au";
- type = "avrftdi";
- usbvid = 0x0403;
-# Note: This PID is reserved for generic 232H devices and
-# should be programmed into the EEPROM
- usbpid = 0x6014;
- usbdev = "A";
- usbvendor = "";
- usbproduct = "";
- usbsn = "";
-#ISP-signals
- sck = 0;
- mosi = 1;
- miso = 2;
- reset = 3;
-;
-
-
-# On the adapter you can read "O-Link". On the PCB is printed "OpenJTAG v3.1"
-# You can find it as "OpenJTAG ARM JTAG USB" in the internet.
-# (But there are also several projects called Open JTAG, eg.
-# http://www.openjtag.org, which are completely different.)
-# http://www.100ask.net/shop/english.html (website seems to be outdated)
-# http://item.taobao.com/item.htm?id=1559277013
-# http://www.micro4you.com/store/openjtag-arm-jtag-usb.html (schematics!)
-# some other sources which call it O-Link
-# http://www.andahammer.com/olink/
-# http://www.developmentboard.net/31-o-link-debugger.html
-# http://armwerks.com/catalog/o-link-debugger-copy/
-# or just have a look at ebay ...
-# It is basically the same entry as jtagkey with different usb ids.
-programmer parent "jtagkey"
- id = "o-link";
- desc = "O-Link, OpenJTAG from www.100ask.net";
- usbvid = 0x1457;
- usbpid = 0x5118;
- usbvendor = "www.100ask.net";
- usbproduct = "USB<=>JTAG&RS232";
-;
-
-# http://wiki.openmoko.org/wiki/Debug_Board_v3
-programmer
- id = "openmoko";
- desc = "Openmoko debug board (v3)";
- type = "avrftdi";
- usbvid = 0x1457;
- usbpid = 0x5118;
- usbdev = "A";
- usbvendor = "";
- usbproduct = "";
- usbsn = "";
- reset = 3; # TMS 7
- sck = 0; # TCK 9
- mosi = 1; # TDI 5
- miso = 2; # TDO 13
-;
-
-# Only Rev. A boards.
-# Schematic and user manual: http://www.cs.put.poznan.pl/wswitala/download/pdf/811EVBK.pdf
-programmer
- id = "lm3s811";
- desc = "Luminary Micro LM3S811 Eval Board (Rev. A)";
- type = "avrftdi";
- connection_type = usb;
- usbvid = 0x0403;
- usbpid = 0xbcd9;
- usbvendor = "LMI";
- usbproduct = "LM3S811 Evaluation Board";
- usbdev = "A";
- usbsn = "";
-#ISP-signals - lower ACBUS-Nibble (default)
- reset = 3;
- sck = 0;
- mosi = 1;
- miso = 2;
-# Enable correct buffers
- buff = 7;
-;
-
-# submitted as bug #46020
-programmer
- id = "tumpa";
- desc = "TIAO USB Multi-Protocol Adapter";
- type = "avrftdi";
- connection_type = usb;
- usbvid = 0x0403;
- usbpid = 0x8A98;
- usbdev = "A";
- usbvendor = "TIAO";
- usbproduct = "";
- usbsn = "";
- sck = 0; # TCK 9
- mosi = 1; # TDI 5
- miso = 2; # TDO 13
- reset = 3; # TMS 7
-;
-
-programmer
- id = "avrisp";
- desc = "Atmel AVR ISP";
- type = "stk500";
- connection_type = serial;
-;
-
-programmer
- id = "avrispv2";
- desc = "Atmel AVR ISP V2";
- type = "stk500v2";
- connection_type = serial;
-;
-
-programmer
- id = "avrispmkII";
- desc = "Atmel AVR ISP mkII";
- type = "stk500v2";
- connection_type = usb;
-;
-
-programmer parent "avrispmkII"
- id = "avrisp2";
-;
-
-programmer
- id = "buspirate";
- desc = "The Bus Pirate";
- type = "buspirate";
- connection_type = serial;
-;
-
-programmer
- id = "buspirate_bb";
- desc = "The Bus Pirate (bitbang interface, supports TPI)";
- type = "buspirate_bb";
- connection_type = serial;
- # pins are bits in bitbang byte (numbers are 87654321)
- # 1|POWER|PULLUP|AUX|MOSI|CLK|MISO|CS
- reset = 1;
- sck = 3;
- mosi = 4;
- miso = 2;
- #vcc = 7; This is internally set independent of this setting.
-;
-
-# This is supposed to be the "default" STK500 entry.
-# Attempts to select the correct firmware version
-# by probing for it. Better use one of the entries
-# below instead.
-programmer
- id = "stk500";
- desc = "Atmel STK500";
- type = "stk500generic";
- connection_type = serial;
-;
-
-programmer
- id = "stk500v1";
- desc = "Atmel STK500 Version 1.x firmware";
- type = "stk500";
- connection_type = serial;
-;
-
-programmer
- id = "mib510";
- desc = "Crossbow MIB510 programming board";
- type = "stk500";
- connection_type = serial;
-;
-
-programmer
- id = "stk500v2";
- desc = "Atmel STK500 Version 2.x firmware";
- type = "stk500v2";
- connection_type = serial;
-;
-
-programmer
- id = "stk500pp";
- desc = "Atmel STK500 V2 in parallel programming mode";
- type = "stk500pp";
- connection_type = serial;
-;
-
-programmer
- id = "stk500hvsp";
- desc = "Atmel STK500 V2 in high-voltage serial programming mode";
- type = "stk500hvsp";
- connection_type = serial;
-;
-
-programmer
- id = "stk600";
- desc = "Atmel STK600";
- type = "stk600";
- connection_type = usb;
-;
-
-programmer
- id = "stk600pp";
- desc = "Atmel STK600 in parallel programming mode";
- type = "stk600pp";
- connection_type = usb;
-;
-
-programmer
- id = "stk600hvsp";
- desc = "Atmel STK600 in high-voltage serial programming mode";
- type = "stk600hvsp";
- connection_type = usb;
-;
-
-programmer
- id = "avr910";
- desc = "Atmel Low Cost Serial Programmer";
- type = "avr910";
- connection_type = serial;
-;
-
-programmer
- id = "ft245r";
- desc = "FT245R Synchronous BitBang";
- type = "ftdi_syncbb";
- connection_type = usb;
- miso = 1; # D1
- sck = 0; # D0
- mosi = 2; # D2
- reset = 4; # D4
-;
-
-programmer
- id = "ft232r";
- desc = "FT232R Synchronous BitBang";
- type = "ftdi_syncbb";
- connection_type = usb;
- miso = 1; # RxD
- sck = 0; # TxD
- mosi = 2; # RTS
- reset = 4; # DTR
-;
-
-# see http://www.bitwizard.nl/wiki/index.php/FTDI_ATmega
-programmer
- id = "bwmega";
- desc = "BitWizard ftdi_atmega builtin programmer";
- type = "ftdi_syncbb";
- connection_type = usb;
- miso = 5; # DSR
- sck = 6; # DCD
- mosi = 3; # CTS
- reset = 7; # RI
-;
-
-# see http://www.geocities.jp/arduino_diecimila/bootloader/index_en.html
-# Note: pins are numbered from 1!
-programmer
- id = "arduino-ft232r";
- desc = "Arduino: FT232R connected to ISP";
- type = "ftdi_syncbb";
- connection_type = usb;
- miso = 3; # CTS X3(1)
- sck = 5; # DSR X3(2)
- mosi = 6; # DCD X3(3)
- reset = 7; # RI X3(4)
-;
-
-# website mentioned above uses this id
-programmer parent "arduino-ft232r"
- id = "diecimila";
- desc = "alias for arduino-ft232r";
-;
-
-# There is a ATmega328P kit PCB called "uncompatino".
-# This board allows ISP via its on-board FT232R.
-# This is designed like Arduino Duemilanove but has no standard ICPS header.
-# Its 4 pairs of pins are shorted to enable ftdi_syncbb.
-# http://akizukidenshi.com/catalog/g/gP-07487/
-# http://akizukidenshi.com/download/ds/akizuki/k6096_manual_20130816.pdf
-programmer
- id = "uncompatino";
- desc = "uncompatino with all pairs of pins shorted";
- type = "ftdi_syncbb";
- connection_type = usb;
- miso = 3; # cts
- sck = 5; # dsr
- mosi = 6; # dcd
- reset = 7; # ri
-;
-
-# FTDI USB to serial cable TTL-232R-5V with a custom adapter for ICSP
-# http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm
-# http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf
-# For ICSP pinout see for example http://www.atmel.com/images/doc2562.pdf
-# (Figure 1. ISP6PIN header pinout and Table 1. Connections required for ISP ...)
-# TTL-232R GND 1 Black -> ICPS GND (pin 6)
-# TTL-232R CTS 2 Brown -> ICPS MOSI (pin 4)
-# TTL-232R VCC 3 Red -> ICPS VCC (pin 2)
-# TTL-232R TXD 4 Orange -> ICPS RESET (pin 5)
-# TTL-232R RXD 5 Yellow -> ICPS SCK (pin 3)
-# TTL-232R RTS 6 Green -> ICPS MISO (pin 1)
-# Except for VCC and GND, you can connect arbitual pairs as long as
-# the following table is adjusted.
-programmer
- id = "ttl232r";
- desc = "FTDI TTL232R-5V with ICSP adapter";
- type = "ftdi_syncbb";
- connection_type = usb;
- miso = 2; # rts
- sck = 1; # rxd
- mosi = 3; # cts
- reset = 0; # txd
-;
-
-programmer
- id = "usbasp";
- desc = "USBasp, http://www.fischl.de/usbasp/";
- type = "usbasp";
- connection_type = usb;
- usbvid = 0x16C0; # VOTI
- usbpid = 0x05DC; # Obdev's free shared PID
- usbvendor = "www.fischl.de";
- usbproduct = "USBasp";
-
- # following variants are autodetected for id "usbasp"
-
- # original usbasp from fischl.de
- # see above "usbasp"
-
- # old usbasp from fischl.de
- #usbvid = 0x03EB; # ATMEL
- #usbpid = 0xC7B4; # (unoffical) USBasp
- #usbvendor = "www.fischl.de";
- #usbproduct = "USBasp";
-
- # NIBObee (only if -P nibobee is given on command line)
- # see below "nibobee"
-;
-
-programmer
- id = "nibobee";
- desc = "NIBObee";
- type = "usbasp";
- connection_type = usb;
- usbvid = 0x16C0; # VOTI
- usbpid = 0x092F; # NIBObee PID
- usbvendor = "www.nicai-systems.com";
- usbproduct = "NIBObee";
-;
-
-programmer
- id = "usbasp-clone";
- desc = "Any usbasp clone with correct VID/PID";
- type = "usbasp";
- connection_type = usb;
- usbvid = 0x16C0; # VOTI
- usbpid = 0x05DC; # Obdev's free shared PID
- #usbvendor = "";
- #usbproduct = "";
-;
-
-# USBtiny can also be used for TPI programming.
-# In that case, a resistor of 1 kOhm is needed between MISO and MOSI
-# pins of the connector, and MISO (pin 1 of the 6-pin connector)
-# connects to TPIDATA.
-programmer
- id = "usbtiny";
- desc = "USBtiny simple USB programmer, https://learn.adafruit.com/usbtinyisp";
- type = "usbtiny";
- connection_type = usb;
- usbvid = 0x1781;
- usbpid = 0x0c9f;
-;
-
-# commercial version of USBtiny, using a separate VID/PID
-programmer
- id = "ehajo-isp";
- desc = "avr-isp-programmer from eHaJo, http://www.eHaJo.de";
- type = "usbtiny";
- connection_type = usb;
- usbvid = 0x16D0;
- usbpid = 0x0BA5;
-;
-
-programmer
- id = "arduinoisp";
- desc = "Arduino ISP Programmer";
- type = "usbtiny";
- connection_type = usb;
- usbvid = 0x2341;
- usbpid = 0x0049;
-;
-
-programmer
- id = "arduinoisporg";
- desc = "Arduino ISP Programmer";
- type = "usbtiny";
- connection_type = usb;
- usbvid = 0x2A03;
- usbpid = 0x0049;
-;
-
-programmer
- id = "butterfly";
- desc = "Atmel Butterfly Development Board";
- type = "butterfly";
- connection_type = serial;
-;
-
-programmer
- id = "avr109";
- desc = "Atmel AppNote AVR109 Boot Loader";
- type = "butterfly";
- connection_type = serial;
-;
-
-programmer
- id = "avr911";
- desc = "Atmel AppNote AVR911 AVROSP";
- type = "butterfly";
- connection_type = serial;
-;
-
-# suggested in http://forum.mikrokopter.de/topic-post48317.html
-programmer
- id = "mkbutterfly";
- desc = "Mikrokopter.de Butterfly";
- type = "butterfly_mk";
- connection_type = serial;
-;
-
-programmer parent "mkbutterfly"
- id = "butterfly_mk";
-;
-
-programmer
- id = "jtagmkI";
- desc = "Atmel JTAG ICE (mkI)";
- baudrate = 115200; # default is 115200
- type = "jtagmki";
- connection_type = serial;
-;
-
-# easier to type
-programmer parent "jtagmkI"
- id = "jtag1";
-;
-
-# easier to type
-programmer parent "jtag1"
- id = "jtag1slow";
- baudrate = 19200;
-;
-
-# The JTAG ICE mkII has both, serial and USB connectivity. As it is
-# mostly used through USB these days (AVR Studio 5 only supporting it
-# that way), we make connection_type = usb the default. Users are
-# still free to use a serial port with the -P option.
-
-programmer
- id = "jtagmkII";
- desc = "Atmel JTAG ICE mkII";
- baudrate = 19200; # default is 19200
- type = "jtagmkii";
- connection_type = usb;
-;
-
-# easier to type
-programmer parent "jtagmkII"
- id = "jtag2slow";
-;
-
-# JTAG ICE mkII @ 115200 Bd
-programmer parent "jtag2slow"
- id = "jtag2fast";
- baudrate = 115200;
-;
-
-# make the fast one the default, people will love that
-programmer parent "jtag2fast"
- id = "jtag2";
-;
-
-# JTAG ICE mkII in ISP mode
-programmer
- id = "jtag2isp";
- desc = "Atmel JTAG ICE mkII in ISP mode";
- baudrate = 115200;
- type = "jtagmkii_isp";
- connection_type = usb;
-;
-
-# JTAG ICE mkII in debugWire mode
-programmer
- id = "jtag2dw";
- desc = "Atmel JTAG ICE mkII in debugWire mode";
- baudrate = 115200;
- type = "jtagmkii_dw";
- connection_type = usb;
-;
-
-# JTAG ICE mkII in AVR32 mode
-programmer
- id = "jtagmkII_avr32";
- desc = "Atmel JTAG ICE mkII im AVR32 mode";
- baudrate = 115200;
- type = "jtagmkii_avr32";
- connection_type = usb;
-;
-
-# JTAG ICE mkII in AVR32 mode
-programmer
- id = "jtag2avr32";
- desc = "Atmel JTAG ICE mkII im AVR32 mode";
- baudrate = 115200;
- type = "jtagmkii_avr32";
- connection_type = usb;
-;
-
-# JTAG ICE mkII in PDI mode
-programmer
- id = "jtag2pdi";
- desc = "Atmel JTAG ICE mkII PDI mode";
- baudrate = 115200;
- type = "jtagmkii_pdi";
- connection_type = usb;
-;
-
-# AVR Dragon in JTAG mode
-programmer
- id = "dragon_jtag";
- desc = "Atmel AVR Dragon in JTAG mode";
- baudrate = 115200;
- type = "dragon_jtag";
- connection_type = usb;
-;
-
-# AVR Dragon in ISP mode
-programmer
- id = "dragon_isp";
- desc = "Atmel AVR Dragon in ISP mode";
- baudrate = 115200;
- type = "dragon_isp";
- connection_type = usb;
-;
-
-# AVR Dragon in PP mode
-programmer
- id = "dragon_pp";
- desc = "Atmel AVR Dragon in PP mode";
- baudrate = 115200;
- type = "dragon_pp";
- connection_type = usb;
-;
-
-# AVR Dragon in HVSP mode
-programmer
- id = "dragon_hvsp";
- desc = "Atmel AVR Dragon in HVSP mode";
- baudrate = 115200;
- type = "dragon_hvsp";
- connection_type = usb;
-;
-
-# AVR Dragon in debugWire mode
-programmer
- id = "dragon_dw";
- desc = "Atmel AVR Dragon in debugWire mode";
- baudrate = 115200;
- type = "dragon_dw";
- connection_type = usb;
-;
-
-# AVR Dragon in PDI mode
-programmer
- id = "dragon_pdi";
- desc = "Atmel AVR Dragon in PDI mode";
- baudrate = 115200;
- type = "dragon_pdi";
- connection_type = usb;
-;
-
-programmer
- id = "jtag3";
- desc = "Atmel AVR JTAGICE3 in JTAG mode";
- type = "jtagice3";
- connection_type = usb;
- usbpid = 0x2110, 0x2140;
-;
-
-programmer
- id = "jtag3pdi";
- desc = "Atmel AVR JTAGICE3 in PDI mode";
- type = "jtagice3_pdi";
- connection_type = usb;
- usbpid = 0x2110, 0x2140;
-;
-
-programmer
- id = "jtag3dw";
- desc = "Atmel AVR JTAGICE3 in debugWIRE mode";
- type = "jtagice3_dw";
- connection_type = usb;
- usbpid = 0x2110, 0x2140;
-;
-
-programmer
- id = "jtag3isp";
- desc = "Atmel AVR JTAGICE3 in ISP mode";
- type = "jtagice3_isp";
- connection_type = usb;
- usbpid = 0x2110, 0x2140;
-;
-
-programmer
- id = "xplainedpro";
- desc = "Atmel AVR XplainedPro in JTAG mode";
- type = "jtagice3";
- connection_type = usb;
- usbpid = 0x2111;
-;
-
-programmer
- id = "xplainedpro_updi";
- desc = "Atmel AVR XplainedPro in UPDI mode";
- type = "jtagice3_updi";
- connection_type = usb;
- usbpid = 0x2111;
-;
-
-programmer
- id = "xplainedmini";
- desc = "Atmel AVR XplainedMini in ISP mode";
- type = "jtagice3_isp";
- connection_type = usb;
- usbpid = 0x2145;
-;
-
-programmer
- id = "xplainedmini_dw";
- desc = "Atmel AVR XplainedMini in debugWIRE mode";
- type = "jtagice3_dw";
- connection_type = usb;
- usbpid = 0x2145;
-;
-
-programmer
- id = "xplainedmini_updi";
- desc = "Atmel AVR XplainedMini in UPDI mode";
- type = "jtagice3_updi";
- connection_type = usb;
- usbpid = 0x2145;
-;
-
-programmer
- id = "curiosity_updi";
- desc = "Curiosity in UPDI mode";
- type = "jtagice3_updi";
- connection_type = usb;
- usbpid = 0x2175;
-;
-
-programmer
- id = "atmelice";
- desc = "Atmel-ICE (ARM/AVR) in JTAG mode";
- type = "jtagice3";
- connection_type = usb;
- usbpid = 0x2141;
-;
-
-programmer
- id = "atmelice_pdi";
- desc = "Atmel-ICE (ARM/AVR) in PDI mode";
- type = "jtagice3_pdi";
- connection_type = usb;
- usbpid = 0x2141;
-;
-
-programmer
- id = "atmelice_updi";
- desc = "Atmel-ICE (ARM/AVR) in UPDI mode";
- type = "jtagice3_updi";
- connection_type = usb;
- usbpid = 0x2141;
-;
-
-programmer
- id = "atmelice_dw";
- desc = "Atmel-ICE (ARM/AVR) in debugWIRE mode";
- type = "jtagice3_dw";
- connection_type = usb;
- usbpid = 0x2141;
-;
-
-programmer
- id = "atmelice_isp";
- desc = "Atmel-ICE (ARM/AVR) in ISP mode";
- type = "jtagice3_isp";
- connection_type = usb;
- usbpid = 0x2141;
-;
-
-programmer
- id = "powerdebugger";
- desc = "Atmel PowerDebugger (ARM/AVR) in JTAG mode";
- type = "jtagice3";
- connection_type = usb;
- usbpid = 0x2144;
-;
-
-programmer
- id = "powerdebugger_pdi";
- desc = "Atmel PowerDebugger (ARM/AVR) in PDI mode";
- type = "jtagice3_pdi";
- connection_type = usb;
- usbpid = 0x2144;
-;
-
-programmer
- id = "powerdebugger_updi";
- desc = "Atmel PowerDebugger (ARM/AVR) in UPDI mode";
- type = "jtagice3_updi";
- connection_type = usb;
- usbpid = 0x2144;
-;
-
-programmer
- id = "powerdebugger_dw";
- desc = "Atmel PowerDebugger (ARM/AVR) in debugWire mode";
- type = "jtagice3_dw";
- connection_type = usb;
- usbpid = 0x2144;
-;
-
-programmer
- id = "powerdebugger_isp";
- desc = "Atmel PowerDebugger (ARM/AVR) in ISP mode";
- type = "jtagice3_isp";
- connection_type = usb;
- usbpid = 0x2144;
-;
-
-programmer
- id = "pavr";
- desc = "Jason Kyle's pAVR Serial Programmer";
- type = "avr910";
- connection_type = serial;
-;
-
-programmer
- id = "pickit2";
- desc = "MicroChip's PICkit2 Programmer";
- type = "pickit2";
- connection_type = usb;
-;
-
-programmer
- id = "flip1";
- desc = "FLIP USB DFU protocol version 1 (doc7618)";
- type = "flip1";
- connection_type = usb;
-;
-
-programmer
- id = "flip2";
- desc = "FLIP USB DFU protocol version 2 (AVR4023)";
- type = "flip2";
- connection_type = usb;
-;
-
-
-#This programmer bitbangs GPIO lines using the Linux sysfs GPIO interface
-#
-#To enable it set the configuration below to match the GPIO lines connected to the
-#relevant ISP header pins and uncomment the entry definition. In case you don't
-#have the required permissions to edit this system wide config file put the
-#entry in a separate .conf file and use it with -C+.conf
-#on the command line.
-#
-#To check if your avrdude build has support for the linuxgpio programmer compiled in,
-#use -c?type on the command line and look for linuxgpio in the list. If it's not available
-#you need pass the --enable-linuxgpio=yes option to configure and recompile avrdude.
-#
-#programmer
-# id = "linuxgpio";
-# desc = "Use the Linux sysfs interface to bitbang GPIO lines";
-# type = "linuxgpio";
-# reset = ?;
-# sck = ?;
-# mosi = ?;
-# miso = ?;
-#;
-
-
-#This programmer uses the built in linux SPI bus devices to program an
-#attached AVR. A GPIO accessed through the sysfs GPIO interface needs to
-#be specified for a reset pin since the linux SPI userspace functions do
-#not allow for control over the slave select/chip select signal.
-#
-programmer
- id = "linuxspi";
- desc = "Use Linux SPI device in /dev/spidev*";
- type = "linuxspi";
- reset = 25;
-;
-
-# some ultra cheap programmers use bitbanging on the
-# serialport.
-#
-# PC - DB9 - Pins for RS232:
-#
-# GND 5 -- |O
-# | O| <- 9 RI
-# DTR 4 <- |O |
-# | O| <- 8 CTS
-# TXD 3 <- |O |
-# | O| -> 7 RTS
-# RXD 2 -> |O |
-# | O| <- 6 DSR
-# DCD 1 -> |O
-#
-# Using RXD is currently not supported.
-# Using RI is not supported under Win32 but is supported under Posix.
-
-# serial ponyprog design (dasa2 in uisp)
-# reset=!txd sck=rts mosi=dtr miso=cts
-
-programmer
- id = "ponyser";
- desc = "design ponyprog serial, reset=!txd sck=rts mosi=dtr miso=cts";
- type = "serbb";
- connection_type = serial;
- reset = ~3;
- sck = 7;
- mosi = 4;
- miso = 8;
-;
-
-# Same as above, different name
-# reset=!txd sck=rts mosi=dtr miso=cts
-
-programmer parent "ponyser"
- id = "siprog";
- desc = "Lancos SI-Prog ";
-;
-
-# unknown (dasa in uisp)
-# reset=rts sck=dtr mosi=txd miso=cts
-
-programmer
- id = "dasa";
- desc = "serial port banging, reset=rts sck=dtr mosi=txd miso=cts";
- type = "serbb";
- connection_type = serial;
- reset = 7;
- sck = 4;
- mosi = 3;
- miso = 8;
-;
-
-# unknown (dasa3 in uisp)
-# reset=!dtr sck=rts mosi=txd miso=cts
-
-programmer
- id = "dasa3";
- desc = "serial port banging, reset=!dtr sck=rts mosi=txd miso=cts";
- type = "serbb";
- connection_type = serial;
- reset = ~4;
- sck = 7;
- mosi = 3;
- miso = 8;
-;
-
-# C2N232i (jumper configuration "auto")
-# reset=dtr sck=!rts mosi=!txd miso=!cts
-
-programmer
- id = "c2n232i";
- desc = "serial port banging, reset=dtr sck=!rts mosi=!txd miso=!cts";
- type = "serbb";
- connection_type = serial;
- reset = 4;
- sck = ~7;
- mosi = ~3;
- miso = ~8;
-;
-
-#
-# PART DEFINITIONS
-#
-
-#------------------------------------------------------------
-# ATtiny11
-#------------------------------------------------------------
-
-# This is an HVSP-only device.
-
-part
- id = "t11";
- desc = "ATtiny11";
- stk500_devcode = 0x11;
- signature = 0x1e 0x90 0x04;
- chip_erase_delay = 20000;
-
- timeout = 200;
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
- 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
- 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 0;
- resetdelayus = 50;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- memory "eeprom"
- size = 64;
- blocksize = 64;
- readsize = 256;
- delay = 5;
- ;
-
- memory "flash"
- size = 1024;
- blocksize = 128;
- readsize = 256;
- delay = 3;
- ;
-
- memory "signature"
- size = 3;
- ;
-
- memory "lock"
- size = 1;
- ;
-
- memory "calibration"
- size = 1;
- ;
-
- memory "fuse"
- size = 1;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny12
-#------------------------------------------------------------
-
-part
- id = "t12";
- desc = "ATtiny12";
- stk500_devcode = 0x12;
- avr910_devcode = 0x55;
- signature = 0x1e 0x90 0x05;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
- 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
- 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
- hventerstabdelay = 100;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 0;
- resetdelayus = 50;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- memory "eeprom"
- size = 64;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 x x x x x x x x",
- "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 x x x x x x x x",
- "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 8;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "flash"
- size = 1024;
- min_write_delay = 4500;
- max_write_delay = 20000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 5;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x o o x";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "fuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 x x x x x x x x",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny13
-#------------------------------------------------------------
-
-part
- id = "t13";
- desc = "ATtiny13";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x0E, 0x1E;
- eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x0E, 0xB4, 0x0E, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
- stk500_devcode = 0x14;
- signature = 0x1e 0x90 0x07;
- chip_erase_delay = 4000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
- 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
- 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 0;
- resetdelayus = 90;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- ocdrev = 0;
-
- memory "eeprom"
- size = 64;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
- "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
- "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 5;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 1024;
- page_size = 32;
- num_pages = 32;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 0 0 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 0 0 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 0 0 a8",
- " a7 a6 a5 a4 x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 2;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- ;
-
-;
-
-
-#------------------------------------------------------------
-# ATtiny15
-#------------------------------------------------------------
-
-part
- id = "t15";
- desc = "ATtiny15";
- stk500_devcode = 0x13;
- avr910_devcode = 0x56;
- signature = 0x1e 0x90 0x06;
- chip_erase_delay = 8200;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
- 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
- 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
- hventerstabdelay = 100;
- hvspcmdexedelay = 5;
- synchcycles = 6;
- latchcycles = 16;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 0;
- resetdelayus = 50;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- memory "eeprom"
- size = 64;
- min_write_delay = 8200;
- max_write_delay = 8200;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 x x x x x x x x",
- "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 x x x x x x x x",
- "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 10;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "flash"
- size = 1024;
- min_write_delay = 4100;
- max_write_delay = 4100;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 5;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x o o x";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "fuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 x x x x x x x x",
- "x x x x x x x x o o o o x x o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
- "x x x x x x x x i i i i 1 1 i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-;
-
-#------------------------------------------------------------
-# AT90s1200
-#------------------------------------------------------------
-
-part
- id = "1200";
- desc = "AT90S1200";
- is_at90s1200 = yes;
- stk500_devcode = 0x33;
- avr910_devcode = 0x13;
- signature = 0x1e 0x90 0x01;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 1;
- bytedelay = 0;
- pollindex = 0;
- pollvalue = 0xFF;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 15;
- chiperasepolltimeout = 0;
- programfusepulsewidth = 2;
- programfusepolltimeout = 0;
- programlockpulsewidth = 0;
- programlockpolltimeout = 1;
-
- memory "eeprom"
- size = 64;
- min_write_delay = 4000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 x x x x x x x x",
- "x x a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 x x x x x x x x",
- "x x a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 20;
- blocksize = 32;
- readsize = 256;
- ;
- memory "flash"
- size = 1024;
- min_write_delay = 4000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x02;
- delay = 15;
- blocksize = 128;
- readsize = 256;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- ;
- memory "lock"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90s4414
-#------------------------------------------------------------
-
-part
- id = "4414";
- desc = "AT90S4414";
- stk500_devcode = 0x50;
- avr910_devcode = 0x28;
- signature = 0x1e 0x92 0x01;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 15;
- chiperasepolltimeout = 0;
- programfusepulsewidth = 2;
- programfusepolltimeout = 0;
- programlockpulsewidth = 0;
- programlockpolltimeout = 1;
-
- memory "eeprom"
- size = 256;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0x80;
- readback_p2 = 0x7f;
- read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 64;
- readsize = 256;
- ;
- memory "flash"
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0x7f;
- readback_p2 = 0x7f;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 64;
- readsize = 256;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
- ;
-
-#------------------------------------------------------------
-# AT90s2313
-#------------------------------------------------------------
-
-part
- id = "2313";
- desc = "AT90S2313";
- stk500_devcode = 0x40;
- avr910_devcode = 0x20;
- signature = 0x1e 0x91 0x01;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 15;
- chiperasepolltimeout = 0;
- programfusepulsewidth = 2;
- programfusepolltimeout = 0;
- programlockpulsewidth = 0;
- programlockpolltimeout = 1;
-
- memory "eeprom"
- size = 128;
- min_write_delay = 4000;
- max_write_delay = 9000;
- readback_p1 = 0x80;
- readback_p2 = 0x7f;
- read = "1 0 1 0 0 0 0 0 x x x x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 x x x x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 64;
- readsize = 256;
- ;
- memory "flash"
- size = 2048;
- min_write_delay = 4000;
- max_write_delay = 9000;
- readback_p1 = 0x7f;
- readback_p2 = 0x7f;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x i i x",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
- ;
-
-#------------------------------------------------------------
-# AT90s2333
-#------------------------------------------------------------
-
-part
- id = "2333";
-##### WARNING: No XML file for device 'AT90S2333'! #####
- desc = "AT90S2333";
- stk500_devcode = 0x42;
- avr910_devcode = 0x34;
- signature = 0x1e 0x91 0x05;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 15;
- chiperasepolltimeout = 0;
- programfusepulsewidth = 2;
- programfusepolltimeout = 0;
- programlockpulsewidth = 0;
- programlockpolltimeout = 1;
-
- memory "eeprom"
- size = 128;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0x00;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 x x x x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 x x x x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "flash"
- size = 2048;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- pwroff_after_write = yes;
- read = "0 1 0 1 0 0 0 0 x x x x x x x x",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
- "x x x x x x x x x x x x x x x x";
- ;
- memory "lock"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x o o x";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- ;
- ;
-
-
-#------------------------------------------------------------
-# AT90s2343 (also AT90s2323 and ATtiny22)
-#------------------------------------------------------------
-
-part
- id = "2343";
- desc = "AT90S2343";
- stk500_devcode = 0x43;
- avr910_devcode = 0x4c;
- signature = 0x1e 0x91 0x03;
- chip_erase_delay = 18000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x00,
- 0x68, 0x78, 0x68, 0x68, 0x00, 0x00, 0x68, 0x78,
- 0x78, 0x00, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
- hventerstabdelay = 100;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 0;
- poweroffdelay = 25;
- resetdelayms = 0;
- resetdelayus = 50;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- memory "eeprom"
- size = 128;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0x00;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0",
- "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0",
- "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 64;
- readsize = 256;
- ;
- memory "flash"
- size = 2048;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 128;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x o o o x x x x o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
- "x x x x x x x x x x x x x x x x";
- ;
- memory "lock"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x o o o x x x x o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- ;
- ;
-
-
-#------------------------------------------------------------
-# AT90s4433
-#------------------------------------------------------------
-
-part
- id = "4433";
- desc = "AT90S4433";
- stk500_devcode = 0x51;
- avr910_devcode = 0x30;
- signature = 0x1e 0x92 0x03;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 15;
- chiperasepolltimeout = 0;
- programfusepulsewidth = 2;
- programfusepolltimeout = 0;
- programlockpulsewidth = 0;
- programlockpolltimeout = 1;
-
- memory "eeprom"
- size = 256;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0x00;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
- memory "flash"
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- pwroff_after_write = yes;
- read = "0 1 0 1 0 0 0 0 x x x x x x x x",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
- "x x x x x x x x x x x x x x x x";
- ;
- memory "lock"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x o o x";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90s4434
-#------------------------------------------------------------
-
-part
- id = "4434";
-##### WARNING: No XML file for device 'AT90S4434'! #####
- desc = "AT90S4434";
- stk500_devcode = 0x52;
- avr910_devcode = 0x6c;
- signature = 0x1e 0x92 0x02;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- memory "eeprom"
- size = 256;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0x00;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
- ;
- memory "flash"
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- read = "0 1 0 1 0 0 0 0 x x x x x x x x",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 i i i i i",
- "x x x x x x x x x x x x x x x x";
- ;
- memory "lock"
- size = 1;
- min_write_delay = 9000;
- max_write_delay = 20000;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x o o x";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90s8515
-#------------------------------------------------------------
-
-part
- id = "8515";
- desc = "AT90S8515";
- stk500_devcode = 0x60;
- avr910_devcode = 0x38;
- signature = 0x1e 0x93 0x01;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 15;
- chiperasepolltimeout = 0;
- programfusepulsewidth = 2;
- programfusepolltimeout = 0;
- programlockpulsewidth = 0;
- programlockpolltimeout = 1;
-
- memory "eeprom"
- size = 512;
- min_write_delay = 4000;
- max_write_delay = 9000;
- readback_p1 = 0x80;
- readback_p2 = 0x7f;
- read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
- memory "flash"
- size = 8192;
- min_write_delay = 4000;
- max_write_delay = 9000;
- readback_p1 = 0x7f;
- readback_p2 = 0x7f;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
- ;
-
-#------------------------------------------------------------
-# AT90s8535
-#------------------------------------------------------------
-
-part
- id = "8535";
- desc = "AT90S8535";
- stk500_devcode = 0x61;
- avr910_devcode = 0x68;
- signature = 0x1e 0x93 0x03;
- chip_erase_delay = 20000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 15;
- chiperasepolltimeout = 0;
- programfusepulsewidth = 2;
- programfusepolltimeout = 0;
- programlockpulsewidth = 0;
- programlockpolltimeout = 1;
-
- memory "eeprom"
- size = 512;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0x00;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
- memory "flash"
- size = 8192;
- min_write_delay = 9000;
- max_write_delay = 20000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write_lo = " 0 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- write_hi = " 0 1 0 0 1 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 128;
- readsize = 256;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "fuse"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x x x o";
- write = "1 0 1 0 1 1 0 0 1 0 1 1 1 1 1 i",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x o o x x x x x x";
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega103
-#------------------------------------------------------------
-
-part
- id = "m103";
- desc = "ATmega103";
- stk500_devcode = 0xB1;
- avr910_devcode = 0x41;
- signature = 0x1e 0x97 0x01;
- chip_erase_delay = 112000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x8E, 0x9E, 0x2E, 0x3E, 0xAE, 0xBE,
- 0x4E, 0x5E, 0xCE, 0xDE, 0x6E, 0x7E, 0xEE, 0xDE,
- 0x66, 0x76, 0xE6, 0xF6, 0x6A, 0x7A, 0xEA, 0x7A,
- 0x7F, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 15;
- chiperasepolltimeout = 0;
- programfusepulsewidth = 2;
- programfusepolltimeout = 0;
- programlockpulsewidth = 0;
- programlockpolltimeout = 10;
-
- memory "eeprom"
- size = 4096;
- min_write_delay = 4000;
- max_write_delay = 9000;
- readback_p1 = 0x80;
- readback_p2 = 0x7f;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 131072;
- page_size = 256;
- num_pages = 512;
- min_write_delay = 22000;
- max_write_delay = 56000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x11;
- delay = 70;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "fuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 x x x x x x x x",
- "x x x x x x x x x x o x o 1 o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 1 i 1 i i",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x o o x";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 i i 1",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-
-#------------------------------------------------------------
-# ATmega64
-#------------------------------------------------------------
-
-part
- id = "m64";
- desc = "ATmega64";
- has_jtag = yes;
- stk500_devcode = 0xA0;
- avr910_devcode = 0x45;
- signature = 0x1e 0x96 0x02;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x22;
- spmcr = 0x68;
- allowfullpagebitstream = yes;
-
- ocdrev = 2;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 2048;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 20;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 65536;
- page_size = 256;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 4;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-
-
-
-#------------------------------------------------------------
-# ATmega128
-#------------------------------------------------------------
-
-part
- id = "m128";
- desc = "ATmega128";
- has_jtag = yes;
- stk500_devcode = 0xB2;
- avr910_devcode = 0x43;
- signature = 0x1e 0x97 0x02;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x22;
- spmcr = 0x68;
- rampz = 0x3b;
- allowfullpagebitstream = yes;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 12;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 131072;
- page_size = 256;
- num_pages = 512;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 4;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90CAN128
-#------------------------------------------------------------
-
-part
- id = "c128";
- desc = "AT90CAN128";
- has_jtag = yes;
- stk500_devcode = 0xB3;
-# avr910_devcode = 0x43;
- signature = 0x1e 0x97 0x81;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- eecr = 0x3f;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
-
- mode = 0x41;
- delay = 20;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 131072;
- page_size = 256;
- num_pages = 512;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90CAN64
-#------------------------------------------------------------
-
-part
- id = "c64";
- desc = "AT90CAN64";
- has_jtag = yes;
- stk500_devcode = 0xB3;
-# avr910_devcode = 0x43;
- signature = 0x1e 0x96 0x81;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- eecr = 0x3f;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 2048;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
-
- mode = 0x41;
- delay = 20;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 65536;
- page_size = 256;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90CAN32
-#------------------------------------------------------------
-
-part
- id = "c32";
- desc = "AT90CAN32";
- has_jtag = yes;
- stk500_devcode = 0xB3;
-# avr910_devcode = 0x43;
- signature = 0x1e 0x95 0x81;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- eecr = 0x3f;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 1024;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
-
- mode = 0x41;
- delay = 20;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 32768;
- page_size = 256;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-
-#------------------------------------------------------------
-# ATmega16
-#------------------------------------------------------------
-
-part
- id = "m16";
- desc = "ATmega16";
- has_jtag = yes;
- stk500_devcode = 0x82;
- avr910_devcode = 0x74;
- signature = 0x1e 0x94 0x03;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 100;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- allowfullpagebitstream = yes;
-
- ocdrev = 2;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 512;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x04;
- delay = 10;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "calibration"
- size = 4;
-
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
- ;
-
-
-#------------------------------------------------------------
-# ATmega164P
-#------------------------------------------------------------
-
-# close to ATmega16
-
-part parent "m16"
- id = "m164p";
- desc = "ATmega164P";
- signature = 0x1e 0x94 0x0a;
-
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- allowfullpagebitstream = no;
- chip_erase_delay = 55000;
-
- ocdrev = 3;
- ;
-
-
-#------------------------------------------------------------
-# ATmega324P
-#------------------------------------------------------------
-
-# similar to ATmega164P
-
-part
- id = "m324p";
- desc = "ATmega324P";
- has_jtag = yes;
- stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
- avr910_devcode = 0x74;
- signature = 0x1e 0x95 0x08;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 55000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 1024;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 32768;
- page_size = 128;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x 1 1 1 1 1 i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
-
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-
-#------------------------------------------------------------
-# ATmega324PA
-#------------------------------------------------------------
-
-# similar to ATmega324P
-
-part parent "m324p"
- id = "m324pa";
- desc = "ATmega324PA";
- signature = 0x1e 0x95 0x11;
-
- ocdrev = 3;
- ;
-
-
-#------------------------------------------------------------
-# ATmega644
-#------------------------------------------------------------
-
-# similar to ATmega164
-
-part
- id = "m644";
- desc = "ATmega644";
- has_jtag = yes;
- stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
- avr910_devcode = 0x74;
- signature = 0x1e 0x96 0x09;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 55000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 2048;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 65536;
- page_size = 256;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x 1 1 1 1 1 i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
-
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega644P
-#------------------------------------------------------------
-
-# similar to ATmega164p
-
-part parent "m644"
- id = "m644p";
- desc = "ATmega644P";
- signature = 0x1e 0x96 0x0a;
-
- ocdrev = 3;
- ;
-
-
-
-#------------------------------------------------------------
-# ATmega1284
-#------------------------------------------------------------
-
-# similar to ATmega164
-
-part
- id = "m1284";
- desc = "ATmega1284";
- has_jtag = yes;
- stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
- avr910_devcode = 0x74;
- signature = 0x1e 0x97 0x06;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 55000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 131072;
- page_size = 256;
- num_pages = 512;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x 1 1 1 1 1 i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
-
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-
-
-#------------------------------------------------------------
-# ATmega1284P
-#------------------------------------------------------------
-
-# similar to ATmega164p
-
-part
- id = "m1284p";
- desc = "ATmega1284P";
- has_jtag = yes;
- stk500_devcode = 0x82; # no STK500v1 support, use the ATmega16 one
- avr910_devcode = 0x74;
- signature = 0x1e 0x97 0x05;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 55000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 131072;
- page_size = 256;
- num_pages = 512;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x 1 1 1 1 1 i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
-
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-
-
-#------------------------------------------------------------
-# ATmega162
-#------------------------------------------------------------
-
-part
- id = "m162";
- desc = "ATmega162";
- has_jtag = yes;
- stk500_devcode = 0x83;
- avr910_devcode = 0x63;
- signature = 0x1e 0x94 0x04;
- chip_erase_delay = 9000;
- pagel = 0xd7;
- bs2 = 0xa0;
-
- idr = 0x04;
- spmcr = 0x57;
- allowfullpagebitstream = yes;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- ocdrev = 2;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
- mode = 0x41;
- delay = 10;
- blocksize = 128;
- readsize = 256;
-
- ;
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 512;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 16000;
- max_write_delay = 16000;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 16000;
- max_write_delay = 16000;
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 16000;
- max_write_delay = 16000;
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x 1 1 1 1 1 i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 16000;
- max_write_delay = 16000;
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "signature"
- size = 3;
-
- read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
-
- read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-;
-
-
-
-#------------------------------------------------------------
-# ATmega163
-#------------------------------------------------------------
-
-part
- id = "m163";
- desc = "ATmega163";
- stk500_devcode = 0x81;
- avr910_devcode = 0x64;
- signature = 0x1e 0x94 0x02;
- chip_erase_delay = 32000;
- pagel = 0xd7;
- bs2 = 0xa0;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 30;
- programfusepulsewidth = 0;
- programfusepolltimeout = 2;
- programlockpulsewidth = 0;
- programlockpolltimeout = 2;
-
-
- memory "eeprom"
- size = 512;
- min_write_delay = 4000;
- max_write_delay = 4000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 16000;
- max_write_delay = 16000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x11;
- delay = 20;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o x x o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i 1 1 i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x x x x x 1 o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x 1 1 1 1 1 i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x 0 x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega169
-#------------------------------------------------------------
-
-part
- id = "m169";
- desc = "ATmega169";
- has_jtag = yes;
- stk500_devcode = 0x85;
- avr910_devcode = 0x78;
- signature = 0x1e 0x94 0x05;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
-
- ocdrev = 2;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 512;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega329
-#------------------------------------------------------------
-
-part
- id = "m329";
- desc = "ATmega329";
- has_jtag = yes;
-# stk500_devcode = 0x85; # no STK500 support, only STK500v2
-# avr910_devcode = 0x?; # try the ATmega169 one:
- avr910_devcode = 0x75;
- signature = 0x1e 0x95 0x03;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 1024;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 32768;
- page_size = 128;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega329P
-#------------------------------------------------------------
-# Identical to ATmega329 except of the signature
-
-part parent "m329"
- id = "m329p";
- desc = "ATmega329P";
- signature = 0x1e 0x95 0x0b;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# ATmega3290
-#------------------------------------------------------------
-
-# identical to ATmega329
-
-part parent "m329"
- id = "m3290";
- desc = "ATmega3290";
- signature = 0x1e 0x95 0x04;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# ATmega3290P
-#------------------------------------------------------------
-
-# identical to ATmega3290 except of the signature
-
-part parent "m3290"
- id = "m3290p";
- desc = "ATmega3290P";
- signature = 0x1e 0x95 0x0c;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# ATmega649
-#------------------------------------------------------------
-
-part
- id = "m649";
- desc = "ATmega649";
- has_jtag = yes;
-# stk500_devcode = 0x85; # no STK500 support, only STK500v2
-# avr910_devcode = 0x?; # try the ATmega169 one:
- avr910_devcode = 0x75;
- signature = 0x1e 0x96 0x03;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 2048;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 65536;
- page_size = 256;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega6490
-#------------------------------------------------------------
-
-# identical to ATmega649
-
-part parent "m649"
- id = "m6490";
- desc = "ATmega6490";
- signature = 0x1e 0x96 0x04;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# ATmega32
-#------------------------------------------------------------
-
-part
- id = "m32";
- desc = "ATmega32";
- has_jtag = yes;
- stk500_devcode = 0x91;
- avr910_devcode = 0x72;
- signature = 0x1e 0x95 0x02;
- chip_erase_delay = 9000;
- pagel = 0xd7;
- bs2 = 0xa0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- allowfullpagebitstream = yes;
-
- ocdrev = 2;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 1024;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x04;
- delay = 10;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 32768;
- page_size = 128;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 4;
- read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega161
-#------------------------------------------------------------
-
-part
- id = "m161";
- desc = "ATmega161";
- stk500_devcode = 0x80;
- avr910_devcode = 0x60;
- signature = 0x1e 0x94 0x01;
- chip_erase_delay = 28000;
- pagel = 0xd7;
- bs2 = 0xa0;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 30;
- programfusepulsewidth = 0;
- programfusepolltimeout = 2;
- programlockpulsewidth = 0;
- programlockpolltimeout = 2;
-
- memory "eeprom"
- size = 512;
- min_write_delay = 3400;
- max_write_delay = 3400;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 5;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 14000;
- max_write_delay = 14000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 16;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "fuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 0 0 0 0 x x x x x x x x",
- "x x x x x x x x x o x o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 x x x x x",
- "x x x x x x x x 1 i 1 i i i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-
-#------------------------------------------------------------
-# ATmega8
-#------------------------------------------------------------
-
-part
- id = "m8";
- desc = "ATmega8";
- stk500_devcode = 0x70;
- avr910_devcode = 0x76;
- signature = 0x1e 0x93 0x07;
- pagel = 0xd7;
- bs2 = 0xc2;
- chip_erase_delay = 10000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 2;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- memory "eeprom"
- size = 512;
- page_size = 4;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 20;
- blocksize = 128;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 0 x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 0 x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 10;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- # Required for Arduino IDE
- # see: https://github.com/arduino/Arduino/issues/2075
- # https://github.com/arduino/Arduino/issues/2075#issuecomment-238031689
- memory "efuse"
- size = 0;
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 4;
- read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-
-
-#------------------------------------------------------------
-# ATmega8515
-#------------------------------------------------------------
-
-part
- id = "m8515";
- desc = "ATmega8515";
- stk500_devcode = 0x63;
- avr910_devcode = 0x3A;
- signature = 0x1e 0x93 0x06;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- memory "eeprom"
- size = 512;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 20;
- blocksize = 128;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 0 x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 0 x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 4;
- read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-
-
-
-#------------------------------------------------------------
-# ATmega8535
-#------------------------------------------------------------
-
-part
- id = "m8535";
- desc = "ATmega8535";
- stk500_devcode = 0x64;
- avr910_devcode = 0x69;
- signature = 0x1e 0x93 0x08;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 6;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- memory "eeprom"
- size = 512;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- mode = 0x04;
- delay = 20;
- blocksize = 128;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 0 x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 0 x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 2000;
- max_write_delay = 2000;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 4;
- read = "0 0 1 1 1 0 0 0 0 0 x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-
-#------------------------------------------------------------
-# ATtiny26
-#------------------------------------------------------------
-
-part
- id = "t26";
- desc = "ATtiny26";
- stk500_devcode = 0x21;
- avr910_devcode = 0x5e;
- signature = 0x1e 0x91 0x09;
- pagel = 0xb3;
- bs2 = 0xb2;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
- 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
- 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
- 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 2;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- memory "eeprom"
- size = 128;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 x x x x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 x x x x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- mode = 0x04;
- delay = 10;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 2048;
- page_size = 32;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 16;
- readsize = 256;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x x o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x x x x i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 4;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
-;
-
-
-#------------------------------------------------------------
-# ATtiny261
-#------------------------------------------------------------
-# Close to ATtiny26
-
-part
- id = "t261";
- desc = "ATtiny261";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x00, 0x10;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
-# stk500_devcode = 0x21;
-# avr910_devcode = 0x5e;
- signature = 0x1e 0x91 0x0c;
- pagel = 0xb3;
- bs2 = 0xb2;
- chip_erase_delay = 4000;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
- 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
- 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
- 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 2;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no;
- size = 128;
- page_size = 4;
- num_pages = 32;
- min_write_delay = 4000;
- max_write_delay = 4000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read = "1 0 1 0 0 0 0 0 x x x x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 x x x x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 2048;
- page_size = 32;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x x x x a9 a8",
- " a7 a6 a5 a4 x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x x o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
-;
-
-
-#------------------------------------------------------------
-# ATtiny461
-#------------------------------------------------------------
-# Close to ATtiny261
-
-part
- id = "t461";
- desc = "ATtiny461";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x00, 0x10;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
-# stk500_devcode = 0x21;
-# avr910_devcode = 0x5e;
- signature = 0x1e 0x92 0x08;
- pagel = 0xb3;
- bs2 = 0xb2;
- chip_erase_delay = 4000;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
- 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
- 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
- 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 2;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no;
- size = 256;
- page_size = 4;
- num_pages = 64;
- min_write_delay = 4000;
- max_write_delay = 4000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read = " 1 0 1 0 0 0 0 0 x x x x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0 x x x x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 4096;
- page_size = 64;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x x o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
-;
-
-
-#------------------------------------------------------------
-# ATtiny861
-#------------------------------------------------------------
-# Close to ATtiny461
-
-part
- id = "t861";
- desc = "ATtiny861";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x00, 0x10;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x00, 0xB4, 0x00, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
-# stk500_devcode = 0x21;
-# avr910_devcode = 0x5e;
- signature = 0x1e 0x93 0x0d;
- pagel = 0xb3;
- bs2 = 0xb2;
- chip_erase_delay = 4000;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 0;
-
- pp_controlstack =
- 0xC4, 0xE4, 0xC4, 0xE4, 0xCC, 0xEC, 0xCC, 0xEC,
- 0xD4, 0xF4, 0xD4, 0xF4, 0xDC, 0xFC, 0xDC, 0xFC,
- 0xC8, 0xE8, 0xD8, 0xF8, 0x4C, 0x6C, 0x5C, 0x7C,
- 0xEC, 0xBC, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 2;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no;
- size = 512;
- num_pages = 128;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read = " 1 0 1 0 0 0 0 0 x x x x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0 x x x x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read_lo = " 0 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 x x x x x x x x",
- "x x x x x x x x x x x x x x o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 1 1 1 i i",
- "x x x x x x x x x x x x x x x x";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
-;
-
-
-#------------------------------------------------------------
-# ATtiny28
-#------------------------------------------------------------
-
-# This is an HVPP-only device.
-
-part
- id = "t28";
- desc = "ATtiny28";
- stk500_devcode = 0x22;
- avr910_devcode = 0x5c;
- signature = 0x1e 0x91 0x07;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 0;
- poweroffdelay = 0;
- resetdelayms = 0;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- memory "flash"
- size = 2048;
- page_size = 2;
- readsize = 256;
- delay = 5;
- ;
-
- memory "signature"
- size = 3;
- ;
-
- memory "lock"
- size = 1;
- ;
-
- memory "calibration"
- size = 1;
- ;
-
- memory "fuse"
- size = 1;
- ;
-;
-
-
-
-#------------------------------------------------------------
-# ATmega48
-#------------------------------------------------------------
-
-part
- id = "m48";
- desc = "ATmega48";
- has_debugwire = yes;
- flash_instr = 0xB6, 0x01, 0x11;
- eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
- 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
- 0x99, 0xF9, 0xBB, 0xAF;
- stk500_devcode = 0x59;
-# avr910_devcode = 0x;
- signature = 0x1e 0x92 0x05;
- pagel = 0xd7;
- bs2 = 0xc2;
- chip_erase_delay = 45000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no;
- page_size = 4;
- size = 256;
- min_write_delay = 3600;
- max_write_delay = 3600;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 4096;
- page_size = 64;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega48P
-#------------------------------------------------------------
-
-part parent "m48"
- id = "m48p";
- desc = "ATmega48P";
- signature = 0x1e 0x92 0x0a;
-
- ocdrev = 1;
- ;
-
-#------------------------------------------------------------
-# ATmega48PB
-#------------------------------------------------------------
-
-part parent "m48"
- id = "m48pb";
- desc = "ATmega48PB";
- signature = 0x1e 0x92 0x10;
-
- ocdrev = 1;
- ;
-
-#------------------------------------------------------------
-# ATmega88
-#------------------------------------------------------------
-
-part
- id = "m88";
- desc = "ATmega88";
- has_debugwire = yes;
- flash_instr = 0xB6, 0x01, 0x11;
- eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
- 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
- 0x99, 0xF9, 0xBB, 0xAF;
- stk500_devcode = 0x73;
-# avr910_devcode = 0x;
- signature = 0x1e 0x93 0x0a;
- pagel = 0xd7;
- bs2 = 0xc2;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no;
- page_size = 4;
- size = 512;
- min_write_delay = 3600;
- max_write_delay = 3600;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega88P
-#------------------------------------------------------------
-
-part parent "m88"
- id = "m88p";
- desc = "ATmega88P";
- signature = 0x1e 0x93 0x0f;
-
- ocdrev = 1;
- ;
-
-#------------------------------------------------------------
-# ATmega88PB
-#------------------------------------------------------------
-
-part parent "m88"
- id = "m88pb";
- desc = "ATmega88PB";
- signature = 0x1e 0x93 0x16;
-
- ocdrev = 1;
- ;
-
-#------------------------------------------------------------
-# ATmega168
-#------------------------------------------------------------
-
-part
- id = "m168";
- desc = "ATmega168";
- has_debugwire = yes;
- flash_instr = 0xB6, 0x01, 0x11;
- eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
- 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
- 0x99, 0xF9, 0xBB, 0xAF;
- stk500_devcode = 0x86;
- # avr910_devcode = 0x;
- signature = 0x1e 0x94 0x06;
- pagel = 0xd7;
- bs2 = 0xc2;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no;
- page_size = 4;
- size = 512;
- min_write_delay = 3600;
- max_write_delay = 3600;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
-
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-;
-
-#------------------------------------------------------------
-# ATmega168P
-#------------------------------------------------------------
-
-part parent "m168"
- id = "m168p";
- desc = "ATmega168P";
- signature = 0x1e 0x94 0x0b;
-
- ocdrev = 1;
-;
-
-#------------------------------------------------------------
-# ATmega168PB
-#------------------------------------------------------------
-
-part parent "m168"
- id = "m168pb";
- desc = "ATmega168PB";
- signature = 0x1e 0x94 0x15;
-
- ocdrev = 1;
-;
-
-#------------------------------------------------------------
-# ATtiny88
-#------------------------------------------------------------
-
-part
- id = "t88";
- desc = "ATtiny88";
- has_debugwire = yes;
- flash_instr = 0xB6, 0x01, 0x11;
- eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
- 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
- 0x99, 0xF9, 0xBB, 0xAF;
- stk500_devcode = 0x73;
-# avr910_devcode = 0x;
- signature = 0x1e 0x93 0x11;
- pagel = 0xd7;
- bs2 = 0xc2;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no;
- page_size = 4;
- size = 64;
- min_write_delay = 3600;
- max_write_delay = 3600;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 64;
- ;
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega328
-#------------------------------------------------------------
-
-part
- id = "m328";
- desc = "ATmega328";
- has_debugwire = yes;
- flash_instr = 0xB6, 0x01, 0x11;
- eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
- 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
- 0x99, 0xF9, 0xBB, 0xAF;
- stk500_devcode = 0x86;
- # avr910_devcode = 0x;
- signature = 0x1e 0x95 0x14;
- pagel = 0xd7;
- bs2 = 0xc2;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no;
- page_size = 4;
- size = 1024;
- min_write_delay = 3600;
- max_write_delay = 3600;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 32768;
- page_size = 128;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
-
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-;
-
-part parent "m328"
- id = "m328p";
- desc = "ATmega328P";
- signature = 0x1e 0x95 0x0F;
-
- ocdrev = 1;
-;
-
-part parent "m328"
- id = "m328pb";
- desc = "ATmega328PB";
- signature = 0x1e 0x95 0x16;
-
- ocdrev = 1;
-;
-
-#------------------------------------------------------------
-# ATmega32m1
-#------------------------------------------------------------
-
-part parent "m328"
- id = "m32m1";
- desc = "ATmega32M1";
- # stk500_devcode = 0x;
- # avr910_devcode = 0x;
- signature = 0x1e 0x95 0x84;
- bs2 = 0xe2;
-
- memory "efuse"
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x i i i i i i";
- ;
-;
-
-#------------------------------------------------------------
-# ATmega64m1
-#------------------------------------------------------------
-
-part parent "m328"
- id = "m64m1";
- desc = "ATmega64M1";
- # stk500_devcode = 0x;
- # avr910_devcode = 0x;
- signature = 0x1e 0x96 0x84;
- bs2 = 0xe2;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x i i i i i i";
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny2313
-#------------------------------------------------------------
-
-part
- id = "t2313";
- desc = "ATtiny2313";
- has_debugwire = yes;
- flash_instr = 0xB2, 0x0F, 0x1F;
- eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
- stk500_devcode = 0x23;
-## Use the ATtiny26 devcode:
- avr910_devcode = 0x5e;
- signature = 0x1e 0x91 0x0a;
- pagel = 0xD4;
- bs2 = 0xD6;
- reset = io;
- chip_erase_delay = 9000;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
- 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
- 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
- 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 0;
-
- memory "eeprom"
- size = 128;
- paged = no;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 2048;
- page_size = 32;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
-# The information in the data sheet of April/2004 is wrong, this works:
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
-# The information in the data sheet of April/2004 is wrong, this works:
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
-# The information in the data sheet of April/2004 is wrong, this works:
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-# ATtiny2313 has Signature Bytes: 0x1E 0x91 0x0A.
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-# The Tiny2313 has calibration data for both 4 MHz and 8 MHz.
-# The information in the data sheet of April/2004 is wrong, this works:
-
- memory "calibration"
- size = 2;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATtiny4313
-#------------------------------------------------------------
-
-part
- id = "t4313";
- desc = "ATtiny4313";
- has_debugwire = yes;
- flash_instr = 0xB2, 0x0F, 0x1F;
- eeprom_instr = 0xBB, 0xFE, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBA, 0x0F, 0xB2, 0x0F, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
- stk500_devcode = 0x23;
-## Use the ATtiny26 devcode:
- avr910_devcode = 0x5e;
- signature = 0x1e 0x92 0x0d;
- pagel = 0xD4;
- bs2 = 0xD6;
- reset = io;
- chip_erase_delay = 9000;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
- 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
- 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
- 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 0;
-
- memory "eeprom"
- size = 256;
- paged = no;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 4096;
- page_size = 64;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-# ATtiny4313 has Signature Bytes: 0x1E 0x92 0x0D.
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 2;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90PWM2
-#------------------------------------------------------------
-
-part
- id = "pwm2";
- desc = "AT90PWM2";
- has_debugwire = yes;
- flash_instr = 0xB6, 0x01, 0x11;
- eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
- 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
- 0x99, 0xF9, 0xBB, 0xAF;
- stk500_devcode = 0x65;
-## avr910_devcode = ?;
- signature = 0x1e 0x93 0x81;
- pagel = 0xD8;
- bs2 = 0xE2;
- reset = io;
- chip_erase_delay = 9000;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- memory "eeprom"
- size = 512;
- paged = no;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 64;
- readsize = 256;
- ;
-# AT90PWM2 has Signature Bytes: 0x1E 0x93 0x81.
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90PWM3
-#------------------------------------------------------------
-
-# Completely identical to AT90PWM2 (including the signature!)
-
-part parent "pwm2"
- id = "pwm3";
- desc = "AT90PWM3";
- ;
-
-#------------------------------------------------------------
-# AT90PWM2B
-#------------------------------------------------------------
-# Same as AT90PWM2 but different signature.
-
-part parent "pwm2"
- id = "pwm2b";
- desc = "AT90PWM2B";
- signature = 0x1e 0x93 0x83;
-
- ocdrev = 1;
- ;
-
-#------------------------------------------------------------
-# AT90PWM3B
-#------------------------------------------------------------
-
-# Completely identical to AT90PWM2B (including the signature!)
-
-part parent "pwm2b"
- id = "pwm3b";
- desc = "AT90PWM3B";
-
- ocdrev = 1;
- ;
-
-#------------------------------------------------------------
-# AT90PWM316
-#------------------------------------------------------------
-
-# Similar to AT90PWM3B, but with 16 kiB flash, 512 B EEPROM, and 1024 B SRAM.
-
-part parent "pwm3b"
- id = "pwm316";
- desc = "AT90PWM316";
- signature = 0x1e 0x94 0x83;
-
- ocdrev = 1;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x21;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
- ;
-
-#------------------------------------------------------------
-# AT90PWM216
-#------------------------------------------------------------
-# Completely identical to AT90PWM316 (including the signature!)
-
-part parent "pwm316"
- id = "pwm216";
- desc = "AT90PWM216";
- ;
-
-#------------------------------------------------------------
-# ATtiny25
-#------------------------------------------------------------
-
-part
- id = "t25";
- desc = "ATtiny25";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x02, 0x12;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
-## no STK500 devcode in XML file, use the ATtiny45 one
- stk500_devcode = 0x14;
-## avr910_devcode = ?;
-## Try the AT90S2313 devcode:
- avr910_devcode = 0x20;
- signature = 0x1e 0x91 0x08;
- reset = io;
- chip_erase_delay = 4500;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
- 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
- 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
- hventerstabdelay = 100;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- ocdrev = 1;
-
- memory "eeprom"
- size = 128;
- paged = no;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 2048;
- page_size = 32;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-# ATtiny25 has Signature Bytes: 0x1E 0x91 0x08.
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATtiny45
-#------------------------------------------------------------
-
-part
- id = "t45";
- desc = "ATtiny45";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x02, 0x12;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
- stk500_devcode = 0x14;
-## avr910_devcode = ?;
-## Try the AT90S2313 devcode:
- avr910_devcode = 0x20;
- signature = 0x1e 0x92 0x06;
- reset = io;
- chip_erase_delay = 4500;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
- 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
- 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- ocdrev = 1;
-
- memory "eeprom"
- size = 256;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 4096;
- page_size = 64;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-# ATtiny45 has Signature Bytes: 0x1E 0x92 0x08. (Data sheet 2586C-AVR-06/05 (doc2586.pdf) indicates otherwise!)
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATtiny85
-#------------------------------------------------------------
-
-part
- id = "t85";
- desc = "ATtiny85";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x02, 0x12;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x02, 0xB4, 0x02, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
-## no STK500 devcode in XML file, use the ATtiny45 one
- stk500_devcode = 0x14;
-## avr910_devcode = ?;
-## Try the AT90S2313 devcode:
- avr910_devcode = 0x20;
- signature = 0x1e 0x93 0x0b;
- reset = io;
- chip_erase_delay = 400000;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
- 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
- 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x00;
- hventerstabdelay = 100;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- ocdrev = 1;
-
- memory "eeprom"
- size = 512;
- paged = no;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 12;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 30000;
- max_write_delay = 30000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-# ATtiny85 has Signature Bytes: 0x1E 0x93 0x08.
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega640
-#------------------------------------------------------------
-# Almost same as ATmega1280, except for different memory sizes
-
-part
- id = "m640";
- desc = "ATmega640";
- signature = 0x1e 0x96 0x08;
- has_jtag = yes;
-# stk500_devcode = 0xB2;
-# avr910_devcode = 0x43;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 65536;
- page_size = 256;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega1280
-#------------------------------------------------------------
-
-part
- id = "m1280";
- desc = "ATmega1280";
- signature = 0x1e 0x97 0x03;
- has_jtag = yes;
-# stk500_devcode = 0xB2;
-# avr910_devcode = 0x43;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 131072;
- page_size = 256;
- num_pages = 512;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega1281
-#------------------------------------------------------------
-# Identical to ATmega1280
-
-part parent "m1280"
- id = "m1281";
- desc = "ATmega1281";
- signature = 0x1e 0x97 0x04;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# ATmega2560
-#------------------------------------------------------------
-
-part
- id = "m2560";
- desc = "ATmega2560";
- signature = 0x1e 0x98 0x01;
- has_jtag = yes;
- stk500_devcode = 0xB2;
-# avr910_devcode = 0x43;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- allowfullpagebitstream = no;
-
- ocdrev = 4;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 262144;
- page_size = 256;
- num_pages = 1024;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- load_ext_addr = " 0 1 0 0 1 1 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 0 a16",
- " 0 0 0 0 0 0 0 0";
-
- mode = 0x41;
- delay = 10;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega2561
-#------------------------------------------------------------
-
-part parent "m2560"
- id = "m2561";
- desc = "ATmega2561";
- signature = 0x1e 0x98 0x02;
-
- ocdrev = 4;
- ;
-
-#------------------------------------------------------------
-# ATmega128RFA1
-#------------------------------------------------------------
-# Identical to ATmega2561 but half the ROM
-
-part parent "m2561"
- id = "m128rfa1";
- desc = "ATmega128RFA1";
- signature = 0x1e 0xa7 0x01;
- chip_erase_delay = 55000;
- bs2 = 0xE2;
-
- ocdrev = 3;
-
- memory "flash"
- paged = yes;
- size = 131072;
- page_size = 256;
- num_pages = 512;
- min_write_delay = 50000;
- max_write_delay = 50000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 256;
- readsize = 256;
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega256RFR2
-#------------------------------------------------------------
-
-part parent "m2561"
- id = "m256rfr2";
- desc = "ATmega256RFR2";
- signature = 0x1e 0xa8 0x02;
- chip_erase_delay = 18500;
- bs2 = 0xE2;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 8192;
- min_write_delay = 13000;
- max_write_delay = 13000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 8;
- readsize = 256;
- ;
-
-
- ocdrev = 4;
- ;
-
-#------------------------------------------------------------
-# ATmega128RFR2
-#------------------------------------------------------------
-
-part parent "m128rfa1"
- id = "m128rfr2";
- desc = "ATmega128RFR2";
- signature = 0x1e 0xa7 0x02;
-
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# ATmega64RFR2
-#------------------------------------------------------------
-
-part parent "m128rfa1"
- id = "m64rfr2";
- desc = "ATmega64RFR2";
- signature = 0x1e 0xa6 0x02;
-
-
- ocdrev = 3;
-
- memory "flash"
- paged = yes;
- size = 65536;
- page_size = 256;
- num_pages = 256;
- min_write_delay = 50000;
- max_write_delay = 50000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 2048;
- min_write_delay = 13000;
- max_write_delay = 13000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 8;
- readsize = 256;
- ;
-
-
- ;
-
-#------------------------------------------------------------
-# ATmega2564RFR2
-#------------------------------------------------------------
-
-part parent "m256rfr2"
- id = "m2564rfr2";
- desc = "ATmega2564RFR2";
- signature = 0x1e 0xa8 0x03;
- ;
-
-#------------------------------------------------------------
-# ATmega1284RFR2
-#------------------------------------------------------------
-
-part parent "m128rfr2"
- id = "m1284rfr2";
- desc = "ATmega1284RFR2";
- signature = 0x1e 0xa7 0x03;
- ;
-
-#------------------------------------------------------------
-# ATmega644RFR2
-#------------------------------------------------------------
-
-part parent "m64rfr2"
- id = "m644rfr2";
- desc = "ATmega644RFR2";
- signature = 0x1e 0xa6 0x03;
- ;
-
-#------------------------------------------------------------
-# ATtiny24
-#------------------------------------------------------------
-
-part
- id = "t24";
- desc = "ATtiny24";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x07, 0x17;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
-## no STK500 devcode in XML file, use the ATtiny45 one
- stk500_devcode = 0x14;
-## avr910_devcode = ?;
-## Try the AT90S2313 devcode:
- avr910_devcode = 0x20;
- signature = 0x1e 0x91 0x0b;
- reset = io;
- chip_erase_delay = 4500;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
- 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
- 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
- hventerstabdelay = 100;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 0;
- resetdelayus = 70;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- ocdrev = 1;
-
- memory "eeprom"
- size = 128;
- paged = no;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
- "x a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 2048;
- page_size = 32;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-# ATtiny24 has Signature Bytes: 0x1E 0x91 0x0B.
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x x x x x x x i i";
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATtiny44
-#------------------------------------------------------------
-
-part
- id = "t44";
- desc = "ATtiny44";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x07, 0x17;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
-## no STK500 devcode in XML file, use the ATtiny45 one
- stk500_devcode = 0x14;
-## avr910_devcode = ?;
-## Try the AT90S2313 devcode:
- avr910_devcode = 0x20;
- signature = 0x1e 0x92 0x07;
- reset = io;
- chip_erase_delay = 4500;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
- 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
- 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
- hventerstabdelay = 100;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 0;
- resetdelayus = 70;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- ocdrev = 1;
-
- memory "eeprom"
- size = 256;
- paged = no;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 4096;
- page_size = 64;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-# ATtiny44 has Signature Bytes: 0x1E 0x92 0x07.
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x x x x x x x i i";
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATtiny84
-#------------------------------------------------------------
-
-part
- id = "t84";
- desc = "ATtiny84";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x07, 0x17;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
-## no STK500 devcode in XML file, use the ATtiny45 one
- stk500_devcode = 0x14;
-## avr910_devcode = ?;
-## Try the AT90S2313 devcode:
- avr910_devcode = 0x20;
- signature = 0x1e 0x93 0x0c;
- reset = io;
- chip_erase_delay = 4500;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- hvsp_controlstack =
- 0x4C, 0x0C, 0x1C, 0x2C, 0x3C, 0x64, 0x74, 0x66,
- 0x68, 0x78, 0x68, 0x68, 0x7A, 0x6A, 0x68, 0x78,
- 0x78, 0x7D, 0x6D, 0x0C, 0x80, 0x40, 0x20, 0x10,
- 0x11, 0x08, 0x04, 0x02, 0x03, 0x08, 0x04, 0x0F;
- hventerstabdelay = 100;
- hvspcmdexedelay = 0;
- synchcycles = 6;
- latchcycles = 1;
- togglevtg = 1;
- poweroffdelay = 25;
- resetdelayms = 0;
- resetdelayus = 70;
- hvleavestabdelay = 100;
- resetdelay = 25;
- chiperasepolltimeout = 40;
- chiperasetime = 0;
- programfusepolltimeout = 25;
- programlockpolltimeout = 25;
-
- ocdrev = 1;
-
- memory "eeprom"
- size = 512;
- paged = no;
- page_size = 4;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x a8",
- "a7 a6 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " x a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 64;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 32;
- readsize = 256;
- ;
-# ATtiny84 has Signature Bytes: 0x1E 0x93 0x0C.
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x x x x x x x i i";
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATtiny441
-#------------------------------------------------------------
-
-part parent "t44"
- id = "t441";
- desc = "ATtiny441";
- signature = 0x1e 0x92 0x15;
-
- memory "flash"
- paged = yes;
- size = 4096;
- page_size = 16;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x x a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x x a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 16;
- readsize = 256;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny841
-#------------------------------------------------------------
-
-part parent "t84"
- id = "t841";
- desc = "ATtiny841";
- signature = 0x1e 0x93 0x15;
-
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 16;
- num_pages = 512;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x x a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x x x a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 16;
- readsize = 256;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny43U
-#------------------------------------------------------------
-
-part
- id = "t43u";
- desc = "ATtiny43u";
- has_debugwire = yes;
- flash_instr = 0xB4, 0x07, 0x17;
- eeprom_instr = 0xBB, 0xFF, 0xBB, 0xEE, 0xBB, 0xCC, 0xB2, 0x0D,
- 0xBC, 0x07, 0xB4, 0x07, 0xBA, 0x0D, 0xBB, 0xBC,
- 0x99, 0xE1, 0xBB, 0xAC;
- stk500_devcode = 0x14;
-## avr910_devcode = ?;
-## Try the AT90S2313 devcode:
- avr910_devcode = 0x20;
- signature = 0x1e 0x92 0x0C;
- reset = io;
- chip_erase_delay = 1000;
-
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
- pp_controlstack = 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E, 0x4E, 0x5E,
- 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E, 0x06, 0x16, 0x46, 0x56,
- 0x0A, 0x1A, 0x4A, 0x5A, 0x1E, 0x7C, 0x00, 0x01, 0x00, 0x00,
- 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- hvspcmdexedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 20;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
- memory "eeprom"
- size = 64;
- paged = yes;
- page_size = 4;
- num_pages = 16;
- min_write_delay = 4000;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = "1 0 1 0 0 0 0 0 0 0 0 x x x x x",
- "0 0 a4 a3 a2 a1 a0 o o o o o o o o";
-
- write = "1 1 0 0 0 0 0 0 0 0 0 x x x x x",
- "0 0 a5 a4 a3 a2 a1 a0 i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x x",
- " 0 0 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 5;
- blocksize = 4;
- readsize = 256;
- ;
- memory "flash"
- paged = yes;
- size = 4096;
- page_size = 64;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
-
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x x a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 64;
- readsize = 256;
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- memory "lock"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x x x x i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 4500;
- max_write_delay = 4500;
- ;
-
- memory "calibration"
- size = 2;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 a0 o o o o o o o o";
- ;
-;
-
-#------------------------------------------------------------
-# ATmega32u4
-#------------------------------------------------------------
-
-part
- id = "m32u4";
- desc = "ATmega32U4";
- signature = 0x1e 0x95 0x87;
- usbpid = 0x2ff4;
- has_jtag = yes;
-# stk500_devcode = 0xB2;
-# avr910_devcode = 0x43;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 1024;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 32768;
- page_size = 128;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90USB646
-#------------------------------------------------------------
-
-part
- id = "usb646";
- desc = "AT90USB646";
- signature = 0x1e 0x96 0x82;
- usbpid = 0x2ff9;
- has_jtag = yes;
-# stk500_devcode = 0xB2;
-# avr910_devcode = 0x43;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 2048;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 65536;
- page_size = 256;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90USB647
-#------------------------------------------------------------
-# identical to AT90USB646
-
-part parent "usb646"
- id = "usb647";
- desc = "AT90USB647";
- signature = 0x1e 0x96 0x82;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# AT90USB1286
-#------------------------------------------------------------
-
-part
- id = "usb1286";
- desc = "AT90USB1286";
- signature = 0x1e 0x97 0x82;
- usbpid = 0x2ffb;
- has_jtag = yes;
-# stk500_devcode = 0xB2;
-# avr910_devcode = 0x43;
- chip_erase_delay = 9000;
- pagel = 0xD7;
- bs2 = 0xA0;
- reset = dedicated;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- rampz = 0x3b;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 4096;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " x x x x a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 131072;
- page_size = 256;
- num_pages = 512;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 x x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 256;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x x i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 x x x x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 x x x x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90USB1287
-#------------------------------------------------------------
-# identical to AT90USB1286
-
-part parent "usb1286"
- id = "usb1287";
- desc = "AT90USB1287";
- signature = 0x1e 0x97 0x82;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# AT90USB162
-#------------------------------------------------------------
-
-part
- id = "usb162";
- desc = "AT90USB162";
- has_jtag = no;
- has_debugwire = yes;
- signature = 0x1e 0x94 0x82;
- usbpid = 0x2ffa;
- chip_erase_delay = 9000;
- reset = io;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
- pagel = 0xD7;
- bs2 = 0xC6;
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 512;
- num_pages = 128;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# AT90USB82
-#------------------------------------------------------------
-# Changes against AT90USB162 (beside IDs)
-# memory "flash"
-# size = 8192;
-# num_pages = 64;
-
-part
- id = "usb82";
- desc = "AT90USB82";
- has_jtag = no;
- has_debugwire = yes;
- signature = 0x1e 0x93 0x82;
- usbpid = 0x2ff7;
- chip_erase_delay = 9000;
- reset = io;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
- pagel = 0xD7;
- bs2 = 0xC6;
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 512;
- num_pages = 128;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 128;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega32U2
-#------------------------------------------------------------
-# Changes against AT90USB162 (beside IDs)
-# memory "flash"
-# size = 32768;
-# num_pages = 256;
-# memory "eeprom"
-# size = 1024;
-# num_pages = 256;
-part
- id = "m32u2";
- desc = "ATmega32U2";
- has_jtag = no;
- has_debugwire = yes;
- signature = 0x1e 0x95 0x8a;
- usbpid = 0x2ff0;
- chip_erase_delay = 9000;
- reset = io;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
- pagel = 0xD7;
- bs2 = 0xC6;
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 1024;
- num_pages = 256;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 32768;
- page_size = 128;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-#------------------------------------------------------------
-# ATmega16U2
-#------------------------------------------------------------
-# Changes against ATmega32U2 (beside IDs)
-# memory "flash"
-# size = 16384;
-# num_pages = 128;
-# memory "eeprom"
-# size = 512;
-# num_pages = 128;
-part
- id = "m16u2";
- desc = "ATmega16U2";
- has_jtag = no;
- has_debugwire = yes;
- signature = 0x1e 0x94 0x89;
- usbpid = 0x2fef;
- chip_erase_delay = 9000;
- reset = io;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
- pagel = 0xD7;
- bs2 = 0xC6;
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 512;
- num_pages = 128;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 128;
- num_pages = 128;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega8U2
-#------------------------------------------------------------
-# Changes against ATmega16U2 (beside IDs)
-# memory "flash"
-# size = 8192;
-# page_size = 64;
-# blocksize = 64;
-
-part
- id = "m8u2";
- desc = "ATmega8U2";
- has_jtag = no;
- has_debugwire = yes;
- signature = 0x1e 0x93 0x89;
- usbpid = 0x2fee;
- chip_erase_delay = 9000;
- reset = io;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
- pagel = 0xD7;
- bs2 = 0xC6;
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- ocdrev = 1;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 512;
- num_pages = 128;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 0 0 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 20;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 8192;
- page_size = 128;
- num_pages = 64;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0x00;
- readback_p2 = 0x00;
- read_lo = " 0 0 1 0 0 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " x x x x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- "a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x i i i i i i i i";
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
- ;
-#------------------------------------------------------------
-# ATmega325
-#------------------------------------------------------------
-
-part
- id = "m325";
- desc = "ATmega325";
- signature = 0x1e 0x95 0x05;
- has_jtag = yes;
-# stk500_devcode = 0x??; # No STK500v1 support?
-# avr910_devcode = 0x??; # Try the ATmega16 one
- avr910_devcode = 0x74;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 4; /* for parallel programming */
- size = 1024;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 0 0 0 0 a9 a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 32768;
- page_size = 128;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 0 0 0 0 0",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 0 0 0 0 0",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "0 0 0 0 0 0 0 0 i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
-
- read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega645
-#------------------------------------------------------------
-
-part
- id = "m645";
- desc = "ATmega645";
- signature = 0x1E 0x96 0x05;
- has_jtag = yes;
-# stk500_devcode = 0x??; # No STK500v1 support?
-# avr910_devcode = 0x??; # Try the ATmega16 one
- avr910_devcode = 0x74;
- pagel = 0xd7;
- bs2 = 0xa0;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x66, 0x76, 0x67, 0x77, 0x6A, 0x7A, 0x6B, 0x7B,
- 0xBE, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 5;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- idr = 0x31;
- spmcr = 0x57;
- allowfullpagebitstream = no;
-
- ocdrev = 3;
-
- memory "eeprom"
- paged = no; /* leave this "no" */
- page_size = 8; /* for parallel programming */
- size = 2048;
- min_write_delay = 9000;
- max_write_delay = 9000;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 0 0 0 a10 a9 a8",
- " a7 a6 a5 a4 a3 0 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 10;
- blocksize = 8;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 65536;
- page_size = 256;
- num_pages = 256;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 0 0 0 0 0",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 0 0 0 0 0",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " a15 a14 a13 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " 0 0 0 0 0 0 0 0";
-
- mode = 0x41;
- delay = 10;
- blocksize = 128;
- readsize = 256;
- ;
-
- memory "lock"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 1 1 i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "lfuse"
- size = 1;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "hfuse"
- size = 1;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "0 0 0 0 0 0 0 0 i i i i i i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "efuse"
- size = 1;
-
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "0 0 0 0 0 0 0 0 1 1 1 1 1 i i i";
- min_write_delay = 9000;
- max_write_delay = 9000;
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 a1 a0 o o o o o o o o";
- ;
-
- memory "calibration"
- size = 1;
-
- read = "0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
- ;
-
-#------------------------------------------------------------
-# ATmega3250
-#------------------------------------------------------------
-
-part parent "m325"
- id = "m3250";
- desc = "ATmega3250";
- signature = 0x1E 0x95 0x06;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# ATmega6450
-#------------------------------------------------------------
-
-part parent "m645"
- id = "m6450";
- desc = "ATmega6450";
- signature = 0x1E 0x96 0x06;
-
- ocdrev = 3;
- ;
-
-#------------------------------------------------------------
-# AVR XMEGA family common values
-#------------------------------------------------------------
-
-part
- id = ".xmega";
- desc = "AVR XMEGA family common values";
- has_pdi = yes;
- nvm_base = 0x01c0;
- mcu_base = 0x0090;
-
- memory "signature"
- size = 3;
- offset = 0x1000090;
- ;
-
- memory "prodsig"
- size = 0x32;
- offset = 0x8e0200;
- page_size = 0x32;
- readsize = 0x32;
- ;
-
- memory "fuse1"
- size = 1;
- offset = 0x8f0021;
- ;
-
- memory "fuse2"
- size = 1;
- offset = 0x8f0022;
- ;
-
- memory "fuse4"
- size = 1;
- offset = 0x8f0024;
- ;
-
- memory "fuse5"
- size = 1;
- offset = 0x8f0025;
- ;
-
- memory "lock"
- size = 1;
- offset = 0x8f0027;
- ;
-
- memory "data"
- # SRAM, only used to supply the offset
- offset = 0x1000000;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega16A4U
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x16a4u";
- desc = "ATxmega16A4U";
- signature = 0x1e 0x94 0x41;
- usbpid = 0x2fe3;
-
- memory "eeprom"
- size = 0x400;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x4000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x1000;
- offset = 0x803000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x1000;
- offset = 0x804000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x5000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x100;
- offset = 0x8e0400;
- page_size = 0x100;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega16C4
-#------------------------------------------------------------
-
-part parent "x16a4u"
- id = "x16c4";
- desc = "ATxmega16C4";
- signature = 0x1e 0x94 0x43;
-;
-
-#------------------------------------------------------------
-# ATxmega16D4
-#------------------------------------------------------------
-
-part parent "x16a4u"
- id = "x16d4";
- desc = "ATxmega16D4";
- signature = 0x1e 0x94 0x42;
-;
-
-#------------------------------------------------------------
-# ATxmega16A4
-#------------------------------------------------------------
-
-part parent "x16a4u"
- id = "x16a4";
- desc = "ATxmega16A4";
- signature = 0x1e 0x94 0x41;
- has_jtag = yes;
-
- memory "fuse0"
- size = 1;
- offset = 0x8f0020;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega32A4U
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x32a4u";
- desc = "ATxmega32A4U";
- signature = 0x1e 0x95 0x41;
- usbpid = 0x2fe4;
-
- memory "eeprom"
- size = 0x400;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x8000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x1000;
- offset = 0x807000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x1000;
- offset = 0x808000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x9000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x100;
- offset = 0x8e0400;
- page_size = 0x100;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega32C4
-#------------------------------------------------------------
-
-part parent "x32a4u"
- id = "x32c4";
- desc = "ATxmega32C4";
- signature = 0x1e 0x95 0x44;
-;
-
-#------------------------------------------------------------
-# ATxmega32D4
-#------------------------------------------------------------
-
-part parent "x32a4u"
- id = "x32d4";
- desc = "ATxmega32D4";
- signature = 0x1e 0x95 0x42;
-;
-
-#------------------------------------------------------------
-# ATxmega32A4
-#------------------------------------------------------------
-
-part parent "x32a4u"
- id = "x32a4";
- desc = "ATxmega32A4";
- signature = 0x1e 0x95 0x41;
- has_jtag = yes;
-
- memory "fuse0"
- size = 1;
- offset = 0x8f0020;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega64A4U
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x64a4u";
- desc = "ATxmega64A4U";
- signature = 0x1e 0x96 0x46;
- usbpid = 0x2fe5;
-
- memory "eeprom"
- size = 0x800;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x10000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x1000;
- offset = 0x80f000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x1000;
- offset = 0x810000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x11000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x100;
- offset = 0x8e0400;
- page_size = 0x100;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega64C3
-#------------------------------------------------------------
-
-part parent "x64a4u"
- id = "x64c3";
- desc = "ATxmega64C3";
- signature = 0x1e 0x96 0x49;
- usbpid = 0x2fd6;
-;
-
-#------------------------------------------------------------
-# ATxmega64D3
-#------------------------------------------------------------
-
-part parent "x64a4u"
- id = "x64d3";
- desc = "ATxmega64D3";
- signature = 0x1e 0x96 0x4a;
-;
-
-#------------------------------------------------------------
-# ATxmega64D4
-#------------------------------------------------------------
-
-part parent "x64a4u"
- id = "x64d4";
- desc = "ATxmega64D4";
- signature = 0x1e 0x96 0x47;
-;
-
-#------------------------------------------------------------
-# ATxmega64A1
-#------------------------------------------------------------
-
-part parent "x64a4u"
- id = "x64a1";
- desc = "ATxmega64A1";
- signature = 0x1e 0x96 0x4e;
- has_jtag = yes;
-
- memory "fuse0"
- size = 1;
- offset = 0x8f0020;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega64A1U
-#------------------------------------------------------------
-
-part parent "x64a1"
- id = "x64a1u";
- desc = "ATxmega64A1U";
- signature = 0x1e 0x96 0x4e;
- usbpid = 0x2fe8;
-;
-
-#------------------------------------------------------------
-# ATxmega64A3
-#------------------------------------------------------------
-
-part parent "x64a1"
- id = "x64a3";
- desc = "ATxmega64A3";
- signature = 0x1e 0x96 0x42;
-;
-
-#------------------------------------------------------------
-# ATxmega64A3U
-#------------------------------------------------------------
-
-part parent "x64a1"
- id = "x64a3u";
- desc = "ATxmega64A3U";
- signature = 0x1e 0x96 0x42;
- usbpid = 0x2fe5;
-;
-
-#------------------------------------------------------------
-# ATxmega64A4
-#------------------------------------------------------------
-
-part parent "x64a1"
- id = "x64a4";
- desc = "ATxmega64A4";
- signature = 0x1e 0x96 0x46;
-;
-
-#------------------------------------------------------------
-# ATxmega64B1
-#------------------------------------------------------------
-
-part parent "x64a1"
- id = "x64b1";
- desc = "ATxmega64B1";
- signature = 0x1e 0x96 0x52;
- usbpid = 0x2fe1;
-;
-
-#------------------------------------------------------------
-# ATxmega64B3
-#------------------------------------------------------------
-
-part parent "x64a1"
- id = "x64b3";
- desc = "ATxmega64B3";
- signature = 0x1e 0x96 0x51;
- usbpid = 0x2fdf;
-;
-
-#------------------------------------------------------------
-# ATxmega128C3
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x128c3";
- desc = "ATxmega128C3";
- signature = 0x1e 0x97 0x52;
- usbpid = 0x2fd7;
-
- memory "eeprom"
- size = 0x800;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x20000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x2000;
- offset = 0x81e000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x2000;
- offset = 0x820000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x22000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x200;
- offset = 0x8e0400;
- page_size = 0x200;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega128D3
-#------------------------------------------------------------
-
-part parent "x128c3"
- id = "x128d3";
- desc = "ATxmega128D3";
- signature = 0x1e 0x97 0x48;
-;
-
-#------------------------------------------------------------
-# ATxmega128D4
-#------------------------------------------------------------
-
-part parent "x128c3"
- id = "x128d4";
- desc = "ATxmega128D4";
- signature = 0x1e 0x97 0x47;
-;
-
-#------------------------------------------------------------
-# ATxmega128A1
-#------------------------------------------------------------
-
-part parent "x128c3"
- id = "x128a1";
- desc = "ATxmega128A1";
- signature = 0x1e 0x97 0x4c;
- has_jtag = yes;
-
- memory "fuse0"
- size = 1;
- offset = 0x8f0020;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega128A1 revision D
-#------------------------------------------------------------
-
-part parent "x128a1"
- id = "x128a1d";
- desc = "ATxmega128A1revD";
- signature = 0x1e 0x97 0x41;
-;
-
-#------------------------------------------------------------
-# ATxmega128A1U
-#------------------------------------------------------------
-
-part parent "x128a1"
- id = "x128a1u";
- desc = "ATxmega128A1U";
- signature = 0x1e 0x97 0x4c;
- usbpid = 0x2fed;
-;
-
-#------------------------------------------------------------
-# ATxmega128A3
-#------------------------------------------------------------
-
-part parent "x128a1"
- id = "x128a3";
- desc = "ATxmega128A3";
- signature = 0x1e 0x97 0x42;
-;
-
-#------------------------------------------------------------
-# ATxmega128A3U
-#------------------------------------------------------------
-
-part parent "x128a1"
- id = "x128a3u";
- desc = "ATxmega128A3U";
- signature = 0x1e 0x97 0x42;
- usbpid = 0x2fe6;
-;
-
-#------------------------------------------------------------
-# ATxmega128A4
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x128a4";
- desc = "ATxmega128A4";
- signature = 0x1e 0x97 0x46;
- has_jtag = yes;
-
- memory "eeprom"
- size = 0x800;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x20000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x1000;
- offset = 0x81f000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x2000;
- offset = 0x820000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x22000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x200;
- offset = 0x8e0400;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "fuse0"
- size = 1;
- offset = 0x8f0020;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega128A4U
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x128a4u";
- desc = "ATxmega128A4U";
- signature = 0x1e 0x97 0x46;
- usbpid = 0x2fde;
-
- memory "eeprom"
- size = 0x800;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x20000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x1000;
- offset = 0x81f000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x2000;
- offset = 0x820000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x22000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x100;
- offset = 0x8e0400;
- page_size = 0x100;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega128B1
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x128b1";
- desc = "ATxmega128B1";
- signature = 0x1e 0x97 0x4d;
- usbpid = 0x2fea;
- has_jtag = yes;
-
- memory "eeprom"
- size = 0x800;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x20000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x2000;
- offset = 0x81e000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x2000;
- offset = 0x820000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x22000;
- offset = 0x800000;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x100;
- offset = 0x8e0400;
- page_size = 0x100;
- readsize = 0x100;
- ;
-
- memory "fuse0"
- size = 1;
- offset = 0x8f0020;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega128B3
-#------------------------------------------------------------
-
-part parent "x128b1"
- id = "x128b3";
- desc = "ATxmega128B3";
- signature = 0x1e 0x97 0x4b;
- usbpid = 0x2fe0;
-;
-
-#------------------------------------------------------------
-# ATxmega192C3
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x192c3";
- desc = "ATxmega192C3";
- signature = 0x1e 0x97 0x51;
- # usbpid = 0x2f??;
-
- memory "eeprom"
- size = 0x800;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x30000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x2000;
- offset = 0x82e000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x2000;
- offset = 0x830000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x32000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x200;
- offset = 0x8e0400;
- page_size = 0x200;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega192D3
-#------------------------------------------------------------
-
-part parent "x192c3"
- id = "x192d3";
- desc = "ATxmega192D3";
- signature = 0x1e 0x97 0x49;
-;
-
-#------------------------------------------------------------
-# ATxmega192A1
-#------------------------------------------------------------
-
-part parent "x192c3"
- id = "x192a1";
- desc = "ATxmega192A1";
- signature = 0x1e 0x97 0x4e;
- has_jtag = yes;
-
- memory "fuse0"
- size = 1;
- offset = 0x8f0020;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega192A3
-#------------------------------------------------------------
-
-part parent "x192a1"
- id = "x192a3";
- desc = "ATxmega192A3";
- signature = 0x1e 0x97 0x44;
-;
-
-#------------------------------------------------------------
-# ATxmega192A3U
-#------------------------------------------------------------
-
-part parent "x192a1"
- id = "x192a3u";
- desc = "ATxmega192A3U";
- signature = 0x1e 0x97 0x44;
- usbpid = 0x2fe7;
-;
-
-#------------------------------------------------------------
-# ATxmega256C3
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x256c3";
- desc = "ATxmega256C3";
- signature = 0x1e 0x98 0x46;
- usbpid = 0x2fda;
-
- memory "eeprom"
- size = 0x1000;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x40000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x2000;
- offset = 0x83e000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x2000;
- offset = 0x840000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x42000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x200;
- offset = 0x8e0400;
- page_size = 0x200;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega256D3
-#------------------------------------------------------------
-
-part parent "x256c3"
- id = "x256d3";
- desc = "ATxmega256D3";
- signature = 0x1e 0x98 0x44;
-;
-
-#------------------------------------------------------------
-# ATxmega256A1
-#------------------------------------------------------------
-
-part parent "x256c3"
- id = "x256a1";
- desc = "ATxmega256A1";
- signature = 0x1e 0x98 0x46;
- has_jtag = yes;
-
- memory "fuse0"
- size = 1;
- offset = 0x8f0020;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega256A3
-#------------------------------------------------------------
-
-part parent "x256a1"
- id = "x256a3";
- desc = "ATxmega256A3";
- signature = 0x1e 0x98 0x42;
-;
-
-#------------------------------------------------------------
-# ATxmega256A3U
-#------------------------------------------------------------
-
-part parent "x256a1"
- id = "x256a3u";
- desc = "ATxmega256A3U";
- signature = 0x1e 0x98 0x42;
- usbpid = 0x2fec;
-;
-
-#------------------------------------------------------------
-# ATxmega256A3B
-#------------------------------------------------------------
-
-part parent "x256a1"
- id = "x256a3b";
- desc = "ATxmega256A3B";
- signature = 0x1e 0x98 0x43;
-;
-
-#------------------------------------------------------------
-# ATxmega256A3BU
-#------------------------------------------------------------
-
-part parent "x256a1"
- id = "x256a3bu";
- desc = "ATxmega256A3BU";
- signature = 0x1e 0x98 0x43;
- usbpid = 0x2fe2;
-;
-
-#------------------------------------------------------------
-# ATxmega384C3
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x384c3";
- desc = "ATxmega384C3";
- signature = 0x1e 0x98 0x45;
- usbpid = 0x2fdb;
-
- memory "eeprom"
- size = 0x1000;
- offset = 0x8c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x60000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x2000;
- offset = 0x85e000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x2000;
- offset = 0x860000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x62000;
- offset = 0x800000;
- page_size = 0x200;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x200;
- offset = 0x8e0400;
- page_size = 0x200;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega384D3
-#------------------------------------------------------------
-
-part parent "x384c3"
- id = "x384d3";
- desc = "ATxmega384D3";
- signature = 0x1e 0x98 0x47;
-;
-
-#------------------------------------------------------------
-# ATxmega8E5
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x8e5";
- desc = "ATxmega8E5";
- signature = 0x1e 0x93 0x41;
-
- memory "eeprom"
- size = 0x0200;
- offset = 0x08c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x2000;
- offset = 0x0800000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x800;
- offset = 0x00801800;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x800;
- offset = 0x00802000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x2800;
- offset = 0x0800000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x80;
- offset = 0x8e0400;
- page_size = 0x80;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega16E5
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x16e5";
- desc = "ATxmega16E5";
- signature = 0x1e 0x94 0x45;
-
- memory "eeprom"
- size = 0x0200;
- offset = 0x08c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x4000;
- offset = 0x0800000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x1000;
- offset = 0x00803000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x1000;
- offset = 0x00804000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x5000;
- offset = 0x0800000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x80;
- offset = 0x8e0400;
- page_size = 0x80;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATxmega32E5
-#------------------------------------------------------------
-
-part parent ".xmega"
- id = "x32e5";
- desc = "ATxmega32E5";
- signature = 0x1e 0x95 0x4c;
-
- memory "eeprom"
- size = 0x0400;
- offset = 0x08c0000;
- page_size = 0x20;
- readsize = 0x100;
- ;
-
- memory "application"
- size = 0x8000;
- offset = 0x0800000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "apptable"
- size = 0x1000;
- offset = 0x00807000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "boot"
- size = 0x1000;
- offset = 0x00808000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "flash"
- size = 0x9000;
- offset = 0x0800000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "usersig"
- size = 0x80;
- offset = 0x8e0400;
- page_size = 0x80;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# AVR32UC3A0512
-#------------------------------------------------------------
-
-part
- id = "uc3a0512";
- desc = "AT32UC3A0512";
- signature = 0xED 0xC0 0x3F;
- has_jtag = yes;
- is_avr32 = yes;
-
- memory "flash"
- paged = yes;
- page_size = 512; # bytes
- readsize = 512; # bytes
- num_pages = 1024; # could be set dynamicly
- size = 0x00080000; # could be set dynamicly
- offset = 0x80000000;
- ;
-;
-
-part parent "uc3a0512"
- id = "ucr2";
- desc = "deprecated, use 'uc3a0512'";
-;
-
-#------------------------------------------------------------
-# ATtiny1634.
-#------------------------------------------------------------
-
-part
- id = "t1634";
- desc = "ATtiny1634";
- has_debugwire = yes;
- flash_instr = 0xB6, 0x01, 0x11;
- eeprom_instr = 0xBD, 0xF2, 0xBD, 0xE1, 0xBB, 0xCF, 0xB4, 0x00,
- 0xBE, 0x01, 0xB6, 0x01, 0xBC, 0x00, 0xBB, 0xBF,
- 0x99, 0xF9, 0xBB, 0xAF;
- stk500_devcode = 0x86;
- # avr910_devcode = 0x;
- signature = 0x1e 0x94 0x12;
- pagel = 0xB3;
- bs2 = 0xB1;
- reset = io;
- chip_erase_delay = 9000;
- pgm_enable = "1 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1",
- "x x x x x x x x x x x x x x x x";
-
- chip_erase = "1 0 1 0 1 1 0 0 1 0 0 x x x x x",
- "x x x x x x x x x x x x x x x x";
-
- timeout = 200;
- stabdelay = 100;
- cmdexedelay = 25;
- synchloops = 32;
- bytedelay = 0;
- pollindex = 3;
- pollvalue = 0x53;
- predelay = 1;
- postdelay = 1;
- pollmethod = 1;
-
- pp_controlstack =
- 0x0E, 0x1E, 0x0E, 0x1E, 0x2E, 0x3E, 0x2E, 0x3E,
- 0x4E, 0x5E, 0x4E, 0x5E, 0x6E, 0x7E, 0x6E, 0x7E,
- 0x26, 0x36, 0x66, 0x76, 0x2A, 0x3A, 0x6A, 0x7A,
- 0x2E, 0xFD, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
- hventerstabdelay = 100;
- progmodedelay = 0;
- latchcycles = 0;
- togglevtg = 1;
- poweroffdelay = 15;
- resetdelayms = 1;
- resetdelayus = 0;
- hvleavestabdelay = 15;
- resetdelay = 15;
- chiperasepulsewidth = 0;
- chiperasepolltimeout = 10;
- programfusepulsewidth = 0;
- programfusepolltimeout = 5;
- programlockpulsewidth = 0;
- programlockpolltimeout = 5;
-
- memory "eeprom"
- paged = no;
- page_size = 4;
- size = 256;
- min_write_delay = 3600;
- max_write_delay = 3600;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read = " 1 0 1 0 0 0 0 0",
- " 0 0 0 x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- write = " 1 1 0 0 0 0 0 0",
- " 0 0 0 x x x x a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_lo = " 1 1 0 0 0 0 0 1",
- " 0 0 0 0 0 0 0 0",
- " 0 0 0 0 0 0 a1 a0",
- " i i i i i i i i";
-
- writepage = " 1 1 0 0 0 0 1 0",
- " 0 0 x x x x x a8",
- " a7 a6 a5 a4 a3 a2 0 0",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 5;
- blocksize = 4;
- readsize = 256;
- ;
-
- memory "flash"
- paged = yes;
- size = 16384;
- page_size = 32;
- num_pages = 512;
- min_write_delay = 4500;
- max_write_delay = 4500;
- readback_p1 = 0xff;
- readback_p2 = 0xff;
- read_lo = " 0 0 1 0 0 0 0 0",
- " 0 0 0 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- read_hi = " 0 0 1 0 1 0 0 0",
- " 0 0 0 a12 a11 a10 a9 a8",
- " a7 a6 a5 a4 a3 a2 a1 a0",
- " o o o o o o o o";
-
- loadpage_lo = " 0 1 0 0 0 0 0 0",
- " 0 0 0 x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- loadpage_hi = " 0 1 0 0 1 0 0 0",
- " 0 0 0 x x x x x",
- " x x a5 a4 a3 a2 a1 a0",
- " i i i i i i i i";
-
- writepage = " 0 1 0 0 1 1 0 0",
- " 0 0 0 a12 a11 a10 a9 a8",
- " a7 a6 x x x x x x",
- " x x x x x x x x";
-
- mode = 0x41;
- delay = 6;
- blocksize = 128;
- readsize = 256;
-
- ;
-
- memory "lfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "hfuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 1 0 0 0",
- "x x x x x x x x i i i i i i i i";
- ;
-
- memory "efuse"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0",
- "x x x x x x x x o o o o o o o o";
-
- write = "1 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0",
- "x x x x x x x x x x x i i i i i";
- ;
-
- memory "lock"
- size = 1;
- min_write_delay = 4500;
- max_write_delay = 4500;
- read = "0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0",
- "x x x x x x x x x x x x x x o o";
-
- write = "1 0 1 0 1 1 0 0 1 1 1 x x x x x",
- "x x x x x x x x 1 1 1 1 1 1 i i";
- ;
-
- memory "calibration"
- size = 1;
- read = "0 0 1 1 1 0 0 0 0 0 0 x x x x x",
- "0 0 0 0 0 0 0 0 o o o o o o o o";
- ;
-
- memory "signature"
- size = 3;
- read = "0 0 1 1 0 0 0 0 0 0 0 x x x x x",
- "x x x x x x a1 a0 o o o o o o o o";
- ;
-;
-
-#------------------------------------------------------------
-# Common values for reduced core tinys (4/5/9/10/20/40)
-#------------------------------------------------------------
-
-part
- id = ".reduced_core_tiny";
- desc = "Common values for reduced core tinys";
- has_tpi = yes;
-
- memory "signature"
- size = 3;
- offset = 0x3fc0;
- page_size = 16;
- ;
-
- memory "fuse"
- size = 1;
- offset = 0x3f40;
- page_size = 16;
- blocksize = 4;
- ;
-
- memory "calibration"
- size = 1;
- offset = 0x3f80;
- page_size = 16;
- ;
-
- memory "lockbits"
- size = 1;
- offset = 0x3f00;
- page_size = 16;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny4
-#------------------------------------------------------------
-
-part parent ".reduced_core_tiny"
- id = "t4";
- desc = "ATtiny4";
- signature = 0x1e 0x8f 0x0a;
-
- memory "flash"
- size = 512;
- offset = 0x4000;
- page_size = 16;
- blocksize = 128;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny5
-#------------------------------------------------------------
-
-part parent "t4"
- id = "t5";
- desc = "ATtiny5";
- signature = 0x1e 0x8f 0x09;
-;
-
-#------------------------------------------------------------
-# ATtiny9
-#------------------------------------------------------------
-
-part parent ".reduced_core_tiny"
- id = "t9";
- desc = "ATtiny9";
- signature = 0x1e 0x90 0x08;
-
- memory "flash"
- size = 1024;
- offset = 0x4000;
- page_size = 16;
- blocksize = 128;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny10
-#------------------------------------------------------------
-
-part parent "t9"
- id = "t10";
- desc = "ATtiny10";
- signature = 0x1e 0x90 0x03;
-;
-
-#------------------------------------------------------------
-# ATtiny20
-#------------------------------------------------------------
-
-part parent ".reduced_core_tiny"
- id = "t20";
- desc = "ATtiny20";
- signature = 0x1e 0x91 0x0F;
-
- memory "flash"
- size = 2048;
- offset = 0x4000;
- page_size = 16;
- blocksize = 128;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny40
-#------------------------------------------------------------
-
-part parent ".reduced_core_tiny"
- id = "t40";
- desc = "ATtiny40";
- signature = 0x1e 0x92 0x0E;
-
- memory "flash"
- size = 4096;
- offset = 0x4000;
- page_size = 64;
- blocksize = 128;
- ;
-;
-
-#------------------------------------------------------------
-# ATmega406
-#------------------------------------------------------------
-
-part
- id = "m406";
- desc = "ATMEGA406";
- has_jtag = yes;
- signature = 0x1e 0x95 0x07;
-
- # STK500 parameters (parallel programming IO lines)
- pagel = 0xa7;
- bs2 = 0xa0;
- serial = no;
- parallel = yes;
-
- # STK500v2 HV programming parameters, from XML
- pp_controlstack = 0x0e, 0x1e, 0x0f, 0x1f, 0x2e, 0x3e, 0x2f, 0x3f,
- 0x4e, 0x5e, 0x4f, 0x5f, 0x6e, 0x7e, 0x6f, 0x7f,
- 0x66, 0x76, 0x67, 0x77, 0x6a, 0x7a, 0x6b, 0x7b,
- 0xbe, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00;
-
- # JTAG ICE mkII parameters, also from XML files
- allowfullpagebitstream = no;
- enablepageprogramming = yes;
- idr = 0x51;
- rampz = 0x00;
- spmcr = 0x57;
- eecr = 0x3f;
-
- memory "eeprom"
- paged = no;
- size = 512;
- page_size = 4;
- blocksize = 4;
- readsize = 4;
- num_pages = 128;
- ;
-
- memory "flash"
- paged = yes;
- size = 40960;
- page_size = 128;
- blocksize = 128;
- readsize = 128;
- num_pages = 320;
- ;
-
- memory "hfuse"
- size = 1;
- ;
-
- memory "lfuse"
- size = 1;
- ;
-
- memory "lockbits"
- size = 1;
- ;
-
- memory "signature"
- size = 3;
- ;
-;
-
-#------------------------------------------------------------
-# AVR8X family common values
-#------------------------------------------------------------
-
-part
- id = ".avr8x";
- desc = "AVR8X family common values";
- has_updi = yes;
- nvm_base = 0x1000;
- ocd_base = 0x0F80;
-
- memory "signature"
- size = 3;
- offset = 0x1100;
- ;
-
- memory "prodsig"
- size = 0x3D;
- offset = 0x1103;
- page_size = 0x3D;
- readsize = 0x3D;
- ;
-
- memory "fuses"
- size = 9;
- offset = 0x1280;
- ;
-
- memory "fuse0"
- size = 1;
- offset = 0x1280;
- ;
-
- memory "fuse1"
- size = 1;
- offset = 0x1281;
- ;
-
- memory "fuse2"
- size = 1;
- offset = 0x1282;
- ;
-
- memory "fuse4"
- size = 1;
- offset = 0x1284;
- ;
-
- memory "fuse5"
- size = 1;
- offset = 0x1285;
- ;
-
- memory "fuse6"
- size = 1;
- offset = 0x1286;
- ;
-
- memory "fuse7"
- size = 1;
- offset = 0x1287;
- ;
-
- memory "fuse8"
- size = 1;
- offset = 0x1288;
- ;
-
- memory "lock"
- size = 1;
- offset = 0x128a;
- ;
-
- memory "data"
- # SRAM, only used to supply the offset
- offset = 0x1000000;
- ;
-;
-
-#------------------------------------------------------------
-# AVR8X tiny family common values
-#------------------------------------------------------------
-
-part parent ".avr8x"
- id = ".avr8x_tiny";
- desc = "AVR8X tiny family common values";
- family_id = "tinyAVR";
-
- memory "usersig"
- size = 0x20;
- offset = 0x1300;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# AVR8X mega family common values
-#------------------------------------------------------------
-
-part parent ".avr8x"
- id = ".avr8x_mega";
- desc = "AVR8X mega family common values";
- family_id = "megaAVR";
-
- memory "usersig"
- size = 0x40;
- offset = 0x1300;
- page_size = 0x40;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny202
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t202";
- desc = "ATtiny202";
- signature = 0x1E 0x91 0x23;
-
- memory "flash"
- size = 0x800;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x40;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny204
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t204";
- desc = "ATtiny204";
- signature = 0x1E 0x91 0x22;
-
- memory "flash"
- size = 0x800;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x40;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny402
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t402";
- desc = "ATtiny402";
- signature = 0x1E 0x92 0x23;
-
- memory "flash"
- size = 0x1000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny404
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t404";
- desc = "ATtiny404";
- signature = 0x1E 0x92 0x26;
-
- memory "flash"
- size = 0x1000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny406
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t406";
- desc = "ATtiny406";
- signature = 0x1E 0x92 0x25;
-
- memory "flash"
- size = 0x1000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny804
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t804";
- desc = "ATtiny804";
- signature = 0x1E 0x93 0x25;
-
- memory "flash"
- size = 0x2000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny806
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t806";
- desc = "ATtiny806";
- signature = 0x1E 0x93 0x24;
-
- memory "flash"
- size = 0x2000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny807
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t807";
- desc = "ATtiny807";
- signature = 0x1E 0x93 0x23;
-
- memory "flash"
- size = 0x2000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny1604
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t1604";
- desc = "ATtiny1604";
- signature = 0x1E 0x94 0x25;
-
- memory "flash"
- size = 0x4000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny1606
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t1606";
- desc = "ATtiny1606";
- signature = 0x1E 0x94 0x24;
-
- memory "flash"
- size = 0x4000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny1607
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t1607";
- desc = "ATtiny1607";
- signature = 0x1E 0x94 0x23;
-
- memory "flash"
- size = 0x4000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny212
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t212";
- desc = "ATtiny212";
- signature = 0x1E 0x91 0x21;
-
- memory "flash"
- size = 0x800;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x40;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny214
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t214";
- desc = "ATtiny214";
- signature = 0x1E 0x91 0x20;
-
- memory "flash"
- size = 0x800;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x40;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny412
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t412";
- desc = "ATtiny412";
- signature = 0x1E 0x92 0x23;
-
- memory "flash"
- size = 0x1000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-
-#------------------------------------------------------------
-# ATtiny414
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t414";
- desc = "ATtiny414";
- signature = 0x1E 0x92 0x22;
-
- memory "flash"
- size = 0x1000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny416
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t416";
- desc = "ATtiny416";
- signature = 0x1E 0x92 0x21;
-
- memory "flash"
- size = 0x1000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-
-#------------------------------------------------------------
-# ATtiny417
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t417";
- desc = "ATtiny417";
- signature = 0x1E 0x92 0x20;
-
- memory "flash"
- size = 0x1000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-
-#------------------------------------------------------------
-# ATtiny814
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t814";
- desc = "ATtiny814";
- signature = 0x1E 0x93 0x22;
-
- memory "flash"
- size = 0x2000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-
-#------------------------------------------------------------
-# ATtiny816
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t816";
- desc = "ATtiny816";
- signature = 0x1E 0x93 0x21;
-
- memory "flash"
- size = 0x2000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny817
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t817";
- desc = "ATtiny817";
- signature = 0x1E 0x93 0x20;
-
- memory "flash"
- size = 0x2000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x80;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny1614
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t1614";
- desc = "ATtiny1614";
- signature = 0x1E 0x94 0x22;
-
- memory "flash"
- size = 0x4000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny1616
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t1616";
- desc = "ATtiny1616";
- signature = 0x1E 0x94 0x21;
-
- memory "flash"
- size = 0x4000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny1617
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t1617";
- desc = "ATtiny1617";
- signature = 0x1E 0x94 0x20;
-
- memory "flash"
- size = 0x4000;
- offset = 0x8000;
- page_size = 0x40;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x20;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny3214
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t3214";
- desc = "ATtiny3214";
- signature = 0x1E 0x95 0x20;
-
- memory "flash"
- size = 0x8000;
- offset = 0x8000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x40;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny3216
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t3216";
- desc = "ATtiny3216";
- signature = 0x1E 0x95 0x21;
-
- memory "flash"
- size = 0x8000;
- offset = 0x8000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x40;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATtiny3217
-#------------------------------------------------------------
-
-part parent ".avr8x_tiny"
- id = "t3217";
- desc = "ATtiny3217";
- signature = 0x1E 0x95 0x22;
-
- memory "flash"
- size = 0x8000;
- offset = 0x8000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x40;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATmega3208
-#------------------------------------------------------------
-
-part parent ".avr8x_mega"
- id = "m3208";
- desc = "ATmega3208";
- signature = 0x1E 0x95 0x30;
-
- memory "flash"
- size = 0x8000;
- offset = 0x4000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x40;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATmega3209
-#------------------------------------------------------------
-
-part parent ".avr8x_mega"
- id = "m3209";
- desc = "ATmega3209";
- signature = 0x1E 0x95 0x31;
-
- memory "flash"
- size = 0x8000;
- offset = 0x4000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x40;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATmega4808
-#------------------------------------------------------------
-
-part parent ".avr8x_mega"
- id = "m4808";
- desc = "ATmega4808";
- signature = 0x1E 0x96 0x50;
-
- memory "flash"
- size = 0xC000;
- offset = 0x4000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x40;
- readsize = 0x100;
- ;
-;
-
-#------------------------------------------------------------
-# ATmega4809
-#------------------------------------------------------------
-
-part parent ".avr8x_mega"
- id = "m4809";
- desc = "ATmega4809";
- signature = 0x1E 0x96 0x51;
-
- memory "flash"
- size = 0xC000;
- offset = 0x4000;
- page_size = 0x80;
- readsize = 0x100;
- ;
-
- memory "eeprom"
- size = 0x100;
- offset = 0x1400;
- page_size = 0x40;
- readsize = 0x100;
- ;
-;
diff --git a/megaavr/boards.txt b/megaavr/boards.txt
index 1f9ad9f..74e4904 100644
--- a/megaavr/boards.txt
+++ b/megaavr/boards.txt
@@ -1,7 +1,9 @@
menu.clock=Clock
menu.BOD=BOD
+menu.eeprom=EEPROM
menu.pinout=Pinout
menu.resetpin=Reset pin
+menu.bootloader=Bootloader
####################
@@ -9,42 +11,61 @@ menu.resetpin=Reset pin
####################
# General
-4809.name=Atmega4809
+4809.name=ATmega4809
4809.upload.tool=avrdude
-4809.upload.maximum_size=49152
4809.upload.maximum_data_size=6144
4809.upload.speed=115200
4809.bootloader.tool=avrdude
4809.build.core=coreX-corefiles
4809.build.board=AVR_ATmega4809
4809.build.mcu=atmega4809
+4809.build.extra_flags={build.oscillator} {build.compat}
# Fuses we don't need to modify in the tools menu
4809.bootloader.WDTCFG=0x00
4809.bootloader.TCD0CFG=0x00
4809.bootloader.SYSCFG1=0x06
4809.bootloader.APPEND=0x00
-4809.bootloader.BOOTEND=0x00
4809.bootloader.LOCKBIT=0xC5
# Pinouts
-4809.menu.pinout.uno_wifi=Uno WiFi
-4809.menu.pinout.uno_wifi.build.variant=uno-wifi
-4809.menu.pinout.uno_wifi.build.extra_flags=-DUNO_WIFI_REV2_328MODE
4809.menu.pinout.48pin_standard=48 pin standard
4809.menu.pinout.48pin_standard.build.variant=48pin-standard
+4809.menu.pinout.48pin_standard.build.compat=
+
+4809.menu.pinout.40pin_standard=40 pin standard
+4809.menu.pinout.40pin_standard.build.variant=40pin-standard
+4809.menu.pinout.40pin_standard.build.compat=
+
+4809.menu.pinout.uno_wifi=Uno WiFi
+4809.menu.pinout.uno_wifi.build.variant=uno-wifi
+4809.menu.pinout.uno_wifi.build.compat=
+
+4809.menu.pinout.nano_every=Nano Every
+4809.menu.pinout.nano_every.build.variant=nano-every
+4809.menu.pinout.nano_every.upload.tool=avrdude_nanoevery
+4809.menu.pinout.nano_every.upload.use_1200bps_touch=true
+4809.menu.pinout.nano_every.upload.protocol=jtag2updi
+4809.menu.pinout.nano_every.program.extra_params=-P{serial.port} -e
+4809.menu.pinout.nano_every.build.compat=
+
+# EEPROM
+4809.menu.eeprom.keep=EEPROM retained
+4809.menu.eeprom.keep.bootloader.eesave_bit=1
+4809.menu.eeprom.erase=EEPROM not retained
+4809.menu.eeprom.erase.bootloader.eesave_bit=0
# Reset pin
4809.menu.resetpin.reset=Reset
-4809.menu.resetpin.reset.bootloader.SYSCFG0=0xC9
+4809.menu.resetpin.reset.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
4809.menu.resetpin.gpio=GPIO
-4809.menu.resetpin.gpio.bootloader.SYSCFG0=0xC1
+4809.menu.resetpin.gpio.bootloader.SYSCFG0=0b1100000{bootloader.eesave_bit}
# Brown out detection
4809.menu.BOD.2v6=BOD 2.6V
4809.menu.BOD.2v6.bootloader.BODCFG=0x54
-4809.menu.BOD.4v2=BOD 4.2V
-4809.menu.BOD.4v2.bootloader.BODCFG=0xF4
+4809.menu.BOD.4v3=BOD 4.3V
+4809.menu.BOD.4v3.bootloader.BODCFG=0xF4
4809.menu.BOD.4v0=BOD 4.0V
4809.menu.BOD.4v0.bootloader.BODCFG=0xD4
4809.menu.BOD.3v7=BOD 3.7V
@@ -61,41 +82,186 @@ menu.resetpin=Reset pin
4809.menu.BOD.disabled.bootloader.BODCFG=0x00
# Clock
-4809.menu.clock.16MHz=16 MHz
-4809.menu.clock.16MHz.upload.speed=115200
-4809.menu.clock.16MHz.bootloader.OSCCFG=0x01
-4809.menu.clock.16MHz.build.f_cpu=16000000L
+4809.menu.clock.internal_16MHz=Internal 16 MHz
+4809.menu.clock.internal_16MHz.upload.speed=115200
+4809.menu.clock.internal_16MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.internal_16MHz.build.oscillator=
+4809.menu.clock.internal_16MHz.build.f_cpu=16000000L
+
+4809.menu.clock.internal_20MHz=Internal 20 MHz
+4809.menu.clock.internal_20MHz.upload.speed=115200
+4809.menu.clock.internal_20MHz.bootloader.OSCCFG=0x02
+4809.menu.clock.internal_20MHz.build.oscillator=
+4809.menu.clock.internal_20MHz.build.f_cpu=20000000L
+
+4809.menu.clock.internal_10MHz=Internal 10 MHz
+4809.menu.clock.internal_10MHz.upload.speed=115200
+4809.menu.clock.internal_10MHz.bootloader.OSCCFG=0x02
+4809.menu.clock.internal_10MHz.build.oscillator=
+4809.menu.clock.internal_10MHz.build.f_cpu=10000000L
+
+4809.menu.clock.internal_8MHz=Internal 8 MHz
+4809.menu.clock.internal_8MHz.upload.speed=115200
+4809.menu.clock.internal_8MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.internal_8MHz.build.oscillator=
+4809.menu.clock.internal_8MHz.build.f_cpu=8000000L
+
+4809.menu.clock.internal_5MHz=Internal 5 MHz
+4809.menu.clock.internal_5MHz.upload.speed=115200
+4809.menu.clock.internal_5MHz.bootloader.OSCCFG=0x02
+4809.menu.clock.internal_5MHz.build.oscillator=
+4809.menu.clock.internal_5MHz.build.f_cpu=5000000L
+
+4809.menu.clock.internal_4MHz=Internal 4 MHz
+4809.menu.clock.internal_4MHz.upload.speed=115200
+4809.menu.clock.internal_4MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.internal_4MHz.build.oscillator=
+4809.menu.clock.internal_4MHz.build.f_cpu=4000000L
+
+4809.menu.clock.internal_2MHz=Internal 2 MHz
+4809.menu.clock.internal_2MHz.upload.speed=115200
+4809.menu.clock.internal_2MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.internal_2MHz.build.oscillator=
+4809.menu.clock.internal_2MHz.build.f_cpu=2000000L
-4809.menu.clock.20MHz=20 MHz
-4809.menu.clock.20MHz.upload.speed=115200
-4809.menu.clock.20MHz.bootloader.OSCCFG=0x02
-4809.menu.clock.20MHz.build.f_cpu=20000000L
+4809.menu.clock.internal_1MHz=Internal 1 MHz
+4809.menu.clock.internal_1MHz.upload.speed=115200
+4809.menu.clock.internal_1MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.internal_1MHz.build.oscillator=
+4809.menu.clock.internal_1MHz.build.f_cpu=1000000L
-4809.menu.clock.8MHz_div=8 MHz (divided)
-4809.menu.clock.8MHz_div.upload.speed=115200
-4809.menu.clock.8MHz_div.bootloader.OSCCFG=0x01
-4809.menu.clock.8MHz_div.build.f_cpu=8000000L
+4809.menu.clock.external_20MHz=External 20 MHz
+4809.menu.clock.external_20MHz.upload.speed=115200
+4809.menu.clock.external_20MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.external_20MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4809.menu.clock.external_20MHz.build.f_cpu=20000000L
-4809.menu.clock.4MHz_div=4 MHz (divided)
-4809.menu.clock.4MHz_div.upload.speed=115200
-4809.menu.clock.4MHz_div.bootloader.OSCCFG=0x01
-4809.menu.clock.4MHz_div.build.f_cpu=4000000L
+4809.menu.clock.external_16MHz=External 16 MHz
+4809.menu.clock.external_16MHz.upload.speed=115200
+4809.menu.clock.external_16MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.external_16MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4809.menu.clock.external_16MHz.build.f_cpu=16000000L
-4809.menu.clock.2MHz_div=2 MHz (divided)
-4809.menu.clock.2MHz_div.upload.speed=115200
-4809.menu.clock.2MHz_div.bootloader.OSCCFG=0x01
-4809.menu.clock.2MHz_div.build.f_cpu=2000000L
+4809.menu.clock.external_12MHz=External 12 MHz
+4809.menu.clock.external_12MHz.upload.speed=115200
+4809.menu.clock.external_12MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.external_12MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4809.menu.clock.external_12MHz.build.f_cpu=12000000L
-4809.menu.clock.1MHz_div=1 MHz (divided)
-4809.menu.clock.1MHz_div.upload.speed=115200
-4809.menu.clock.1MHz_div.bootloader.OSCCFG=0x01
-4809.menu.clock.1MHz_div.build.f_cpu=1000000L
+4809.menu.clock.external_8MHz=External 8 MHz
+4809.menu.clock.external_8MHz.upload.speed=115200
+4809.menu.clock.external_8MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.external_8MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4809.menu.clock.external_8MHz.build.f_cpu=8000000L
-# ATmega328 emulation
-#4809.menu.emulation.false=No
-#4809.menu.emulation.true=Yes
-#4809.menu.emulation.true.build.extra_flags=-DUNO_WIFI_REV2_328MODE
+4809.menu.clock.external_4MHz=External 4 MHz
+4809.menu.clock.external_4MHz.upload.speed=115200
+4809.menu.clock.external_4MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.external_4MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4809.menu.clock.external_4MHz.build.f_cpu=4000000L
+4809.menu.clock.external_1MHz=External 1 MHz
+4809.menu.clock.external_1MHz.upload.speed=115200
+4809.menu.clock.external_1MHz.bootloader.OSCCFG=0x01
+4809.menu.clock.external_1MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4809.menu.clock.external_1MHz.build.f_cpu=1000000L
+
+# Bootloader
+4809.menu.bootloader.no_bootloader=No bootloader
+4809.menu.bootloader.no_bootloader.upload.maximum_size=49152
+4809.menu.bootloader.no_bootloader.upload.extra_params=
+4809.menu.bootloader.no_bootloader.build.text_section_start=.text=0x0
+4809.menu.bootloader.no_bootloader.build.export_merged_output=false
+4809.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex
+4809.menu.bootloader.no_bootloader.bootloader.BOOTEND=0x00
+
+4809.menu.bootloader.uart0_default=Optiboot (UART0 default pins)
+4809.menu.bootloader.uart0_default.upload.maximum_size=48640
+4809.menu.bootloader.uart0_default.upload.protocol=arduino
+4809.menu.bootloader.uart0_default.upload.port=UART0_DEF
+4809.menu.bootloader.uart0_default.upload.extra_params=
+4809.menu.bootloader.uart0_default.build.text_section_start=.text=0x200
+4809.menu.bootloader.uart0_default.build.export_merged_output=true
+4809.menu.bootloader.uart0_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4809.menu.bootloader.uart0_default.bootloader.BOOTEND=0x02
+4809.menu.bootloader.uart0_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4809.menu.bootloader.uart0_alternative=Optiboot (UART0 alternative pins)
+4809.menu.bootloader.uart0_alternative.upload.maximum_size=48640
+4809.menu.bootloader.uart0_alternative.upload.protocol=arduino
+4809.menu.bootloader.uart0_alternative.upload.port=UART0_ALT
+4809.menu.bootloader.uart0_alternative.upload.extra_params=
+4809.menu.bootloader.uart0_alternative.build.text_section_start=.text=0x200
+4809.menu.bootloader.uart0_alternative.build.export_merged_output=true
+4809.menu.bootloader.uart0_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4809.menu.bootloader.uart0_alternative.bootloader.BOOTEND=0x02
+4809.menu.bootloader.uart0_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4809.menu.bootloader.uart1_default=Optiboot (UART1 default pins)
+4809.menu.bootloader.uart1_default.upload.maximum_size=48640
+4809.menu.bootloader.uart1_default.upload.protocol=arduino
+4809.menu.bootloader.uart1_default.upload.port=UART1_DEF
+4809.menu.bootloader.uart1_default.upload.extra_params=
+4809.menu.bootloader.uart1_default.build.text_section_start=.text=0x200
+4809.menu.bootloader.uart1_default.build.export_merged_output=true
+4809.menu.bootloader.uart1_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4809.menu.bootloader.uart1_default.bootloader.BOOTEND=0x02
+4809.menu.bootloader.uart1_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4809.menu.bootloader.uart1_alternative=Optiboot (UART1 alternative pins)
+4809.menu.bootloader.uart1_alternative.upload.maximum_size=48640
+4809.menu.bootloader.uart1_alternative.upload.protocol=arduino
+4809.menu.bootloader.uart1_alternative.upload.port=UART1_ALT
+4809.menu.bootloader.uart1_alternative.upload.extra_params=
+4809.menu.bootloader.uart1_alternative.build.text_section_start=.text=0x200
+4809.menu.bootloader.uart1_alternative.build.export_merged_output=true
+4809.menu.bootloader.uart1_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4809.menu.bootloader.uart1_alternative.bootloader.BOOTEND=0x02
+4809.menu.bootloader.uart1_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4809.menu.bootloader.uart2_default=Optiboot (UART2 default pins)
+4809.menu.bootloader.uart2_default.upload.maximum_size=48640
+4809.menu.bootloader.uart2_default.upload.protocol=arduino
+4809.menu.bootloader.uart2_default.upload.port=UART2_DEF
+4809.menu.bootloader.uart2_default.upload.extra_params=
+4809.menu.bootloader.uart2_default.build.text_section_start=.text=0x200
+4809.menu.bootloader.uart2_default.build.export_merged_output=true
+4809.menu.bootloader.uart2_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4809.menu.bootloader.uart2_default.bootloader.BOOTEND=0x02
+4809.menu.bootloader.uart2_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4809.menu.bootloader.uart2_alternative=Optiboot (UART2 alternative pins)
+4809.menu.bootloader.uart2_alternative.upload.maximum_size=48640
+4809.menu.bootloader.uart2_alternative.upload.protocol=arduino
+4809.menu.bootloader.uart2_alternative.upload.port=UART2_ALT
+4809.menu.bootloader.uart2_alternative.upload.extra_params=
+4809.menu.bootloader.uart2_alternative.build.text_section_start=.text=0x200
+4809.menu.bootloader.uart2_alternative.build.export_merged_output=true
+4809.menu.bootloader.uart2_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4809.menu.bootloader.uart2_alternative.bootloader.BOOTEND=0x02
+4809.menu.bootloader.uart2_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4809.menu.bootloader.uart3_default=Optiboot (UART3 default pins)
+4809.menu.bootloader.uart3_default.upload.maximum_size=48640
+4809.menu.bootloader.uart3_default.upload.protocol=arduino
+4809.menu.bootloader.uart3_default.upload.port=UART3_DEF
+4809.menu.bootloader.uart3_default.upload.extra_params=
+4809.menu.bootloader.uart3_default.build.text_section_start=.text=0x200
+4809.menu.bootloader.uart3_default.build.export_merged_output=true
+4809.menu.bootloader.uart3_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4809.menu.bootloader.uart3_default.bootloader.BOOTEND=0x02
+4809.menu.bootloader.uart3_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4809.menu.bootloader.uart3_alternative=Optiboot (UART3 alternative pins)
+4809.menu.bootloader.uart3_alternative.upload.maximum_size=48640
+4809.menu.bootloader.uart3_alternative.upload.protocol=arduino
+4809.menu.bootloader.uart3_alternative.upload.port=UART3_ALT
+4809.menu.bootloader.uart3_alternative.upload.extra_params=
+4809.menu.bootloader.uart3_alternative.build.text_section_start=.text=0x200
+4809.menu.bootloader.uart3_alternative.build.export_merged_output=true
+4809.menu.bootloader.uart3_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4809.menu.bootloader.uart3_alternative.bootloader.BOOTEND=0x02
+4809.menu.bootloader.uart3_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
####################
@@ -103,41 +269,54 @@ menu.resetpin=Reset pin
####################
# General
-4808.name=Atmega4808
+4808.name=ATmega4808
4808.upload.tool=avrdude
-4808.upload.maximum_size=49152
4808.upload.maximum_data_size=6144
4808.upload.speed=115200
4808.bootloader.tool=avrdude
4808.build.core=coreX-corefiles
4808.build.board=AVR_ATmega4808
4808.build.mcu=atmega4808
+4808.build.extra_flags={build.oscillator}
# Fuses we don't need to modify in the tools menu
4808.bootloader.WDTCFG=0x00
4808.bootloader.TCD0CFG=0x00
4808.bootloader.SYSCFG1=0x06
4808.bootloader.APPEND=0x00
-4808.bootloader.BOOTEND=0x00
4808.bootloader.LOCKBIT=0xC5
# Pinouts
4808.menu.pinout.32pin_standard=32 pin standard
4808.menu.pinout.32pin_standard.build.variant=32pin-standard
+
4808.menu.pinout.28pin_standard=28 pin standard
4808.menu.pinout.28pin_standard.build.variant=28pin-standard
+4808.menu.pinout.nano_4808=Nano 4808
+4808.menu.pinout.nano_4808.build.variant=nano-4808
+4808.menu.pinout.nano_4808.upload.tool=avrdude_nanoevery
+4808.menu.pinout.nano_4808.upload.use_1200bps_touch=true
+4808.menu.pinout.nano_4808.upload.protocol=jtag2updi
+4808.menu.pinout.nano_4808.program.extra_params=-P{serial.port} -e
+
+# EEPROM
+4808.menu.eeprom.keep=EEPROM retained
+4808.menu.eeprom.keep.bootloader.eesave_bit=1
+4808.menu.eeprom.erase=EEPROM not retained
+4808.menu.eeprom.erase.bootloader.eesave_bit=0
+
# Reset pin
4808.menu.resetpin.reset=Reset
-4808.menu.resetpin.reset.bootloader.SYSCFG0=0xC9
+4808.menu.resetpin.reset.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
4808.menu.resetpin.gpio=GPIO
-4808.menu.resetpin.gpio.bootloader.SYSCFG0=0xC1
+4808.menu.resetpin.gpio.bootloader.SYSCFG0=0b1100000{bootloader.eesave_bit}
# Brown out detection
4808.menu.BOD.2v6=BOD 2.6V
4808.menu.BOD.2v6.bootloader.BODCFG=0x54
-4808.menu.BOD.4v2=BOD 4.2V
-4808.menu.BOD.4v2.bootloader.BODCFG=0xF4
+4808.menu.BOD.4v3=BOD 4.3V
+4808.menu.BOD.4v3.bootloader.BODCFG=0xF4
4808.menu.BOD.4v0=BOD 4.0V
4808.menu.BOD.4v0.bootloader.BODCFG=0xD4
4808.menu.BOD.3v7=BOD 3.7V
@@ -154,35 +333,158 @@ menu.resetpin=Reset pin
4808.menu.BOD.disabled.bootloader.BODCFG=0x00
# Clock
-4808.menu.clock.16MHz=16 MHz
-4808.menu.clock.16MHz.upload.speed=115200
-4808.menu.clock.16MHz.bootloader.OSCCFG=0x01
-4808.menu.clock.16MHz.build.f_cpu=16000000L
+4808.menu.clock.internal_16MHz=Internal 16 MHz
+4808.menu.clock.internal_16MHz.upload.speed=115200
+4808.menu.clock.internal_16MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.internal_16MHz.build.oscillator=
+4808.menu.clock.internal_16MHz.build.f_cpu=16000000L
+
+4808.menu.clock.internal_20MHz=Internal 20 MHz
+4808.menu.clock.internal_20MHz.upload.speed=115200
+4808.menu.clock.internal_20MHz.bootloader.OSCCFG=0x02
+4808.menu.clock.internal_20MHz.build.oscillator=
+4808.menu.clock.internal_20MHz.build.f_cpu=20000000L
+
+4808.menu.clock.internal_10MHz=Internal 10 MHz
+4808.menu.clock.internal_10MHz.upload.speed=115200
+4808.menu.clock.internal_10MHz.bootloader.OSCCFG=0x02
+4808.menu.clock.internal_10MHz.build.oscillator=
+4808.menu.clock.internal_10MHz.build.f_cpu=10000000L
-4808.menu.clock.20MHz=20 MHz
-4808.menu.clock.20MHz.upload.speed=115200
-4808.menu.clock.20MHz.bootloader.OSCCFG=0x02
-4808.menu.clock.20MHz.build.f_cpu=20000000L
+4808.menu.clock.internal_8MHz=Internal 8 MHz
+4808.menu.clock.internal_8MHz.upload.speed=115200
+4808.menu.clock.internal_8MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.internal_8MHz.build.oscillator=
+4808.menu.clock.internal_8MHz.build.f_cpu=8000000L
-4808.menu.clock.8MHz_div=8 MHz (divided)
-4808.menu.clock.8MHz_div.upload.speed=115200
-4808.menu.clock.8MHz_div.bootloader.OSCCFG=0x01
-4808.menu.clock.8MHz_div.build.f_cpu=8000000L
+4808.menu.clock.internal_5MHz=Internal 5 MHz
+4808.menu.clock.internal_5MHz.upload.speed=115200
+4808.menu.clock.internal_5MHz.bootloader.OSCCFG=0x02
+4808.menu.clock.internal_5MHz.build.oscillator=
+4808.menu.clock.internal_5MHz.build.f_cpu=5000000L
-4808.menu.clock.4MHz_div=4 MHz (divided)
-4808.menu.clock.4MHz_div.upload.speed=115200
-4808.menu.clock.4MHz_div.bootloader.OSCCFG=0x01
-4808.menu.clock.4MHz_div.build.f_cpu=4000000L
+4808.menu.clock.internal_4MHz=Internal 4 MHz
+4808.menu.clock.internal_4MHz.upload.speed=115200
+4808.menu.clock.internal_4MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.internal_4MHz.build.oscillator=
+4808.menu.clock.internal_4MHz.build.f_cpu=4000000L
-4808.menu.clock.2MHz_div=2 MHz (divided)
-4808.menu.clock.2MHz_div.upload.speed=115200
-4808.menu.clock.2MHz_div.bootloader.OSCCFG=0x01
-4808.menu.clock.2MHz_div.build.f_cpu=2000000L
+4808.menu.clock.internal_2MHz=Internal 2 MHz
+4808.menu.clock.internal_2MHz.upload.speed=115200
+4808.menu.clock.internal_2MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.internal_2MHz.build.oscillator=
+4808.menu.clock.internal_2MHz.build.f_cpu=2000000L
-4808.menu.clock.1MHz_div=1 MHz (divided)
-4808.menu.clock.1MHz_div.upload.speed=115200
-4808.menu.clock.1MHz_div.bootloader.OSCCFG=0x01
-4808.menu.clock.1MHz_div.build.f_cpu=1000000L
+4808.menu.clock.internal_1MHz=Internal 1 MHz
+4808.menu.clock.internal_1MHz.upload.speed=115200
+4808.menu.clock.internal_1MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.internal_1MHz.build.oscillator=
+4808.menu.clock.internal_1MHz.build.f_cpu=1000000L
+
+4808.menu.clock.external_16MHz=External 16 MHz
+4808.menu.clock.external_16MHz.upload.speed=115200
+4808.menu.clock.external_16MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.external_16MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4808.menu.clock.external_16MHz.build.f_cpu=16000000L
+
+4808.menu.clock.external_12MHz=External 12 MHz
+4808.menu.clock.external_12MHz.upload.speed=115200
+4808.menu.clock.external_12MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.external_12MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4808.menu.clock.external_12MHz.build.f_cpu=12000000L
+
+4808.menu.clock.external_8MHz=External 8 MHz
+4808.menu.clock.external_8MHz.upload.speed=115200
+4808.menu.clock.external_8MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.external_8MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4808.menu.clock.external_8MHz.build.f_cpu=8000000L
+
+4808.menu.clock.external_4MHz=External 4 MHz
+4808.menu.clock.external_4MHz.upload.speed=115200
+4808.menu.clock.external_4MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.external_4MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4808.menu.clock.external_4MHz.build.f_cpu=4000000L
+
+4808.menu.clock.external_1MHz=External 1 MHz
+4808.menu.clock.external_1MHz.upload.speed=115200
+4808.menu.clock.external_1MHz.bootloader.OSCCFG=0x01
+4808.menu.clock.external_1MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+4808.menu.clock.external_1MHz.build.f_cpu=1000000L
+
+# Bootloader
+4808.menu.bootloader.no_bootloader=No bootloader
+4808.menu.bootloader.no_bootloader.upload.maximum_size=49152
+4808.menu.bootloader.no_bootloader.upload.extra_params=
+4808.menu.bootloader.no_bootloader.build.text_section_start=.text=0x0
+4808.menu.bootloader.no_bootloader.build.export_merged_output=false
+4808.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex
+4808.menu.bootloader.no_bootloader.bootloader.BOOTEND=0x00
+
+4808.menu.bootloader.uart0_default=Optiboot (UART0 default pins)
+4808.menu.bootloader.uart0_default.upload.maximum_size=48640
+4808.menu.bootloader.uart0_default.upload.protocol=arduino
+4808.menu.bootloader.uart0_default.upload.port=UART0_DEF
+4808.menu.bootloader.uart0_default.upload.extra_params=
+4808.menu.bootloader.uart0_default.build.text_section_start=.text=0x200
+4808.menu.bootloader.uart0_default.build.export_merged_output=true
+4808.menu.bootloader.uart0_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4808.menu.bootloader.uart0_default.bootloader.BOOTEND=0x02
+4808.menu.bootloader.uart0_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4808.menu.bootloader.uart0_alternative=Optiboot (UART0 alternative pins)
+4808.menu.bootloader.uart0_alternative.upload.maximum_size=48640
+4808.menu.bootloader.uart0_alternative.upload.protocol=arduino
+4808.menu.bootloader.uart0_alternative.upload.port=UART0_ALT
+4808.menu.bootloader.uart0_alternative.upload.extra_params=
+4808.menu.bootloader.uart0_alternative.build.text_section_start=.text=0x200
+4808.menu.bootloader.uart0_alternative.build.export_merged_output=true
+4808.menu.bootloader.uart0_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4808.menu.bootloader.uart0_alternative.bootloader.BOOTEND=0x02
+4808.menu.bootloader.uart0_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4808.menu.bootloader.uart1_default=Optiboot (UART1 default pins)
+4808.menu.bootloader.uart1_default.upload.maximum_size=48640
+4808.menu.bootloader.uart1_default.upload.protocol=arduino
+4808.menu.bootloader.uart1_default.upload.port=UART1_DEF
+4808.menu.bootloader.uart1_default.upload.extra_params=
+4808.menu.bootloader.uart1_default.build.text_section_start=.text=0x200
+4808.menu.bootloader.uart1_default.build.export_merged_output=true
+4808.menu.bootloader.uart1_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4808.menu.bootloader.uart1_default.bootloader.BOOTEND=0x02
+4808.menu.bootloader.uart1_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4808.menu.bootloader.uart1_alternative=Optiboot (UART1 alternative pins)
+4808.menu.bootloader.uart1_alternative.upload.maximum_size=48640
+4808.menu.bootloader.uart1_alternative.upload.protocol=arduino
+4808.menu.bootloader.uart1_alternative.upload.port=UART1_ALT
+4808.menu.bootloader.uart1_alternative.upload.extra_params=
+4808.menu.bootloader.uart1_alternative.build.text_section_start=.text=0x200
+4808.menu.bootloader.uart1_alternative.build.export_merged_output=true
+4808.menu.bootloader.uart1_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4808.menu.bootloader.uart1_alternative.bootloader.BOOTEND=0x02
+4808.menu.bootloader.uart1_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4808.menu.bootloader.uart2_default=Optiboot (UART2 default pins)
+4808.menu.bootloader.uart2_default.upload.maximum_size=48640
+4808.menu.bootloader.uart2_default.upload.protocol=arduino
+4808.menu.bootloader.uart2_default.upload.port=UART2_DEF
+4808.menu.bootloader.uart2_default.upload.extra_params=
+4808.menu.bootloader.uart2_default.build.text_section_start=.text=0x200
+4808.menu.bootloader.uart2_default.build.export_merged_output=true
+4808.menu.bootloader.uart2_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4808.menu.bootloader.uart2_default.bootloader.BOOTEND=0x02
+4808.menu.bootloader.uart2_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+4808.menu.bootloader.uart2_alternative=Optiboot (UART2 alternative pins)
+4808.menu.bootloader.uart2_alternative.upload.maximum_size=48640
+4808.menu.bootloader.uart2_alternative.upload.protocol=arduino
+4808.menu.bootloader.uart2_alternative.upload.port=UART2_ALT
+4808.menu.bootloader.uart2_alternative.upload.extra_params=
+4808.menu.bootloader.uart2_alternative.build.text_section_start=.text=0x200
+4808.menu.bootloader.uart2_alternative.build.export_merged_output=true
+4808.menu.bootloader.uart2_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+4808.menu.bootloader.uart2_alternative.bootloader.BOOTEND=0x02
+4808.menu.bootloader.uart2_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
@@ -191,42 +493,48 @@ menu.resetpin=Reset pin
#####################
# General
-3209.name=Atmega3209
+3209.name=ATmega3209
3209.upload.tool=avrdude
-3209.upload.maximum_size=32768
3209.upload.maximum_data_size=4096
3209.upload.speed=115200
3209.bootloader.tool=avrdude
3209.build.core=coreX-corefiles
3209.build.board=AVR_ATmega3209
3209.build.mcu=atmega3209
+3209.build.extra_flags={build.oscillator} {build.compat}
# Fuses we don't need to modify in the tools menu
3209.bootloader.WDTCFG=0x00
3209.bootloader.TCD0CFG=0x00
3209.bootloader.SYSCFG1=0x06
3209.bootloader.APPEND=0x00
-3209.bootloader.BOOTEND=0x00
3209.bootloader.LOCKBIT=0xC5
# Pinouts
-3209.menu.pinout.uno_wifi=Uno WiFi
-3209.menu.pinout.uno_wifi.build.variant=uno-wifi
-3209.menu.pinout.uno_wifi.build.extra_flags=-DUNO_WIFI_REV2_328MODE
3209.menu.pinout.48pin_standard=48 pin standard
3209.menu.pinout.48pin_standard.build.variant=48pin-standard
+3209.menu.pinout.48pin_standard.build.compat=
+3209.menu.pinout.uno_wifi=Uno WiFi
+3209.menu.pinout.uno_wifi.build.variant=uno-wifi
+3209.menu.pinout.uno_wifi.build.compat=
+
+# EEPROM
+3209.menu.eeprom.keep=EEPROM retained
+3209.menu.eeprom.keep.bootloader.eesave_bit=1
+3209.menu.eeprom.erase=EEPROM not retained
+3209.menu.eeprom.erase.bootloader.eesave_bit=0
# Reset pin
3209.menu.resetpin.reset=Reset
-3209.menu.resetpin.reset.bootloader.SYSCFG0=0xC9
+3209.menu.resetpin.reset.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
3209.menu.resetpin.gpio=GPIO
-3209.menu.resetpin.gpio.bootloader.SYSCFG0=0xC1
+3209.menu.resetpin.gpio.bootloader.SYSCFG0=0b1100000{bootloader.eesave_bit}
# Brown out detection
3209.menu.BOD.2v6=BOD 2.6V
3209.menu.BOD.2v6.bootloader.BODCFG=0x54
-3209.menu.BOD.4v2=BOD 4.2V
-3209.menu.BOD.4v2.bootloader.BODCFG=0xF4
+3209.menu.BOD.4v3=BOD 4.3V
+3209.menu.BOD.4v3.bootloader.BODCFG=0xF4
3209.menu.BOD.4v0=BOD 4.0V
3209.menu.BOD.4v0.bootloader.BODCFG=0xD4
3209.menu.BOD.3v7=BOD 3.7V
@@ -243,41 +551,180 @@ menu.resetpin=Reset pin
3209.menu.BOD.disabled.bootloader.BODCFG=0x00
# Clock
-3209.menu.clock.16MHz=16 MHz
-3209.menu.clock.16MHz.upload.speed=115200
-3209.menu.clock.16MHz.bootloader.OSCCFG=0x01
-3209.menu.clock.16MHz.build.f_cpu=16000000L
+3209.menu.clock.internal_16MHz=Internal 16 MHz
+3209.menu.clock.internal_16MHz.upload.speed=115200
+3209.menu.clock.internal_16MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.internal_16MHz.build.oscillator=
+3209.menu.clock.internal_16MHz.build.f_cpu=16000000L
+
+3209.menu.clock.internal_20MHz=Internal 20 MHz
+3209.menu.clock.internal_20MHz.upload.speed=115200
+3209.menu.clock.internal_20MHz.bootloader.OSCCFG=0x02
+3209.menu.clock.internal_20MHz.build.oscillator=
+3209.menu.clock.internal_20MHz.build.f_cpu=20000000L
+
+3209.menu.clock.internal_10MHz=Internal 10 MHz
+3209.menu.clock.internal_10MHz.upload.speed=115200
+3209.menu.clock.internal_10MHz.bootloader.OSCCFG=0x02
+3209.menu.clock.internal_10MHz.build.oscillator=
+3209.menu.clock.internal_10MHz.build.f_cpu=10000000L
+
+3209.menu.clock.internal_8MHz=Internal 8 MHz
+3209.menu.clock.internal_8MHz.upload.speed=115200
+3209.menu.clock.internal_8MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.internal_8MHz.build.oscillator=
+3209.menu.clock.internal_8MHz.build.f_cpu=8000000L
+
+3209.menu.clock.internal_5MHz=Internal 5 MHz
+3209.menu.clock.internal_5MHz.upload.speed=115200
+3209.menu.clock.internal_5MHz.bootloader.OSCCFG=0x02
+3209.menu.clock.internal_5MHz.build.oscillator=
+3209.menu.clock.internal_5MHz.build.f_cpu=5000000L
+
+3209.menu.clock.internal_4MHz=Internal 4 MHz
+3209.menu.clock.internal_4MHz.upload.speed=115200
+3209.menu.clock.internal_4MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.internal_4MHz.build.oscillator=
+3209.menu.clock.internal_4MHz.build.f_cpu=4000000L
+
+3209.menu.clock.internal_2MHz=Internal 2 MHz
+3209.menu.clock.internal_2MHz.upload.speed=115200
+3209.menu.clock.internal_2MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.internal_2MHz.build.oscillator=
+3209.menu.clock.internal_2MHz.build.f_cpu=2000000L
+
+3209.menu.clock.internal_1MHz=Internal 1 MHz
+3209.menu.clock.internal_1MHz.upload.speed=115200
+3209.menu.clock.internal_1MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.internal_1MHz.build.oscillator=
+3209.menu.clock.internal_1MHz.build.f_cpu=1000000L
+
+3209.menu.clock.external_16MHz=External 16 MHz
+3209.menu.clock.external_16MHz.upload.speed=115200
+3209.menu.clock.external_16MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.external_16MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3209.menu.clock.external_16MHz.build.f_cpu=16000000L
+
+3209.menu.clock.external_12MHz=External 12 MHz
+3209.menu.clock.external_12MHz.upload.speed=115200
+3209.menu.clock.external_12MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.external_12MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3209.menu.clock.external_12MHz.build.f_cpu=12000000L
+
+3209.menu.clock.external_8MHz=External 8 MHz
+3209.menu.clock.external_8MHz.upload.speed=115200
+3209.menu.clock.external_8MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.external_8MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3209.menu.clock.external_8MHz.build.f_cpu=8000000L
+
+3209.menu.clock.external_4MHz=External 4 MHz
+3209.menu.clock.external_4MHz.upload.speed=115200
+3209.menu.clock.external_4MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.external_4MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3209.menu.clock.external_4MHz.build.f_cpu=4000000L
-3209.menu.clock.20MHz=20 MHz
-3209.menu.clock.20MHz.upload.speed=115200
-3209.menu.clock.20MHz.bootloader.OSCCFG=0x02
-3209.menu.clock.20MHz.build.f_cpu=20000000L
+3209.menu.clock.external_1MHz=External 1 MHz
+3209.menu.clock.external_1MHz.upload.speed=115200
+3209.menu.clock.external_1MHz.bootloader.OSCCFG=0x01
+3209.menu.clock.external_1MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3209.menu.clock.external_1MHz.build.f_cpu=1000000L
-3209.menu.clock.8MHz_div=8 MHz (divided)
-3209.menu.clock.8MHz_div.upload.speed=115200
-3209.menu.clock.8MHz_div.bootloader.OSCCFG=0x01
-3209.menu.clock.8MHz_div.build.f_cpu=8000000L
+# Bootloader
+3209.menu.bootloader.no_bootloader=No bootloader
+3209.menu.bootloader.no_bootloader.upload.maximum_size=32768
+3209.menu.bootloader.no_bootloader.upload.extra_params=
+3209.menu.bootloader.no_bootloader.build.text_section_start=.text=0x0
+3209.menu.bootloader.no_bootloader.build.export_merged_output=false
+3209.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex
+3209.menu.bootloader.no_bootloader.bootloader.BOOTEND=0x00
-3209.menu.clock.4MHz_div=4 MHz (divided)
-3209.menu.clock.4MHz_div.upload.speed=115200
-3209.menu.clock.4MHz_div.bootloader.OSCCFG=0x01
-3209.menu.clock.4MHz_div.build.f_cpu=4000000L
+3209.menu.bootloader.uart0_default=Optiboot (UART0 default pins)
+3209.menu.bootloader.uart0_default.upload.maximum_size=32256
+3209.menu.bootloader.uart0_default.upload.protocol=arduino
+3209.menu.bootloader.uart0_default.upload.port=UART0_DEF
+3209.menu.bootloader.uart0_default.upload.extra_params=
+3209.menu.bootloader.uart0_default.build.text_section_start=.text=0x200
+3209.menu.bootloader.uart0_default.build.export_merged_output=true
+3209.menu.bootloader.uart0_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3209.menu.bootloader.uart0_default.bootloader.BOOTEND=0x02
+3209.menu.bootloader.uart0_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
-3209.menu.clock.2MHz_div=2 MHz (divided)
-3209.menu.clock.2MHz_div.upload.speed=115200
-3209.menu.clock.2MHz_div.bootloader.OSCCFG=0x01
-3209.menu.clock.2MHz_div.build.f_cpu=2000000L
+3209.menu.bootloader.uart0_alternative=Optiboot (UART0 alternative pins)
+3209.menu.bootloader.uart0_alternative.upload.maximum_size=32256
+3209.menu.bootloader.uart0_alternative.upload.protocol=arduino
+3209.menu.bootloader.uart0_alternative.upload.port=UART0_ALT
+3209.menu.bootloader.uart0_alternative.upload.extra_params=
+3209.menu.bootloader.uart0_alternative.build.text_section_start=.text=0x200
+3209.menu.bootloader.uart0_alternative.build.export_merged_output=true
+3209.menu.bootloader.uart0_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3209.menu.bootloader.uart0_alternative.bootloader.BOOTEND=0x02
+3209.menu.bootloader.uart0_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
-3209.menu.clock.1MHz_div=1 MHz (divided)
-3209.menu.clock.1MHz_div.upload.speed=115200
-3209.menu.clock.1MHz_div.bootloader.OSCCFG=0x01
-3209.menu.clock.1MHz_div.build.f_cpu=1000000L
+3209.menu.bootloader.uart1_default=Optiboot (UART1 default pins)
+3209.menu.bootloader.uart1_default.upload.maximum_size=32256
+3209.menu.bootloader.uart1_default.upload.protocol=arduino
+3209.menu.bootloader.uart1_default.upload.port=UART1_DEF
+3209.menu.bootloader.uart1_default.upload.extra_params=
+3209.menu.bootloader.uart1_default.build.text_section_start=.text=0x200
+3209.menu.bootloader.uart1_default.build.export_merged_output=true
+3209.menu.bootloader.uart1_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3209.menu.bootloader.uart1_default.bootloader.BOOTEND=0x02
+3209.menu.bootloader.uart1_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
-# ATmega328 emulation
-3209.menu.emulation.false=No
-3209.menu.emulation.true=Yes
-3209.menu.emulation.true.build.extra_flags=-DUNO_WIFI_REV2_328MODE
+3209.menu.bootloader.uart1_alternative=Optiboot (UART1 alternative pins)
+3209.menu.bootloader.uart1_alternative.upload.maximum_size=32256
+3209.menu.bootloader.uart1_alternative.upload.protocol=arduino
+3209.menu.bootloader.uart1_alternative.upload.port=UART1_ALT
+3209.menu.bootloader.uart1_alternative.upload.extra_params=
+3209.menu.bootloader.uart1_alternative.build.text_section_start=.text=0x200
+3209.menu.bootloader.uart1_alternative.build.export_merged_output=true
+3209.menu.bootloader.uart1_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3209.menu.bootloader.uart1_alternative.bootloader.BOOTEND=0x02
+3209.menu.bootloader.uart1_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+3209.menu.bootloader.uart2_default=Optiboot (UART2 default pins)
+3209.menu.bootloader.uart2_default.upload.maximum_size=32256
+3209.menu.bootloader.uart2_default.upload.protocol=arduino
+3209.menu.bootloader.uart2_default.upload.port=UART2_DEF
+3209.menu.bootloader.uart2_default.upload.extra_params=
+3209.menu.bootloader.uart2_default.build.text_section_start=.text=0x200
+3209.menu.bootloader.uart2_default.build.export_merged_output=true
+3209.menu.bootloader.uart2_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3209.menu.bootloader.uart2_default.bootloader.BOOTEND=0x02
+3209.menu.bootloader.uart2_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+3209.menu.bootloader.uart2_alternative=Optiboot (UART2 alternative pins)
+3209.menu.bootloader.uart2_alternative.upload.maximum_size=32256
+3209.menu.bootloader.uart2_alternative.upload.protocol=arduino
+3209.menu.bootloader.uart2_alternative.upload.port=UART2_ALT
+3209.menu.bootloader.uart2_alternative.upload.extra_params=
+3209.menu.bootloader.uart2_alternative.build.text_section_start=.text=0x200
+3209.menu.bootloader.uart2_alternative.build.export_merged_output=true
+3209.menu.bootloader.uart2_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3209.menu.bootloader.uart2_alternative.bootloader.BOOTEND=0x02
+3209.menu.bootloader.uart2_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+3209.menu.bootloader.uart3_default=Optiboot (UART3 default pins)
+3209.menu.bootloader.uart3_default.upload.maximum_size=32256
+3209.menu.bootloader.uart3_default.upload.protocol=arduino
+3209.menu.bootloader.uart3_default.upload.port=UART3_DEF
+3209.menu.bootloader.uart3_default.upload.extra_params=
+3209.menu.bootloader.uart3_default.build.text_section_start=.text=0x200
+3209.menu.bootloader.uart3_default.build.export_merged_output=true
+3209.menu.bootloader.uart3_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3209.menu.bootloader.uart3_default.bootloader.BOOTEND=0x02
+3209.menu.bootloader.uart3_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+3209.menu.bootloader.uart3_alternative=Optiboot (UART3 alternative pins)
+3209.menu.bootloader.uart3_alternative.upload.maximum_size=32256
+3209.menu.bootloader.uart3_alternative.upload.protocol=arduino
+3209.menu.bootloader.uart3_alternative.upload.port=UART3_ALT
+3209.menu.bootloader.uart3_alternative.upload.extra_params=
+3209.menu.bootloader.uart3_alternative.build.text_section_start=.text=0x200
+3209.menu.bootloader.uart3_alternative.build.export_merged_output=true
+3209.menu.bootloader.uart3_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3209.menu.bootloader.uart3_alternative.bootloader.BOOTEND=0x02
+3209.menu.bootloader.uart3_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
####################
@@ -285,22 +732,21 @@ menu.resetpin=Reset pin
####################
# General
-3208.name=Atmega3208
+3208.name=ATmega3208
3208.upload.tool=avrdude
-3208.upload.maximum_size=32768
3208.upload.maximum_data_size=4096
3208.upload.speed=115200
3208.bootloader.tool=avrdude
3208.build.core=coreX-corefiles
3208.build.board=AVR_ATmega3208
3208.build.mcu=atmega3208
+3208.build.extra_flags={build.oscillator}
# Fuses we don't need to modify in the tools menu
3208.bootloader.WDTCFG=0x00
3208.bootloader.TCD0CFG=0x00
3208.bootloader.SYSCFG1=0x06
3208.bootloader.APPEND=0x00
-3208.bootloader.BOOTEND=0x00
3208.bootloader.LOCKBIT=0xC5
# Pinouts
@@ -309,17 +755,23 @@ menu.resetpin=Reset pin
3208.menu.pinout.28pin_standard=28 pin standard
3208.menu.pinout.28pin_standard.build.variant=28pin-standard
+# EEPROM
+3208.menu.eeprom.keep=EEPROM retained
+3208.menu.eeprom.keep.bootloader.eesave_bit=1
+3208.menu.eeprom.erase=EEPROM not retained
+3208.menu.eeprom.erase.bootloader.eesave_bit=0
+
# Reset pin
3208.menu.resetpin.reset=Reset
-3208.menu.resetpin.reset.bootloader.SYSCFG0=0xC9
+3208.menu.resetpin.reset.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
3208.menu.resetpin.gpio=GPIO
-3208.menu.resetpin.gpio.bootloader.SYSCFG0=0xC1
+3208.menu.resetpin.gpio.bootloader.SYSCFG0=0b1100000{bootloader.eesave_bit}
# Brown out detection
3208.menu.BOD.2v6=BOD 2.6V
3208.menu.BOD.2v6.bootloader.BODCFG=0x54
-3208.menu.BOD.4v2=BOD 4.2V
-3208.menu.BOD.4v2.bootloader.BODCFG=0xF4
+3208.menu.BOD.4v3=BOD 4.3V
+3208.menu.BOD.4v3.bootloader.BODCFG=0xF4
3208.menu.BOD.4v0=BOD 4.0V
3208.menu.BOD.4v0.bootloader.BODCFG=0xD4
3208.menu.BOD.3v7=BOD 3.7V
@@ -336,33 +788,1063 @@ menu.resetpin=Reset pin
3208.menu.BOD.disabled.bootloader.BODCFG=0x00
# Clock
-3208.menu.clock.16MHz=16 MHz
-3208.menu.clock.16MHz.upload.speed=115200
-3208.menu.clock.16MHz.bootloader.OSCCFG=0x01
-3208.menu.clock.16MHz.build.f_cpu=16000000L
-
-3208.menu.clock.20MHz=20 MHz
-3208.menu.clock.20MHz.upload.speed=115200
-3208.menu.clock.20MHz.bootloader.OSCCFG=0x02
-3208.menu.clock.20MHz.build.f_cpu=20000000L
-
-3208.menu.clock.8MHz_div=8 MHz (divided)
-3208.menu.clock.8MHz_div.upload.speed=115200
-3208.menu.clock.8MHz_div.bootloader.OSCCFG=0x01
-3208.menu.clock.8MHz_div.build.f_cpu=8000000L
-
-3208.menu.clock.4MHz_div=4 MHz (divided)
-3208.menu.clock.4MHz_div.upload.speed=115200
-3208.menu.clock.4MHz_div.bootloader.OSCCFG=0x01
-3208.menu.clock.4MHz_div.build.f_cpu=4000000L
-
-3208.menu.clock.2MHz_div=2 MHz (divided)
-3208.menu.clock.2MHz_div.upload.speed=115200
-3208.menu.clock.2MHz_div.bootloader.OSCCFG=0x01
-3208.menu.clock.2MHz_div.build.f_cpu=2000000L
-
-3208.menu.clock.1MHz_div=1 MHz (divided)
-3208.menu.clock.1MHz_div.upload.speed=115200
-3208.menu.clock.1MHz_div.bootloader.OSCCFG=0x01
-3208.menu.clock.1MHz_div.build.f_cpu=1000000L
+3208.menu.clock.internal_16MHz=Internal 16 MHz
+3208.menu.clock.internal_16MHz.upload.speed=115200
+3208.menu.clock.internal_16MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.internal_16MHz.build.oscillator=
+3208.menu.clock.internal_16MHz.build.f_cpu=16000000L
+
+3208.menu.clock.internal_20MHz=Internal 20 MHz
+3208.menu.clock.internal_20MHz.upload.speed=115200
+3208.menu.clock.internal_20MHz.bootloader.OSCCFG=0x02
+3208.menu.clock.internal_20MHz.build.oscillator=
+3208.menu.clock.internal_20MHz.build.f_cpu=20000000L
+
+3208.menu.clock.internal_10MHz=Internal 10 MHz
+3208.menu.clock.internal_10MHz.upload.speed=115200
+3208.menu.clock.internal_10MHz.bootloader.OSCCFG=0x02
+3208.menu.clock.internal_10MHz.build.oscillator=
+3208.menu.clock.internal_10MHz.build.f_cpu=10000000L
+
+3208.menu.clock.internal_8MHz=Internal 8 MHz
+3208.menu.clock.internal_8MHz.upload.speed=115200
+3208.menu.clock.internal_8MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.internal_8MHz.build.oscillator=
+3208.menu.clock.internal_8MHz.build.f_cpu=8000000L
+
+3208.menu.clock.internal_5MHz=Internal 5 MHz
+3208.menu.clock.internal_5MHz.upload.speed=115200
+3208.menu.clock.internal_5MHz.bootloader.OSCCFG=0x02
+3208.menu.clock.internal_5MHz.build.oscillator=
+3208.menu.clock.internal_5MHz.build.f_cpu=5000000L
+
+3208.menu.clock.internal_4MHz=Internal 4 MHz
+3208.menu.clock.internal_4MHz.upload.speed=115200
+3208.menu.clock.internal_4MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.internal_4MHz.build.oscillator=
+3208.menu.clock.internal_4MHz.build.f_cpu=4000000L
+
+3208.menu.clock.internal_2MHz=Internal 2 MHz
+3208.menu.clock.internal_2MHz.upload.speed=115200
+3208.menu.clock.internal_2MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.internal_2MHz.build.oscillator=
+3208.menu.clock.internal_2MHz.build.f_cpu=2000000L
+
+3208.menu.clock.internal_1MHz=Internal 1 MHz
+3208.menu.clock.internal_1MHz.upload.speed=115200
+3208.menu.clock.internal_1MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.internal_1MHz.build.oscillator=
+3208.menu.clock.internal_1MHz.build.f_cpu=1000000L
+
+3208.menu.clock.external_16MHz=External 16 MHz
+3208.menu.clock.external_16MHz.upload.speed=115200
+3208.menu.clock.external_16MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.external_16MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3208.menu.clock.external_16MHz.build.f_cpu=16000000L
+
+3208.menu.clock.external_12MHz=External 12 MHz
+3208.menu.clock.external_12MHz.upload.speed=115200
+3208.menu.clock.external_12MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.external_12MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3208.menu.clock.external_12MHz.build.f_cpu=12000000L
+
+3208.menu.clock.external_8MHz=External 8 MHz
+3208.menu.clock.external_8MHz.upload.speed=115200
+3208.menu.clock.external_8MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.external_8MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3208.menu.clock.external_8MHz.build.f_cpu=8000000L
+
+3208.menu.clock.external_4MHz=External 4 MHz
+3208.menu.clock.external_4MHz.upload.speed=115200
+3208.menu.clock.external_4MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.external_4MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3208.menu.clock.external_4MHz.build.f_cpu=4000000L
+
+3208.menu.clock.external_1MHz=External 1 MHz
+3208.menu.clock.external_1MHz.upload.speed=115200
+3208.menu.clock.external_1MHz.bootloader.OSCCFG=0x01
+3208.menu.clock.external_1MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+3208.menu.clock.external_1MHz.build.f_cpu=1000000L
+
+# Bootloader
+3208.menu.bootloader.no_bootloader=No bootloader
+3208.menu.bootloader.no_bootloader.upload.maximum_size=32768
+3208.menu.bootloader.no_bootloader.upload.extra_params=
+3208.menu.bootloader.no_bootloader.build.text_section_start=.text=0x0
+3208.menu.bootloader.no_bootloader.build.export_merged_output=false
+3208.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex
+3208.menu.bootloader.no_bootloader.bootloader.BOOTEND=0x00
+
+3208.menu.bootloader.uart0_default=Optiboot (UART0 default pins)
+3208.menu.bootloader.uart0_default.upload.maximum_size=32256
+3208.menu.bootloader.uart0_default.upload.protocol=arduino
+3208.menu.bootloader.uart0_default.upload.port=UART0_DEF
+3208.menu.bootloader.uart0_default.upload.extra_params=
+3208.menu.bootloader.uart0_default.build.text_section_start=.text=0x200
+3208.menu.bootloader.uart0_default.build.export_merged_output=true
+3208.menu.bootloader.uart0_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3208.menu.bootloader.uart0_default.bootloader.BOOTEND=0x02
+3208.menu.bootloader.uart0_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+3208.menu.bootloader.uart0_alternative=Optiboot (UART0 alternative pins)
+3208.menu.bootloader.uart0_alternative.upload.maximum_size=32256
+3208.menu.bootloader.uart0_alternative.upload.protocol=arduino
+3208.menu.bootloader.uart0_alternative.upload.port=UART0_ALT
+3208.menu.bootloader.uart0_alternative.upload.extra_params=
+3208.menu.bootloader.uart0_alternative.build.text_section_start=.text=0x200
+3208.menu.bootloader.uart0_alternative.build.export_merged_output=true
+3208.menu.bootloader.uart0_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3208.menu.bootloader.uart0_alternative.bootloader.BOOTEND=0x02
+3208.menu.bootloader.uart0_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+3208.menu.bootloader.uart1_default=Optiboot (UART1 default pins)
+3208.menu.bootloader.uart1_default.upload.maximum_size=32256
+3208.menu.bootloader.uart1_default.upload.protocol=arduino
+3208.menu.bootloader.uart1_default.upload.port=UART1_DEF
+3208.menu.bootloader.uart1_default.upload.extra_params=
+3208.menu.bootloader.uart1_default.build.text_section_start=.text=0x200
+3208.menu.bootloader.uart1_default.build.export_merged_output=true
+3208.menu.bootloader.uart1_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3208.menu.bootloader.uart1_default.bootloader.BOOTEND=0x02
+3208.menu.bootloader.uart1_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+3208.menu.bootloader.uart1_alternative=Optiboot (UART1 alternative pins)
+3208.menu.bootloader.uart1_alternative.upload.maximum_size=32256
+3208.menu.bootloader.uart1_alternative.upload.protocol=arduino
+3208.menu.bootloader.uart1_alternative.upload.port=UART1_ALT
+3208.menu.bootloader.uart1_alternative.upload.extra_params=
+3208.menu.bootloader.uart1_alternative.build.text_section_start=.text=0x200
+3208.menu.bootloader.uart1_alternative.build.export_merged_output=true
+3208.menu.bootloader.uart1_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3208.menu.bootloader.uart1_alternative.bootloader.BOOTEND=0x02
+3208.menu.bootloader.uart1_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+3208.menu.bootloader.uart2_default=Optiboot (UART2 default pins)
+3208.menu.bootloader.uart2_default.upload.maximum_size=32256
+3208.menu.bootloader.uart2_default.upload.protocol=arduino
+3208.menu.bootloader.uart2_default.upload.port=UART2_DEF
+3208.menu.bootloader.uart2_default.upload.extra_params=
+3208.menu.bootloader.uart2_default.build.text_section_start=.text=0x200
+3208.menu.bootloader.uart2_default.build.export_merged_output=true
+3208.menu.bootloader.uart2_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3208.menu.bootloader.uart2_default.bootloader.BOOTEND=0x02
+3208.menu.bootloader.uart2_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+3208.menu.bootloader.uart2_alternative=Optiboot (UART2 alternative pins)
+3208.menu.bootloader.uart2_alternative.upload.maximum_size=32256
+3208.menu.bootloader.uart2_alternative.upload.protocol=arduino
+3208.menu.bootloader.uart2_alternative.upload.port=UART2_ALT
+3208.menu.bootloader.uart2_alternative.upload.extra_params=
+3208.menu.bootloader.uart2_alternative.build.text_section_start=.text=0x200
+3208.menu.bootloader.uart2_alternative.build.export_merged_output=true
+3208.menu.bootloader.uart2_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+3208.menu.bootloader.uart2_alternative.bootloader.BOOTEND=0x02
+3208.menu.bootloader.uart2_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+
+#####################
+#### ATmega1609 ####
+#####################
+
+# General
+1609.name=ATmega1609
+1609.upload.tool=avrdude
+1609.upload.maximum_data_size=2048
+1609.upload.speed=115200
+1609.bootloader.tool=avrdude
+1609.build.core=coreX-corefiles
+1609.build.board=AVR_ATmega1609
+1609.build.mcu=atmega1609
+1609.build.extra_flags={build.oscillator} {build.compat}
+
+# Fuses we don't need to modify in the tools menu
+1609.bootloader.WDTCFG=0x00
+1609.bootloader.TCD0CFG=0x00
+1609.bootloader.SYSCFG1=0x06
+1609.bootloader.APPEND=0x00
+1609.bootloader.LOCKBIT=0xC5
+
+# Pinouts
+1609.menu.pinout.48pin_standard=48 pin standard
+1609.menu.pinout.48pin_standard.build.variant=48pin-standard
+1609.menu.pinout.48pin_standard.build.compat=
+1609.menu.pinout.uno_wifi=Uno WiFi
+1609.menu.pinout.uno_wifi.build.variant=uno-wifi
+1609.menu.pinout.uno_wifi.build.compat=
+
+# EEPROM
+1609.menu.eeprom.keep=EEPROM retained
+1609.menu.eeprom.keep.bootloader.eesave_bit=1
+1609.menu.eeprom.erase=EEPROM not retained
+1609.menu.eeprom.erase.bootloader.eesave_bit=0
+
+# Reset pin
+1609.menu.resetpin.reset=Reset
+1609.menu.resetpin.reset.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+1609.menu.resetpin.gpio=GPIO
+1609.menu.resetpin.gpio.bootloader.SYSCFG0=0b1100000{bootloader.eesave_bit}
+
+# Brown out detection
+1609.menu.BOD.2v6=BOD 2.6V
+1609.menu.BOD.2v6.bootloader.BODCFG=0x54
+1609.menu.BOD.4v3=BOD 4.3V
+1609.menu.BOD.4v3.bootloader.BODCFG=0xF4
+1609.menu.BOD.4v0=BOD 4.0V
+1609.menu.BOD.4v0.bootloader.BODCFG=0xD4
+1609.menu.BOD.3v7=BOD 3.7V
+1609.menu.BOD.3v7.bootloader.BODCFG=0xB4
+1609.menu.BOD.3v3=BOD 3.3V
+1609.menu.BOD.3v3.bootloader.BODCFG=0x94
+1609.menu.BOD.2v9=BOD 2.9V
+1609.menu.BOD.2v9.bootloader.BODCFG=0x74
+1609.menu.BOD.2v1=BOD 2.1V
+1609.menu.BOD.2v1.bootloader.BODCFG=0x34
+1609.menu.BOD.1v8=BOD 1.8V
+1609.menu.BOD.1v8.bootloader.BODCFG=0x14
+1609.menu.BOD.disabled=BOD disabled
+1609.menu.BOD.disabled.bootloader.BODCFG=0x00
+
+# Clock
+1609.menu.clock.internal_16MHz=Internal 16 MHz
+1609.menu.clock.internal_16MHz.upload.speed=115200
+1609.menu.clock.internal_16MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.internal_16MHz.build.oscillator=
+1609.menu.clock.internal_16MHz.build.f_cpu=16000000L
+
+1609.menu.clock.internal_20MHz=Internal 20 MHz
+1609.menu.clock.internal_20MHz.upload.speed=115200
+1609.menu.clock.internal_20MHz.bootloader.OSCCFG=0x02
+1609.menu.clock.internal_20MHz.build.oscillator=
+1609.menu.clock.internal_20MHz.build.f_cpu=20000000L
+
+1609.menu.clock.internal_10MHz=Internal 10 MHz
+1609.menu.clock.internal_10MHz.upload.speed=115200
+1609.menu.clock.internal_10MHz.bootloader.OSCCFG=0x02
+1609.menu.clock.internal_10MHz.build.oscillator=
+1609.menu.clock.internal_10MHz.build.f_cpu=10000000L
+
+1609.menu.clock.internal_8MHz=Internal 8 MHz
+1609.menu.clock.internal_8MHz.upload.speed=115200
+1609.menu.clock.internal_8MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.internal_8MHz.build.oscillator=
+1609.menu.clock.internal_8MHz.build.f_cpu=8000000L
+
+1609.menu.clock.internal_5MHz=Internal 5 MHz
+1609.menu.clock.internal_5MHz.upload.speed=115200
+1609.menu.clock.internal_5MHz.bootloader.OSCCFG=0x02
+1609.menu.clock.internal_5MHz.build.oscillator=
+1609.menu.clock.internal_5MHz.build.f_cpu=5000000L
+
+1609.menu.clock.internal_4MHz=Internal 4 MHz
+1609.menu.clock.internal_4MHz.upload.speed=115200
+1609.menu.clock.internal_4MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.internal_4MHz.build.oscillator=
+1609.menu.clock.internal_4MHz.build.f_cpu=4000000L
+
+1609.menu.clock.internal_2MHz=Internal 2 MHz
+1609.menu.clock.internal_2MHz.upload.speed=115200
+1609.menu.clock.internal_2MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.internal_2MHz.build.oscillator=
+1609.menu.clock.internal_2MHz.build.f_cpu=2000000L
+
+1609.menu.clock.internal_1MHz=Internal 1 MHz
+1609.menu.clock.internal_1MHz.upload.speed=115200
+1609.menu.clock.internal_1MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.internal_1MHz.build.oscillator=
+1609.menu.clock.internal_1MHz.build.f_cpu=1000000L
+
+1609.menu.clock.external_16MHz=External 16 MHz
+1609.menu.clock.external_16MHz.upload.speed=115200
+1609.menu.clock.external_16MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.external_16MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1609.menu.clock.external_16MHz.build.f_cpu=16000000L
+
+1609.menu.clock.external_12MHz=External 12 MHz
+1609.menu.clock.external_12MHz.upload.speed=115200
+1609.menu.clock.external_12MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.external_12MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1609.menu.clock.external_12MHz.build.f_cpu=12000000L
+
+1609.menu.clock.external_8MHz=External 8 MHz
+1609.menu.clock.external_8MHz.upload.speed=115200
+1609.menu.clock.external_8MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.external_8MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1609.menu.clock.external_8MHz.build.f_cpu=8000000L
+
+1609.menu.clock.external_4MHz=External 4 MHz
+1609.menu.clock.external_4MHz.upload.speed=115200
+1609.menu.clock.external_4MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.external_4MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1609.menu.clock.external_4MHz.build.f_cpu=4000000L
+
+1609.menu.clock.external_1MHz=External 1 MHz
+1609.menu.clock.external_1MHz.upload.speed=115200
+1609.menu.clock.external_1MHz.bootloader.OSCCFG=0x01
+1609.menu.clock.external_1MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1609.menu.clock.external_1MHz.build.f_cpu=1000000L
+
+# Bootloader
+1609.menu.bootloader.no_bootloader=No bootloader
+1609.menu.bootloader.no_bootloader.upload.maximum_size=16384
+1609.menu.bootloader.no_bootloader.upload.extra_params=
+1609.menu.bootloader.no_bootloader.build.text_section_start=.text=0x0
+1609.menu.bootloader.no_bootloader.build.export_merged_output=false
+1609.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex
+1609.menu.bootloader.no_bootloader.bootloader.BOOTEND=0x00
+
+1609.menu.bootloader.uart0_default=Optiboot (UART0 default pins)
+1609.menu.bootloader.uart0_default.upload.maximum_size=15872
+1609.menu.bootloader.uart0_default.upload.protocol=arduino
+1609.menu.bootloader.uart0_default.upload.port=UART0_DEF
+1609.menu.bootloader.uart0_default.upload.extra_params=
+1609.menu.bootloader.uart0_default.build.text_section_start=.text=0x200
+1609.menu.bootloader.uart0_default.build.export_merged_output=true
+1609.menu.bootloader.uart0_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1609.menu.bootloader.uart0_default.bootloader.BOOTEND=0x02
+1609.menu.bootloader.uart0_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1609.menu.bootloader.uart0_alternative=Optiboot (UART0 alternative pins)
+1609.menu.bootloader.uart0_alternative.upload.maximum_size=15872
+1609.menu.bootloader.uart0_alternative.upload.protocol=arduino
+1609.menu.bootloader.uart0_alternative.upload.port=UART0_ALT
+1609.menu.bootloader.uart0_alternative.upload.extra_params=
+1609.menu.bootloader.uart0_alternative.build.text_section_start=.text=0x200
+1609.menu.bootloader.uart0_alternative.build.export_merged_output=true
+1609.menu.bootloader.uart0_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1609.menu.bootloader.uart0_alternative.bootloader.BOOTEND=0x02
+1609.menu.bootloader.uart0_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1609.menu.bootloader.uart1_default=Optiboot (UART1 default pins)
+1609.menu.bootloader.uart1_default.upload.maximum_size=15872
+1609.menu.bootloader.uart1_default.upload.protocol=arduino
+1609.menu.bootloader.uart1_default.upload.port=UART1_DEF
+1609.menu.bootloader.uart1_default.upload.extra_params=
+1609.menu.bootloader.uart1_default.build.text_section_start=.text=0x200
+1609.menu.bootloader.uart1_default.build.export_merged_output=true
+1609.menu.bootloader.uart1_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1609.menu.bootloader.uart1_default.bootloader.BOOTEND=0x02
+1609.menu.bootloader.uart1_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1609.menu.bootloader.uart1_alternative=Optiboot (UART1 alternative pins)
+1609.menu.bootloader.uart1_alternative.upload.maximum_size=15872
+1609.menu.bootloader.uart1_alternative.upload.protocol=arduino
+1609.menu.bootloader.uart1_alternative.upload.port=UART1_ALT
+1609.menu.bootloader.uart1_alternative.upload.extra_params=
+1609.menu.bootloader.uart1_alternative.build.text_section_start=.text=0x200
+1609.menu.bootloader.uart1_alternative.build.export_merged_output=true
+1609.menu.bootloader.uart1_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1609.menu.bootloader.uart1_alternative.bootloader.BOOTEND=0x02
+1609.menu.bootloader.uart1_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1609.menu.bootloader.uart2_default=Optiboot (UART2 default pins)
+1609.menu.bootloader.uart2_default.upload.maximum_size=15872
+1609.menu.bootloader.uart2_default.upload.protocol=arduino
+1609.menu.bootloader.uart2_default.upload.port=UART2_DEF
+1609.menu.bootloader.uart2_default.upload.extra_params=
+1609.menu.bootloader.uart2_default.build.text_section_start=.text=0x200
+1609.menu.bootloader.uart2_default.build.export_merged_output=true
+1609.menu.bootloader.uart2_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1609.menu.bootloader.uart2_default.bootloader.BOOTEND=0x02
+1609.menu.bootloader.uart2_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1609.menu.bootloader.uart2_alternative=Optiboot (UART2 alternative pins)
+1609.menu.bootloader.uart2_alternative.upload.maximum_size=15872
+1609.menu.bootloader.uart2_alternative.upload.protocol=arduino
+1609.menu.bootloader.uart2_alternative.upload.port=UART2_ALT
+1609.menu.bootloader.uart2_alternative.upload.extra_params=
+1609.menu.bootloader.uart2_alternative.build.text_section_start=.text=0x200
+1609.menu.bootloader.uart2_alternative.build.export_merged_output=true
+1609.menu.bootloader.uart2_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1609.menu.bootloader.uart2_alternative.bootloader.BOOTEND=0x02
+1609.menu.bootloader.uart2_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1609.menu.bootloader.uart3_default=Optiboot (UART3 default pins)
+1609.menu.bootloader.uart3_default.upload.maximum_size=15872
+1609.menu.bootloader.uart3_default.upload.protocol=arduino
+1609.menu.bootloader.uart3_default.upload.port=UART3_DEF
+1609.menu.bootloader.uart3_default.upload.extra_params=
+1609.menu.bootloader.uart3_default.build.text_section_start=.text=0x200
+1609.menu.bootloader.uart3_default.build.export_merged_output=true
+1609.menu.bootloader.uart3_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1609.menu.bootloader.uart3_default.bootloader.BOOTEND=0x02
+1609.menu.bootloader.uart3_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1609.menu.bootloader.uart3_alternative=Optiboot (UART3 alternative pins)
+1609.menu.bootloader.uart3_alternative.upload.maximum_size=15872
+1609.menu.bootloader.uart3_alternative.upload.protocol=arduino
+1609.menu.bootloader.uart3_alternative.upload.port=UART3_ALT
+1609.menu.bootloader.uart3_alternative.upload.extra_params=
+1609.menu.bootloader.uart3_alternative.build.text_section_start=.text=0x200
+1609.menu.bootloader.uart3_alternative.build.export_merged_output=true
+1609.menu.bootloader.uart3_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1609.menu.bootloader.uart3_alternative.bootloader.BOOTEND=0x02
+1609.menu.bootloader.uart3_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+
+####################
+#### ATmega1608 ####
+####################
+
+# General
+1608.name=ATmega1608
+1608.upload.tool=avrdude
+1608.upload.maximum_data_size=2048
+1608.upload.speed=115200
+1608.bootloader.tool=avrdude
+1608.build.core=coreX-corefiles
+1608.build.board=AVR_ATmega1608
+1608.build.mcu=atmega1608
+1608.build.extra_flags={build.oscillator}
+
+# Fuses we don't need to modify in the tools menu
+1608.bootloader.WDTCFG=0x00
+1608.bootloader.TCD0CFG=0x00
+1608.bootloader.SYSCFG1=0x06
+1608.bootloader.APPEND=0x00
+1608.bootloader.LOCKBIT=0xC5
+
+# Pinouts
+1608.menu.pinout.32pin_standard=32 pin standard
+1608.menu.pinout.32pin_standard.build.variant=32pin-standard
+1608.menu.pinout.28pin_standard=28 pin standard
+1608.menu.pinout.28pin_standard.build.variant=28pin-standard
+
+# EEPROM
+1608.menu.eeprom.keep=EEPROM retained
+1608.menu.eeprom.keep.bootloader.eesave_bit=1
+1608.menu.eeprom.erase=EEPROM not retained
+1608.menu.eeprom.erase.bootloader.eesave_bit=0
+
+# Reset pin
+1608.menu.resetpin.reset=Reset
+1608.menu.resetpin.reset.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+1608.menu.resetpin.gpio=GPIO
+1608.menu.resetpin.gpio.bootloader.SYSCFG0=0b1100000{bootloader.eesave_bit}
+
+# Brown out detection
+1608.menu.BOD.2v6=BOD 2.6V
+1608.menu.BOD.2v6.bootloader.BODCFG=0x54
+1608.menu.BOD.4v3=BOD 4.3V
+1608.menu.BOD.4v3.bootloader.BODCFG=0xF4
+1608.menu.BOD.4v0=BOD 4.0V
+1608.menu.BOD.4v0.bootloader.BODCFG=0xD4
+1608.menu.BOD.3v7=BOD 3.7V
+1608.menu.BOD.3v7.bootloader.BODCFG=0xB4
+1608.menu.BOD.3v3=BOD 3.3V
+1608.menu.BOD.3v3.bootloader.BODCFG=0x94
+1608.menu.BOD.2v9=BOD 2.9V
+1608.menu.BOD.2v9.bootloader.BODCFG=0x74
+1608.menu.BOD.2v1=BOD 2.1V
+1608.menu.BOD.2v1.bootloader.BODCFG=0x34
+1608.menu.BOD.1v8=BOD 1.8V
+1608.menu.BOD.1v8.bootloader.BODCFG=0x14
+1608.menu.BOD.disabled=BOD disabled
+1608.menu.BOD.disabled.bootloader.BODCFG=0x00
+
+# Clock
+1608.menu.clock.internal_16MHz=Internal 16 MHz
+1608.menu.clock.internal_16MHz.upload.speed=115200
+1608.menu.clock.internal_16MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.internal_16MHz.build.oscillator=
+1608.menu.clock.internal_16MHz.build.f_cpu=16000000L
+
+1608.menu.clock.internal_20MHz=Internal 20 MHz
+1608.menu.clock.internal_20MHz.upload.speed=115200
+1608.menu.clock.internal_20MHz.bootloader.OSCCFG=0x02
+1608.menu.clock.internal_20MHz.build.oscillator=
+1608.menu.clock.internal_20MHz.build.f_cpu=20000000L
+
+1608.menu.clock.internal_10MHz=Internal 10 MHz
+1608.menu.clock.internal_10MHz.upload.speed=115200
+1608.menu.clock.internal_10MHz.bootloader.OSCCFG=0x02
+1608.menu.clock.internal_10MHz.build.oscillator=
+1608.menu.clock.internal_10MHz.build.f_cpu=10000000L
+
+1608.menu.clock.internal_8MHz=Internal 8 MHz
+1608.menu.clock.internal_8MHz.upload.speed=115200
+1608.menu.clock.internal_8MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.internal_8MHz.build.oscillator=
+1608.menu.clock.internal_8MHz.build.f_cpu=8000000L
+
+1608.menu.clock.internal_5MHz=Internal 5 MHz
+1608.menu.clock.internal_5MHz.upload.speed=115200
+1608.menu.clock.internal_5MHz.bootloader.OSCCFG=0x02
+1608.menu.clock.internal_5MHz.build.oscillator=
+1608.menu.clock.internal_5MHz.build.f_cpu=5000000L
+
+1608.menu.clock.internal_4MHz=Internal 4 MHz
+1608.menu.clock.internal_4MHz.upload.speed=115200
+1608.menu.clock.internal_4MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.internal_4MHz.build.oscillator=
+1608.menu.clock.internal_4MHz.build.f_cpu=4000000L
+
+1608.menu.clock.internal_2MHz=Internal 2 MHz
+1608.menu.clock.internal_2MHz.upload.speed=115200
+1608.menu.clock.internal_2MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.internal_2MHz.build.oscillator=
+1608.menu.clock.internal_2MHz.build.f_cpu=2000000L
+
+1608.menu.clock.internal_1MHz=Internal 1 MHz
+1608.menu.clock.internal_1MHz.upload.speed=115200
+1608.menu.clock.internal_1MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.internal_1MHz.build.oscillator=
+1608.menu.clock.internal_1MHz.build.f_cpu=1000000L
+
+1608.menu.clock.external_16MHz=External 16 MHz
+1608.menu.clock.external_16MHz.upload.speed=115200
+1608.menu.clock.external_16MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.external_16MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1608.menu.clock.external_16MHz.build.f_cpu=16000000L
+
+1608.menu.clock.external_12MHz=External 12 MHz
+1608.menu.clock.external_12MHz.upload.speed=115200
+1608.menu.clock.external_12MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.external_12MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1608.menu.clock.external_12MHz.build.f_cpu=12000000L
+
+1608.menu.clock.external_8MHz=External 8 MHz
+1608.menu.clock.external_8MHz.upload.speed=115200
+1608.menu.clock.external_8MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.external_8MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1608.menu.clock.external_8MHz.build.f_cpu=8000000L
+
+1608.menu.clock.external_4MHz=External 4 MHz
+1608.menu.clock.external_4MHz.upload.speed=115200
+1608.menu.clock.external_4MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.external_4MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1608.menu.clock.external_4MHz.build.f_cpu=4000000L
+
+1608.menu.clock.external_1MHz=External 1 MHz
+1608.menu.clock.external_1MHz.upload.speed=115200
+1608.menu.clock.external_1MHz.bootloader.OSCCFG=0x01
+1608.menu.clock.external_1MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+1608.menu.clock.external_1MHz.build.f_cpu=1000000L
+
+# Bootloader
+1608.menu.bootloader.no_bootloader=No bootloader
+1608.menu.bootloader.no_bootloader.upload.maximum_size=16384
+1608.menu.bootloader.no_bootloader.upload.extra_params=
+1608.menu.bootloader.no_bootloader.build.text_section_start=.text=0x0
+1608.menu.bootloader.no_bootloader.build.export_merged_output=false
+1608.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex
+1608.menu.bootloader.no_bootloader.bootloader.BOOTEND=0x00
+
+1608.menu.bootloader.uart0_default=Optiboot (UART0 default pins)
+1608.menu.bootloader.uart0_default.upload.maximum_size=15872
+1608.menu.bootloader.uart0_default.upload.protocol=arduino
+1608.menu.bootloader.uart0_default.upload.port=UART0_DEF
+1608.menu.bootloader.uart0_default.upload.extra_params=
+1608.menu.bootloader.uart0_default.build.text_section_start=.text=0x200
+1608.menu.bootloader.uart0_default.build.export_merged_output=true
+1608.menu.bootloader.uart0_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1608.menu.bootloader.uart0_default.bootloader.BOOTEND=0x02
+1608.menu.bootloader.uart0_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1608.menu.bootloader.uart0_alternative=Optiboot (UART0 alternative pins)
+1608.menu.bootloader.uart0_alternative.upload.maximum_size=15872
+1608.menu.bootloader.uart0_alternative.upload.protocol=arduino
+1608.menu.bootloader.uart0_alternative.upload.port=UART0_ALT
+1608.menu.bootloader.uart0_alternative.upload.extra_params=
+1608.menu.bootloader.uart0_alternative.build.text_section_start=.text=0x200
+1608.menu.bootloader.uart0_alternative.build.export_merged_output=true
+1608.menu.bootloader.uart0_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1608.menu.bootloader.uart0_alternative.bootloader.BOOTEND=0x02
+1608.menu.bootloader.uart0_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1608.menu.bootloader.uart1_default=Optiboot (UART1 default pins)
+1608.menu.bootloader.uart1_default.upload.maximum_size=15872
+1608.menu.bootloader.uart1_default.upload.protocol=arduino
+1608.menu.bootloader.uart1_default.upload.port=UART1_DEF
+1608.menu.bootloader.uart1_default.upload.extra_params=
+1608.menu.bootloader.uart1_default.build.text_section_start=.text=0x200
+1608.menu.bootloader.uart1_default.build.export_merged_output=true
+1608.menu.bootloader.uart1_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1608.menu.bootloader.uart1_default.bootloader.BOOTEND=0x02
+1608.menu.bootloader.uart1_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1608.menu.bootloader.uart1_alternative=Optiboot (UART1 alternative pins)
+1608.menu.bootloader.uart1_alternative.upload.maximum_size=15872
+1608.menu.bootloader.uart1_alternative.upload.protocol=arduino
+1608.menu.bootloader.uart1_alternative.upload.port=UART1_ALT
+1608.menu.bootloader.uart1_alternative.upload.extra_params=
+1608.menu.bootloader.uart1_alternative.build.text_section_start=.text=0x200
+1608.menu.bootloader.uart1_alternative.build.export_merged_output=true
+1608.menu.bootloader.uart1_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1608.menu.bootloader.uart1_alternative.bootloader.BOOTEND=0x02
+1608.menu.bootloader.uart1_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1608.menu.bootloader.uart2_default=Optiboot (UART2 default pins)
+1608.menu.bootloader.uart2_default.upload.maximum_size=15872
+1608.menu.bootloader.uart2_default.upload.protocol=arduino
+1608.menu.bootloader.uart2_default.upload.port=UART2_DEF
+1608.menu.bootloader.uart2_default.upload.extra_params=
+1608.menu.bootloader.uart2_default.build.text_section_start=.text=0x200
+1608.menu.bootloader.uart2_default.build.export_merged_output=true
+1608.menu.bootloader.uart2_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1608.menu.bootloader.uart2_default.bootloader.BOOTEND=0x02
+1608.menu.bootloader.uart2_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+1608.menu.bootloader.uart2_alternative=Optiboot (UART2 alternative pins)
+1608.menu.bootloader.uart2_alternative.upload.maximum_size=15872
+1608.menu.bootloader.uart2_alternative.upload.protocol=arduino
+1608.menu.bootloader.uart2_alternative.upload.port=UART2_ALT
+1608.menu.bootloader.uart2_alternative.upload.extra_params=
+1608.menu.bootloader.uart2_alternative.build.text_section_start=.text=0x200
+1608.menu.bootloader.uart2_alternative.build.export_merged_output=true
+1608.menu.bootloader.uart2_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+1608.menu.bootloader.uart2_alternative.bootloader.BOOTEND=0x02
+1608.menu.bootloader.uart2_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+
+###################
+#### ATmega809 ####
+###################
+
+# General
+809.name=ATmega809
+809.upload.tool=avrdude
+809.upload.maximum_data_size=1024
+809.upload.speed=115200
+809.bootloader.tool=avrdude
+809.build.core=coreX-corefiles
+809.build.board=AVR_ATmega809
+809.build.mcu=atmega809
+809.build.extra_flags={build.oscillator} {build.compat}
+
+# Fuses we don't need to modify in the tools menu
+809.bootloader.WDTCFG=0x00
+809.bootloader.TCD0CFG=0x00
+809.bootloader.SYSCFG1=0x06
+809.bootloader.APPEND=0x00
+809.bootloader.LOCKBIT=0xC5
+
+# Pinouts
+809.menu.pinout.48pin_standard=48 pin standard
+809.menu.pinout.48pin_standard.build.variant=48pin-standard
+809.menu.pinout.48pin_standard.build.compat=
+809.menu.pinout.uno_wifi=Uno WiFi
+809.menu.pinout.uno_wifi.build.variant=uno-wifi
+809.menu.pinout.uno_wifi.build.compat=
+
+# EEPROM
+809.menu.eeprom.keep=EEPROM retained
+809.menu.eeprom.keep.bootloader.eesave_bit=1
+809.menu.eeprom.erase=EEPROM not retained
+809.menu.eeprom.erase.bootloader.eesave_bit=0
+
+# Reset pin
+809.menu.resetpin.reset=Reset
+809.menu.resetpin.reset.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+809.menu.resetpin.gpio=GPIO
+809.menu.resetpin.gpio.bootloader.SYSCFG0=0b1100000{bootloader.eesave_bit}
+
+# Brown out detection
+809.menu.BOD.2v6=BOD 2.6V
+809.menu.BOD.2v6.bootloader.BODCFG=0x54
+809.menu.BOD.4v3=BOD 4.3V
+809.menu.BOD.4v3.bootloader.BODCFG=0xF4
+809.menu.BOD.4v0=BOD 4.0V
+809.menu.BOD.4v0.bootloader.BODCFG=0xD4
+809.menu.BOD.3v7=BOD 3.7V
+809.menu.BOD.3v7.bootloader.BODCFG=0xB4
+809.menu.BOD.3v3=BOD 3.3V
+809.menu.BOD.3v3.bootloader.BODCFG=0x94
+809.menu.BOD.2v9=BOD 2.9V
+809.menu.BOD.2v9.bootloader.BODCFG=0x74
+809.menu.BOD.2v1=BOD 2.1V
+809.menu.BOD.2v1.bootloader.BODCFG=0x34
+809.menu.BOD.1v8=BOD 1.8V
+809.menu.BOD.1v8.bootloader.BODCFG=0x14
+809.menu.BOD.disabled=BOD disabled
+809.menu.BOD.disabled.bootloader.BODCFG=0x00
+
+# Clock
+809.menu.clock.internal_16MHz=Internal 16 MHz
+809.menu.clock.internal_16MHz.upload.speed=115200
+809.menu.clock.internal_16MHz.bootloader.OSCCFG=0x01
+809.menu.clock.internal_16MHz.build.oscillator=
+809.menu.clock.internal_16MHz.build.f_cpu=16000000L
+
+809.menu.clock.internal_20MHz=Internal 20 MHz
+809.menu.clock.internal_20MHz.upload.speed=115200
+809.menu.clock.internal_20MHz.bootloader.OSCCFG=0x02
+809.menu.clock.internal_20MHz.build.oscillator=
+809.menu.clock.internal_20MHz.build.f_cpu=20000000L
+
+809.menu.clock.internal_10MHz=Internal 10 MHz
+809.menu.clock.internal_10MHz.upload.speed=115200
+809.menu.clock.internal_10MHz.bootloader.OSCCFG=0x02
+809.menu.clock.internal_10MHz.build.oscillator=
+809.menu.clock.internal_10MHz.build.f_cpu=10000000L
+
+809.menu.clock.internal_8MHz=Internal 8 MHz
+809.menu.clock.internal_8MHz.upload.speed=115200
+809.menu.clock.internal_8MHz.bootloader.OSCCFG=0x01
+809.menu.clock.internal_8MHz.build.oscillator=
+809.menu.clock.internal_8MHz.build.f_cpu=8000000L
+
+809.menu.clock.internal_5MHz=Internal 5 MHz
+809.menu.clock.internal_5MHz.upload.speed=115200
+809.menu.clock.internal_5MHz.bootloader.OSCCFG=0x02
+809.menu.clock.internal_5MHz.build.oscillator=
+809.menu.clock.internal_5MHz.build.f_cpu=5000000L
+
+809.menu.clock.internal_4MHz=Internal 4 MHz
+809.menu.clock.internal_4MHz.upload.speed=115200
+809.menu.clock.internal_4MHz.bootloader.OSCCFG=0x01
+809.menu.clock.internal_4MHz.build.oscillator=
+809.menu.clock.internal_4MHz.build.f_cpu=4000000L
+
+809.menu.clock.internal_2MHz=Internal 2 MHz
+809.menu.clock.internal_2MHz.upload.speed=115200
+809.menu.clock.internal_2MHz.bootloader.OSCCFG=0x01
+809.menu.clock.internal_2MHz.build.oscillator=
+809.menu.clock.internal_2MHz.build.f_cpu=2000000L
+
+809.menu.clock.internal_1MHz=Internal 1 MHz
+809.menu.clock.internal_1MHz.upload.speed=115200
+809.menu.clock.internal_1MHz.bootloader.OSCCFG=0x01
+809.menu.clock.internal_1MHz.build.oscillator=
+809.menu.clock.internal_1MHz.build.f_cpu=1000000L
+
+809.menu.clock.external_16MHz=External 16 MHz
+809.menu.clock.external_16MHz.upload.speed=115200
+809.menu.clock.external_16MHz.bootloader.OSCCFG=0x01
+809.menu.clock.external_16MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+809.menu.clock.external_16MHz.build.f_cpu=16000000L
+
+809.menu.clock.external_12MHz=External 12 MHz
+809.menu.clock.external_12MHz.upload.speed=115200
+809.menu.clock.external_12MHz.bootloader.OSCCFG=0x01
+809.menu.clock.external_12MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+809.menu.clock.external_12MHz.build.f_cpu=12000000L
+
+809.menu.clock.external_8MHz=External 8 MHz
+809.menu.clock.external_8MHz.upload.speed=115200
+809.menu.clock.external_8MHz.bootloader.OSCCFG=0x01
+809.menu.clock.external_8MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+809.menu.clock.external_8MHz.build.f_cpu=8000000L
+
+809.menu.clock.external_4MHz=External 4 MHz
+809.menu.clock.external_4MHz.upload.speed=115200
+809.menu.clock.external_4MHz.bootloader.OSCCFG=0x01
+809.menu.clock.external_4MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+809.menu.clock.external_4MHz.build.f_cpu=4000000L
+
+809.menu.clock.external_1MHz=External 1 MHz
+809.menu.clock.external_1MHz.upload.speed=115200
+809.menu.clock.external_1MHz.bootloader.OSCCFG=0x01
+809.menu.clock.external_1MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+809.menu.clock.external_1MHz.build.f_cpu=1000000L
+
+# Bootloader
+809.menu.bootloader.no_bootloader=No bootloader
+809.menu.bootloader.no_bootloader.upload.maximum_size=8192
+809.menu.bootloader.no_bootloader.upload.extra_params=
+809.menu.bootloader.no_bootloader.build.text_section_start=.text=0x0
+809.menu.bootloader.no_bootloader.build.export_merged_output=false
+809.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex
+809.menu.bootloader.no_bootloader.bootloader.BOOTEND=0x00
+
+809.menu.bootloader.uart0_default=Optiboot (UART0 default pins)
+809.menu.bootloader.uart0_default.upload.maximum_size=7680
+809.menu.bootloader.uart0_default.upload.protocol=arduino
+809.menu.bootloader.uart0_default.upload.port=UART0_DEF
+809.menu.bootloader.uart0_default.upload.extra_params=
+809.menu.bootloader.uart0_default.build.text_section_start=.text=0x200
+809.menu.bootloader.uart0_default.build.export_merged_output=true
+809.menu.bootloader.uart0_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+809.menu.bootloader.uart0_default.bootloader.BOOTEND=0x02
+809.menu.bootloader.uart0_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+809.menu.bootloader.uart0_alternative=Optiboot (UART0 alternative pins)
+809.menu.bootloader.uart0_alternative.upload.maximum_size=7680
+809.menu.bootloader.uart0_alternative.upload.protocol=arduino
+809.menu.bootloader.uart0_alternative.upload.port=UART0_ALT
+809.menu.bootloader.uart0_alternative.upload.extra_params=
+809.menu.bootloader.uart0_alternative.build.text_section_start=.text=0x200
+809.menu.bootloader.uart0_alternative.build.export_merged_output=true
+809.menu.bootloader.uart0_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+809.menu.bootloader.uart0_alternative.bootloader.BOOTEND=0x02
+809.menu.bootloader.uart0_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+809.menu.bootloader.uart1_default=Optiboot (UART1 default pins)
+809.menu.bootloader.uart1_default.upload.maximum_size=7680
+809.menu.bootloader.uart1_default.upload.protocol=arduino
+809.menu.bootloader.uart1_default.upload.port=UART1_DEF
+809.menu.bootloader.uart1_default.upload.extra_params=
+809.menu.bootloader.uart1_default.build.text_section_start=.text=0x200
+809.menu.bootloader.uart1_default.build.export_merged_output=true
+809.menu.bootloader.uart1_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+809.menu.bootloader.uart1_default.bootloader.BOOTEND=0x02
+809.menu.bootloader.uart1_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+809.menu.bootloader.uart1_alternative=Optiboot (UART1 alternative pins)
+809.menu.bootloader.uart1_alternative.upload.maximum_size=7680
+809.menu.bootloader.uart1_alternative.upload.protocol=arduino
+809.menu.bootloader.uart1_alternative.upload.port=UART1_ALT
+809.menu.bootloader.uart1_alternative.upload.extra_params=
+809.menu.bootloader.uart1_alternative.build.text_section_start=.text=0x200
+809.menu.bootloader.uart1_alternative.build.export_merged_output=true
+809.menu.bootloader.uart1_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+809.menu.bootloader.uart1_alternative.bootloader.BOOTEND=0x02
+809.menu.bootloader.uart1_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+809.menu.bootloader.uart2_default=Optiboot (UART2 default pins)
+809.menu.bootloader.uart2_default.upload.maximum_size=7680
+809.menu.bootloader.uart2_default.upload.protocol=arduino
+809.menu.bootloader.uart2_default.upload.port=UART2_DEF
+809.menu.bootloader.uart2_default.upload.extra_params=
+809.menu.bootloader.uart2_default.build.text_section_start=.text=0x200
+809.menu.bootloader.uart2_default.build.export_merged_output=true
+809.menu.bootloader.uart2_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+809.menu.bootloader.uart2_default.bootloader.BOOTEND=0x02
+809.menu.bootloader.uart2_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+809.menu.bootloader.uart2_alternative=Optiboot (UART2 alternative pins)
+809.menu.bootloader.uart2_alternative.upload.maximum_size=7680
+809.menu.bootloader.uart2_alternative.upload.protocol=arduino
+809.menu.bootloader.uart2_alternative.upload.port=UART2_ALT
+809.menu.bootloader.uart2_alternative.upload.extra_params=
+809.menu.bootloader.uart2_alternative.build.text_section_start=.text=0x200
+809.menu.bootloader.uart2_alternative.build.export_merged_output=true
+809.menu.bootloader.uart2_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+809.menu.bootloader.uart2_alternative.bootloader.BOOTEND=0x02
+809.menu.bootloader.uart2_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+809.menu.bootloader.uart3_default=Optiboot (UART3 default pins)
+809.menu.bootloader.uart3_default.upload.maximum_size=7680
+809.menu.bootloader.uart3_default.upload.protocol=arduino
+809.menu.bootloader.uart3_default.upload.port=UART3_DEF
+809.menu.bootloader.uart3_default.upload.extra_params=
+809.menu.bootloader.uart3_default.build.text_section_start=.text=0x200
+809.menu.bootloader.uart3_default.build.export_merged_output=true
+809.menu.bootloader.uart3_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+809.menu.bootloader.uart3_default.bootloader.BOOTEND=0x02
+809.menu.bootloader.uart3_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+809.menu.bootloader.uart3_alternative=Optiboot (UART3 alternative pins)
+809.menu.bootloader.uart3_alternative.upload.maximum_size=7680
+809.menu.bootloader.uart3_alternative.upload.protocol=arduino
+809.menu.bootloader.uart3_alternative.upload.port=UART3_ALT
+809.menu.bootloader.uart3_alternative.upload.extra_params=
+809.menu.bootloader.uart3_alternative.build.text_section_start=.text=0x200
+809.menu.bootloader.uart3_alternative.build.export_merged_output=true
+809.menu.bootloader.uart3_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+809.menu.bootloader.uart3_alternative.bootloader.BOOTEND=0x02
+809.menu.bootloader.uart3_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+
+###################
+#### ATmega808 ####
+###################
+
+# General
+808.name=ATmega808
+808.upload.tool=avrdude
+808.upload.maximum_data_size=1024
+808.upload.speed=115200
+808.bootloader.tool=avrdude
+808.build.core=coreX-corefiles
+808.build.board=AVR_ATmega808
+808.build.mcu=atmega808
+808.build.extra_flags={build.oscillator}
+
+# Fuses we don't need to modify in the tools menu
+808.bootloader.WDTCFG=0x00
+808.bootloader.TCD0CFG=0x00
+808.bootloader.SYSCFG1=0x06
+808.bootloader.APPEND=0x00
+808.bootloader.LOCKBIT=0xC5
+
+# Pinouts
+808.menu.pinout.32pin_standard=32 pin standard
+808.menu.pinout.32pin_standard.build.variant=32pin-standard
+808.menu.pinout.28pin_standard=28 pin standard
+808.menu.pinout.28pin_standard.build.variant=28pin-standard
+
+# EEPROM
+808.menu.eeprom.keep=EEPROM retained
+808.menu.eeprom.keep.bootloader.eesave_bit=1
+808.menu.eeprom.erase=EEPROM not retained
+808.menu.eeprom.erase.bootloader.eesave_bit=0
+
+# Reset pin
+808.menu.resetpin.reset=Reset
+808.menu.resetpin.reset.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+808.menu.resetpin.gpio=GPIO
+808.menu.resetpin.gpio.bootloader.SYSCFG0=0b1100000{bootloader.eesave_bit}
+
+# Brown out detection
+808.menu.BOD.2v6=BOD 2.6V
+808.menu.BOD.2v6.bootloader.BODCFG=0x54
+808.menu.BOD.4v3=BOD 4.3V
+808.menu.BOD.4v3.bootloader.BODCFG=0xF4
+808.menu.BOD.4v0=BOD 4.0V
+808.menu.BOD.4v0.bootloader.BODCFG=0xD4
+808.menu.BOD.3v7=BOD 3.7V
+808.menu.BOD.3v7.bootloader.BODCFG=0xB4
+808.menu.BOD.3v3=BOD 3.3V
+808.menu.BOD.3v3.bootloader.BODCFG=0x94
+808.menu.BOD.2v9=BOD 2.9V
+808.menu.BOD.2v9.bootloader.BODCFG=0x74
+808.menu.BOD.2v1=BOD 2.1V
+808.menu.BOD.2v1.bootloader.BODCFG=0x34
+808.menu.BOD.1v8=BOD 1.8V
+808.menu.BOD.1v8.bootloader.BODCFG=0x14
+808.menu.BOD.disabled=BOD disabled
+808.menu.BOD.disabled.bootloader.BODCFG=0x00
+
+# Clock
+808.menu.clock.internal_16MHz=Internal 16 MHz
+808.menu.clock.internal_16MHz.upload.speed=115200
+808.menu.clock.internal_16MHz.bootloader.OSCCFG=0x01
+808.menu.clock.internal_16MHz.build.oscillator=
+808.menu.clock.internal_16MHz.build.f_cpu=16000000L
+
+808.menu.clock.internal_20MHz=Internal 20 MHz
+808.menu.clock.internal_20MHz.upload.speed=115200
+808.menu.clock.internal_20MHz.bootloader.OSCCFG=0x02
+808.menu.clock.internal_20MHz.build.oscillator=
+808.menu.clock.internal_20MHz.build.f_cpu=20000000L
+
+808.menu.clock.internal_10MHz=Internal 10 MHz
+808.menu.clock.internal_10MHz.upload.speed=115200
+808.menu.clock.internal_10MHz.bootloader.OSCCFG=0x02
+808.menu.clock.internal_10MHz.build.oscillator=
+808.menu.clock.internal_10MHz.build.f_cpu=10000000L
+
+808.menu.clock.internal_8MHz=Internal 8 MHz
+808.menu.clock.internal_8MHz.upload.speed=115200
+808.menu.clock.internal_8MHz.bootloader.OSCCFG=0x01
+808.menu.clock.internal_8MHz.build.oscillator=
+808.menu.clock.internal_8MHz.build.f_cpu=8000000L
+
+808.menu.clock.internal_5MHz=Internal 5 MHz
+808.menu.clock.internal_5MHz.upload.speed=115200
+808.menu.clock.internal_5MHz.bootloader.OSCCFG=0x02
+808.menu.clock.internal_5MHz.build.oscillator=
+808.menu.clock.internal_5MHz.build.f_cpu=5000000L
+
+808.menu.clock.internal_4MHz=Internal 4 MHz
+808.menu.clock.internal_4MHz.upload.speed=115200
+808.menu.clock.internal_4MHz.bootloader.OSCCFG=0x01
+808.menu.clock.internal_4MHz.build.oscillator=
+808.menu.clock.internal_4MHz.build.f_cpu=4000000L
+
+808.menu.clock.internal_2MHz=Internal 2 MHz
+808.menu.clock.internal_2MHz.upload.speed=115200
+808.menu.clock.internal_2MHz.bootloader.OSCCFG=0x01
+808.menu.clock.internal_2MHz.build.oscillator=
+808.menu.clock.internal_2MHz.build.f_cpu=2000000L
+
+808.menu.clock.internal_1MHz=Internal 1 MHz
+808.menu.clock.internal_1MHz.upload.speed=115200
+808.menu.clock.internal_1MHz.bootloader.OSCCFG=0x01
+808.menu.clock.internal_1MHz.build.oscillator=
+808.menu.clock.internal_1MHz.build.f_cpu=1000000L
+
+808.menu.clock.external_16MHz=External 16 MHz
+808.menu.clock.external_16MHz.upload.speed=115200
+808.menu.clock.external_16MHz.bootloader.OSCCFG=0x01
+808.menu.clock.external_16MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+808.menu.clock.external_16MHz.build.f_cpu=16000000L
+
+808.menu.clock.external_12MHz=External 12 MHz
+808.menu.clock.external_12MHz.upload.speed=115200
+808.menu.clock.external_12MHz.bootloader.OSCCFG=0x01
+808.menu.clock.external_12MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+808.menu.clock.external_12MHz.build.f_cpu=12000000L
+
+808.menu.clock.external_8MHz=External 8 MHz
+808.menu.clock.external_8MHz.upload.speed=115200
+808.menu.clock.external_8MHz.bootloader.OSCCFG=0x01
+808.menu.clock.external_8MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+808.menu.clock.external_8MHz.build.f_cpu=8000000L
+
+808.menu.clock.external_4MHz=External 4 MHz
+808.menu.clock.external_4MHz.upload.speed=115200
+808.menu.clock.external_4MHz.bootloader.OSCCFG=0x01
+808.menu.clock.external_4MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+808.menu.clock.external_4MHz.build.f_cpu=4000000L
+
+808.menu.clock.external_1MHz=External 1 MHz
+808.menu.clock.external_1MHz.upload.speed=115200
+808.menu.clock.external_1MHz.bootloader.OSCCFG=0x01
+808.menu.clock.external_1MHz.build.oscillator=-DUSE_EXTERNAL_OSCILLATOR
+808.menu.clock.external_1MHz.build.f_cpu=1000000L
+
+# Bootloader
+808.menu.bootloader.no_bootloader=No bootloader
+808.menu.bootloader.no_bootloader.upload.maximum_size=8192
+808.menu.bootloader.no_bootloader.upload.extra_params=
+808.menu.bootloader.no_bootloader.build.text_section_start=.text=0x0
+808.menu.bootloader.no_bootloader.build.export_merged_output=false
+808.menu.bootloader.no_bootloader.bootloader.file=empty/empty.hex
+808.menu.bootloader.no_bootloader.bootloader.BOOTEND=0x00
+
+808.menu.bootloader.uart0_default=Optiboot (UART0 default pins)
+808.menu.bootloader.uart0_default.upload.maximum_size=7680
+808.menu.bootloader.uart0_default.upload.protocol=arduino
+808.menu.bootloader.uart0_default.upload.port=UART0_DEF
+808.menu.bootloader.uart0_default.upload.extra_params=
+808.menu.bootloader.uart0_default.build.text_section_start=.text=0x200
+808.menu.bootloader.uart0_default.build.export_merged_output=true
+808.menu.bootloader.uart0_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+808.menu.bootloader.uart0_default.bootloader.BOOTEND=0x02
+808.menu.bootloader.uart0_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+808.menu.bootloader.uart0_alternative=Optiboot (UART0 alternative pins)
+808.menu.bootloader.uart0_alternative.upload.maximum_size=7680
+808.menu.bootloader.uart0_alternative.upload.protocol=arduino
+808.menu.bootloader.uart0_alternative.upload.port=UART0_ALT
+808.menu.bootloader.uart0_alternative.upload.extra_params=
+808.menu.bootloader.uart0_alternative.build.text_section_start=.text=0x200
+808.menu.bootloader.uart0_alternative.build.export_merged_output=true
+808.menu.bootloader.uart0_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+808.menu.bootloader.uart0_alternative.bootloader.BOOTEND=0x02
+808.menu.bootloader.uart0_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+808.menu.bootloader.uart1_default=Optiboot (UART1 default pins)
+808.menu.bootloader.uart1_default.upload.maximum_size=7680
+808.menu.bootloader.uart1_default.upload.protocol=arduino
+808.menu.bootloader.uart1_default.upload.port=UART1_DEF
+808.menu.bootloader.uart1_default.upload.extra_params=
+808.menu.bootloader.uart1_default.build.text_section_start=.text=0x200
+808.menu.bootloader.uart1_default.build.export_merged_output=true
+808.menu.bootloader.uart1_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+808.menu.bootloader.uart1_default.bootloader.BOOTEND=0x02
+808.menu.bootloader.uart1_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+808.menu.bootloader.uart1_alternative=Optiboot (UART1 alternative pins)
+808.menu.bootloader.uart1_alternative.upload.maximum_size=7680
+808.menu.bootloader.uart1_alternative.upload.protocol=arduino
+808.menu.bootloader.uart1_alternative.upload.port=UART1_ALT
+808.menu.bootloader.uart1_alternative.upload.extra_params=
+808.menu.bootloader.uart1_alternative.build.text_section_start=.text=0x200
+808.menu.bootloader.uart1_alternative.build.export_merged_output=true
+808.menu.bootloader.uart1_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+808.menu.bootloader.uart1_alternative.bootloader.BOOTEND=0x02
+808.menu.bootloader.uart1_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+
+808.menu.bootloader.uart2_default=Optiboot (UART2 default pins)
+808.menu.bootloader.uart2_default.upload.maximum_size=7680
+808.menu.bootloader.uart2_default.upload.protocol=arduino
+808.menu.bootloader.uart2_default.upload.port=UART2_DEF
+808.menu.bootloader.uart2_default.upload.extra_params=
+808.menu.bootloader.uart2_default.build.text_section_start=.text=0x200
+808.menu.bootloader.uart2_default.build.export_merged_output=true
+808.menu.bootloader.uart2_default.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+808.menu.bootloader.uart2_default.bootloader.BOOTEND=0x02
+808.menu.bootloader.uart2_default.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
+808.menu.bootloader.uart2_alternative=Optiboot (UART2 alternative pins)
+808.menu.bootloader.uart2_alternative.upload.maximum_size=7680
+808.menu.bootloader.uart2_alternative.upload.protocol=arduino
+808.menu.bootloader.uart2_alternative.upload.port=UART2_ALT
+808.menu.bootloader.uart2_alternative.upload.extra_params=
+808.menu.bootloader.uart2_alternative.build.text_section_start=.text=0x200
+808.menu.bootloader.uart2_alternative.build.export_merged_output=true
+808.menu.bootloader.uart2_alternative.bootloader.file=optiboot/bootloaders/mega0/{upload.speed}/Optiboot_mega0_{upload.port}_{upload.speed}_A7.hex
+808.menu.bootloader.uart2_alternative.bootloader.BOOTEND=0x02
+808.menu.bootloader.uart2_alternative.bootloader.SYSCFG0=0b1100100{bootloader.eesave_bit}
diff --git a/megaavr/bootloaders/empty/empty.hex b/megaavr/bootloaders/empty/empty.hex
new file mode 100644
index 0000000..7ef5593
--- /dev/null
+++ b/megaavr/bootloaders/empty/empty.hex
@@ -0,0 +1 @@
+:00000001FF
\ No newline at end of file
diff --git a/megaavr/bootloaders/optiboot/Makefile b/megaavr/bootloaders/optiboot/Makefile
new file mode 100755
index 0000000..f6620a3
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/Makefile
@@ -0,0 +1,174 @@
+# Makefile for AVR Mega-0 (4809), Tiny-0, and Tiny-1 version of Optiboot
+# Bill Westfield, 2019
+# $Id$
+#
+# Edit History
+# Sep-2019 refactor from the normal AVR Makefile.
+# * Copyright 2013-2019 by Bill Westfield. Part of Optiboot.
+# * This software is licensed under version 2 of the Gnu Public Licence.
+# * See optiboot.c for details.
+
+HELPTEXT = "\n"
+#----------------------------------------------------------------------
+#
+# program name should not be changed...
+PROGRAM = optiboot_x
+MF:= $(MAKEFILE_LIST)
+
+# export symbols to recursive makes (for ISP)
+export
+
+LDSECTIONS = -Wl,-section-start=.text=0 \
+ -Wl,--section-start=.application=0x200 \
+ -Wl,--section-start=.version=0x1fe
+
+BAUD_RATE=115200
+
+# Place your avr-gcc tool root here
+GCCROOT =/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/
+
+#
+# End of build environment code.
+
+
+CC = $(GCCROOT)avr-gcc
+RCC = $(abspath $(CC))
+#$(info wildcard ("$(wildcard $(CC))",""))
+ifndef PRODUCTION
+$(info Using Compiler at: ${RCC})
+endif
+
+
+
+
+OPTIMIZE = -Os -fno-split-wide-types -mrelax
+
+# Override is only needed by avr-lib build system.
+
+override CFLAGS = -g -Wall $(OPTIMIZE)
+override LDFLAGS = $(LDSECTIONS) -Wl,--relax -nostartfiles -nostdlib
+
+OBJCOPY = $(GCCROOT)avr-objcopy
+OBJDUMP = $(GCCROOT)avr-objdump
+SIZE = $(GCCROOT)avr-size
+
+include parse_options.mk
+
+.PRECIOUS: optiboot_%.elf
+
+ifndef PRODUCTION
+LISTING= $(OBJDUMP) -S
+else
+LISTING= @true
+endif
+
+ifeq ($(SKIP_BOOTLOADER_ON_POR), 0)
+START_APP_ON_POR=0
+else
+START_APP_ON_POR=1
+endif
+
+ifeq ($(UARTTX), A0)
+UART=0
+UARTMUX=DEF
+endif
+ifeq ($(UARTTX), B0)
+UART=3
+UARTMUX=DEF
+endif
+ifeq ($(UARTTX), C0)
+UART=1
+UARTMUX=DEF
+endif
+ifeq ($(UARTTX), F0)
+UART=2
+UARTMUX=DEF
+endif
+ifeq ($(UARTTX), A4)
+UART=0
+UARTMUX=ALT
+endif
+ifeq ($(UARTTX), B4)
+UART=3
+UARTMUX=ALT
+endif
+ifeq ($(UARTTX), C4)
+UART=1
+UARTMUX=ALT
+endif
+ifeq ($(UARTTX), F4)
+UART=2
+UARTMUX=ALT
+endif
+
+
+#---------------------------------------------------------------------------
+# "Chip-level Platform" targets.
+# A "Chip-level Platform" compiles for a particular chip, but probably does
+# not have "standard" values for things like clock speed, LED pin, etc.
+# Makes for chip-level platforms should usually explicitly define their
+# options like: "make atmega4809 UARTTX=A4 LED=D0"
+#---------------------------------------------------------------------------
+#
+# Mega0, tiny0, tiny1 don't really have any chip-specific requirements.
+#
+# Note about fuses:
+# The fuses are defined in the source code. There are 9!
+# Be sure to use a programmer that will program the fuses from the object file.
+#
+#---------------------------------------------------------------------------
+#
+
+
+
+optiboot_%.hex: optiboot_%.elf
+ $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
+
+%.hex: %.elf
+ $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
+
+%.elf: optiboot_x.c FORCE
+ $(CC) $(CFLAGS) $(CPU_OPTIONS) $(LED_OPTIONS) $(UART_OPTIONS) $(COMMON_OPTIONS) $(POR) $(LDFLAGS) $(PACK_OPT) -mmcu=$(TARGET) -o $@ $<
+ $(SIZE) $@
+
+
+#---------------------------------------------------------------------------
+# "Board-level Platform" targets.
+# A "Board-level Platform" implies a manufactured platform with a particular
+# AVR_FREQ, LED, and so on. Parameters are not particularly changable from
+# the "make" command line.
+# Most of the board-level platform builds should envoke make recursively
+# appropriate specific options
+#---------------------------------------------------------------------------
+
+
+mega0: TARGET=atmega4809
+mega0: bootloaders/mega0/$(BAUD_RATE)/Optiboot_mega0_UART$(UART)_$(UARTMUX)_$(BAUD_RATE)_$(LED).hex
+
+
+#---------------------------------------------------------------------------
+#
+# Generic build instructions
+#
+
+FORCE:
+
+#windows "rm" is dumb and objects to wildcards that don't exist
+clean:
+ @touch __temp_.o __temp_.elf __temp_.lst __temp_.map
+ @touch __temp_.sym __temp_.lss __temp_.eep __temp_.srec
+ @touch __temp_.bin __temp_.hex __temp_.tmp.sh
+ rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.tmp.sh
+
+clean_asm:
+ rm -rf *.lst
+
+%.lst: %.elf FORCE
+ $(OBJDUMP) -h -S $< > $@
+
+%.srec: %.elf FORCE
+ $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
+
+%.bin: %.elf FORCE
+ $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@
+
diff --git a/megaavr/bootloaders/optiboot/README.TXT b/megaavr/bootloaders/optiboot/README.TXT
new file mode 100755
index 0000000..b4db4c9
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/README.TXT
@@ -0,0 +1,99 @@
+This directory contains the Optiboot small bootloader for AVR
+microcontrollers, somewhat modified specifically for the Arduino
+environment.
+
+Optiboot is more fully described here: http://github.com/Optiboot/optiboot
+and is the work of Peter Knight (aka Cathedrow), building on work of Jason P
+Kyle, Spiff, and Ladyada. More recent maintenance and modifications are by
+Bill Westfield (aka WestfW)
+
+Arduino-specific issues are tracked as part of the Arduino project
+at http://github.com/arduino/Arduino
+
+
+Most of the information in this file is superceeded by the wiki content at
+https://github.com/Optiboot/optiboot/wiki
+
+It's till here "just in case."
+
+------------------------------------------------------------
+
+Building optiboot for Arduino.
+
+Production builds of optiboot for Arduino are done on a Mac in "unix mode"
+using CrossPack-AVR-20100115. CrossPack tracks WINAVR (for windows), which
+is just a package of avr-gcc and related utilities, so similar builds should
+work on Windows or Linux systems.
+
+One of the Arduino-specific changes is modifications to the makefile to
+allow building optiboot using only the tools installed as part of the
+Arduino environment, or the Arduino source development tree. All three
+build procedures should yield identical binaries (.hex files) (although
+this may change if compiler versions drift apart between CrossPack and
+the Arduino IDE.)
+
+
+Building Optiboot in the Arduino IDE Install.
+
+Work in the .../hardware/arduino/bootloaders/optiboot/ and use the
+"omake " command, which just generates a command that uses
+the arduino-included "make" utility with a command like:
+ make OS=windows ENV=arduino
+or make OS=macosx ENV=arduino
+On windows, this assumes you're using the windows command shell. If
+you're using a cygwin or mingw shell, or have one of those in your
+path, the build will probably break due to slash vs backslash issues.
+On a Mac, if you have the developer tools installed, you can use the
+Apple-supplied version of make.
+The makefile uses relative paths ("../../../tools/" and such) to find
+the programs it needs, so you need to work in the existing optiboot
+directory (or something created at the same "level") for it to work.
+
+
+Building Optiboot in the Arduino Source Development Install.
+
+In this case, there is no special shell script, and you're assumed to
+have "make" installed somewhere in your path.
+Build the Arduino source ("ant build") to unpack the tools into the
+expected directory.
+Work in Arduino/hardware/arduino/bootloaders/optiboot and use
+ make OS=windows ENV=arduinodev
+or make OS=macosx ENV=arduinodev
+
+
+Programming Chips Using the _isp Targets
+
+The CPU targets have corresponding ISP targets that will actuall
+program the bootloader into a chip. "atmega328_isp" for the atmega328,
+for example. These will set the fuses and lock bits as appropriate as
+well as uploading the bootloader code.
+
+ISP Targets in Version 5.0 and later:
+
+The isp targets are now built using a separate "Makefile.isp" makefile,
+which should make modification easier and more obvious. This also fixes
+the atmega8_isp target problem mentioned below. The default
+configuration assumes an ArduinoISP setup, but you will probably need to
+update at least the serial port, since those are different for each
+Arduino board and/or system/
+
+
+ISP Targets in Version 4.6 and earlier:
+
+The older makefiles default to using a USB programmer, but you can use a
+serial programmer like ArduinoISP by changing the appropriate variables
+when you invoke make:
+
+ make ISPTOOL=stk500v1 ISPPORT=/dev/tty.usbserial-A20e1eAN \
+ ISPSPEED=-b19200 atmega328_isp
+
+The "atmega8_isp" target does not currently work, because the mega8
+doesn't have the "extended" fuse that the generic ISP target wants to
+pass on to avrdude. You'll need to run avrdude manually.
+
+
+Standard Targets
+
+I've reduced the pre-built and source-version-controlled targets
+(.hex and .lst files included in the git repository) to just the
+three basic 16MHz targets: atmega8, atmega16, atmega328.
diff --git a/megaavr/bootloaders/optiboot/boot_opt.h b/megaavr/bootloaders/optiboot/boot_opt.h
new file mode 100755
index 0000000..d0285a6
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/boot_opt.h
@@ -0,0 +1,101 @@
+// Get all the "standard" definitions from the official boot.h
+#include
+
+
+/*
+ * Implement some optimized versions that will use OUT instead
+ * of STS to write SPMCSR.
+ * (However, omit the *_extended_short, since by the time you
+ * need _extended_, the extra byte shouldn't be relevant any more)
+ *
+ * The C preprocessor can not determin at compile time whether SPMCSR is
+ * "out of range" of the OUT instruction, but we CAN do that in the
+ * assembler. We can even make it pretty with a macro.
+ * With this modification, the _short functions should work on cpus
+ * (like ATmega128) where STS is required.
+ */
+
+asm(".macro __wr_spmcsr p, v \n\t"
+ ".if \\p > 0x57 \n\t"
+ "sts \\p, \\v \n\t"
+ ".else \n\t"
+ "out \\p-0x20, \\v \n\t"
+ ".endif \n\t"
+ ".endm \n");
+
+
+#if defined(__SPM_REG)
+
+#define __boot_page_fill_short(address, data) \
+(__extension__({ \
+ __asm__ __volatile__ \
+ ( \
+ "movw r0, %3\n\t" \
+ "__wr_spmcsr %0, %1\n\t" \
+ "spm\n\t" \
+ "clr r1\n\t" \
+ : \
+ : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
+ "r" ((uint8_t)__BOOT_PAGE_FILL), \
+ "z" ((uint16_t)address), \
+ "r" ((uint16_t)data) \
+ : "r0" \
+ ); \
+}))
+
+#define __boot_page_erase_short(address) \
+(__extension__({ \
+ __asm__ __volatile__ \
+ ( \
+ "__wr_spmcsr %0, %1\n\t" \
+ "spm\n\t" \
+ : \
+ : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
+ "r" ((uint8_t)__BOOT_PAGE_ERASE), \
+ "z" ((uint16_t)address) \
+ ); \
+}))
+
+#define __boot_page_write_short(address) \
+(__extension__({ \
+ __asm__ __volatile__ \
+ ( \
+ "__wr_spmcsr %0, %1\n\t" \
+ "spm\n\t" \
+ : \
+ : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
+ "r" ((uint8_t)__BOOT_PAGE_WRITE), \
+ "z" ((uint16_t)address) \
+ ); \
+}))
+
+#define __boot_rww_enable_short() \
+(__extension__({ \
+ __asm__ __volatile__ \
+ ( \
+ "__wr_spmcsr %0, %1\n\t" \
+ "spm\n\t" \
+ : \
+ : "i" (_SFR_MEM_ADDR(__SPM_REG)), \
+ "r" ((uint8_t)__BOOT_RWW_ENABLE) \
+ ); \
+}))
+
+#endif // __SPM_REG
+
+#ifndef __boot_page_erase_short
+
+/*
+ * if __SPM_REG didn't get defined by now, but we didn't exit it means
+ * we have some sort of new-fangled chip that post-dates the version
+ * of boot.h that we know about. In this case, it's possible that the
+ * standard boot.h still has workable functions, so we'll alias those.
+ */
+
+#define __boot_page_fill_short(address, data) boot_page_fill(address, data)
+#define __boot_page_erase_short(address) boot_page_erase(address)
+#define __boot_page_write_short(address) boot_page_write(address)
+#define __boot_rww_enable_short() boot_rww_enable()
+
+#endif
+
diff --git a/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART0_ALT_115200_A7.hex b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART0_ALT_115200_A7.hex
new file mode 100644
index 0000000..5ea5b82
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART0_ALT_115200_A7.hex
@@ -0,0 +1,32 @@
+:1000000001C0D9C0112480914000882369F0282FB5
+:1000100030E083FD03C02C7F232B31F4809340001C
+:100020008CBB80E0B0D0ECC0A895049A0C9A81E01B
+:100030008093E205809182128370813029F58CE5EE
+:1000400090E0809308089093090881E080930B0862
+:1000500083E0809307081092050880EC80930608DF
+:1000600088E091D0079A87E0815089F4A8950DE93E
+:1000700083E0D82E7CD08134F1F479D0182F8CD045
+:10008000123889F480E013C083E790E0DACF179A42
+:100090002EEC36E5A8959091040897FDE8CF215005
+:1000A0003109C1F7E1CF89E0113809F083E058D078
+:1000B00080E156D0DFCF823419F484E175D0F8CFD7
+:1000C000853411F485E0FACF853531F450D0C82F4E
+:1000D0004ED0D82F61D0ECCF863519F484E064D0AF
+:1000E000D1CF8436B9F443D042D0182F40D08634D3
+:1000F00079F4D05C3CD0888321961150D9F74CD04C
+:1001000004BFD0920010809102108370E1F7D0CF2D
+:10011000DC5EF0CF843791F42AD029D0182F27D075
+:10012000F82E3AD086E4F81207C0D05C8881219678
+:1001300017D01150D9F7BCCFDC5EF8CF853751F41A
+:100140002BD0809100110CD08091011109D08091A9
+:100150000211ADCF813509F0BDCF81E014D0BACF07
+:100160009091040895FFFCCF809302080895809138
+:10017000040887FFFCCF909101088091000892FD50
+:1001800001C0A89508959091010190FDFCCF98EDD4
+:1001900094BF809300010895EADF803219F081E076
+:1001A000F2DFFFCF84E1DCCFCF93C82FE0DFC15077
+:1001B000E9F7CF91F1CF683048F48DE984BF6093BF
+:1001C0000010809102108370E1F70895FC014083D4
+:0201D000089590
+:0201FE000009F6
+:00000001FF
diff --git a/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART0_DEF_115200_A7.hex b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART0_DEF_115200_A7.hex
new file mode 100644
index 0000000..516ec1f
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART0_DEF_115200_A7.hex
@@ -0,0 +1,31 @@
+:1000000001C0D8C0112480914000882369F0282FB6
+:1000100030E083FD03C02C7F232B31F4809340001C
+:100020008CBB80E0AFD0ECC0A895009A089A1092E3
+:10003000E205809182128370813029F58CE590E091
+:10004000809308089093090881E080930B0883E06F
+:10005000809307081092050880EC8093060888E0DA
+:1000600091D0079A87E0815089F4A8950DE983E043
+:10007000D82E7CD08134F1F479D0182F8CD012385E
+:1000800089F480E013C083E790E0DACF179A2EEC72
+:1000900036E5A8959091040897FDE8CF21503109E5
+:1000A000C1F7E1CF89E0113809F083E058D080E151
+:1000B00056D0DFCF823419F484E175D0F8CF85347F
+:1000C00011F485E0FACF853531F450D0C82F4ED0E9
+:1000D000D82F61D0ECCF863519F484E064D0D1CF2D
+:1000E0008436B9F443D042D0182F40D0863479F406
+:1000F000D05C3CD0888321961150D9F74CD004BFF6
+:10010000D0920010809102108370E1F7D0CFDC5EB6
+:10011000F0CF843791F42AD029D0182F27D0F82E89
+:100120003AD086E4F81207C0D05C8881219617D0B7
+:100130001150D9F7BCCFDC5EF8CF853751F42BD006
+:10014000809100110CD08091011109D08091021191
+:10015000ADCF813509F0BDCF81E014D0BACF9091F9
+:10016000040895FFFCCF809302080895809104084D
+:1001700087FFFCCF909101088091000892FD01C09B
+:10018000A89508959091010190FDFCCF98ED94BF42
+:10019000809300010895EADF803219F081E0F2DFF8
+:1001A000FFCF84E1DCCFCF93C82FE0DFC150E9F768
+:1001B000CF91F1CF683048F48DE984BF609300108F
+:1001C000809102108370E1F70895FC014083089547
+:0201FE000009F6
+:00000001FF
diff --git a/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART1_ALT_115200_A7.hex b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART1_ALT_115200_A7.hex
new file mode 100644
index 0000000..e54179a
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART1_ALT_115200_A7.hex
@@ -0,0 +1,32 @@
+:1000000001C0D9C0112480914000882369F0282FB5
+:1000100030E083FD03C02C7F232B31F4809340001C
+:100020008CBB80E0B0D0ECC0A895449A4C9A84E098
+:100030008093E205809182128370813029F58CE5EE
+:1000400090E0809328089093290881E080932B0802
+:1000500083E0809327081092250880EC809326087F
+:1000600088E091D0079A87E0815089F4A8950DE93E
+:1000700083E0D82E7CD08134F1F479D0182F8CD045
+:10008000123889F480E013C083E790E0DACF179A42
+:100090002EEC36E5A8959091240897FDE8CF2150E5
+:1000A0003109C1F7E1CF89E0113809F083E058D078
+:1000B00080E156D0DFCF823419F484E175D0F8CFD7
+:1000C000853411F485E0FACF853531F450D0C82F4E
+:1000D0004ED0D82F61D0ECCF863519F484E064D0AF
+:1000E000D1CF8436B9F443D042D0182F40D08634D3
+:1000F00079F4D05C3CD0888321961150D9F74CD04C
+:1001000004BFD0920010809102108370E1F7D0CF2D
+:10011000DC5EF0CF843791F42AD029D0182F27D075
+:10012000F82E3AD086E4F81207C0D05C8881219678
+:1001300017D01150D9F7BCCFDC5EF8CF853751F41A
+:100140002BD0809100110CD08091011109D08091A9
+:100150000211ADCF813509F0BDCF81E014D0BACF07
+:100160009091240895FFFCCF8093220808958091F8
+:10017000240887FFFCCF909121088091200892FDF0
+:1001800001C0A89508959091010190FDFCCF98EDD4
+:1001900094BF809300010895EADF803219F081E076
+:1001A000F2DFFFCF84E1DCCFCF93C82FE0DFC15077
+:1001B000E9F7CF91F1CF683048F48DE984BF6093BF
+:1001C0000010809102108370E1F70895FC014083D4
+:0201D000089590
+:0201FE000009F6
+:00000001FF
diff --git a/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART1_DEF_115200_A7.hex b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART1_DEF_115200_A7.hex
new file mode 100644
index 0000000..e91e29a
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART1_DEF_115200_A7.hex
@@ -0,0 +1,31 @@
+:1000000001C0D8C0112480914000882369F0282FB6
+:1000100030E083FD03C02C7F232B31F4809340001C
+:100020008CBB80E0AFD0ECC0A895409A489A109263
+:10003000E205809182128370813029F58CE590E091
+:10004000809328089093290881E080932B0883E00F
+:10005000809327081092250880EC8093260888E07A
+:1000600091D0079A87E0815089F4A8950DE983E043
+:10007000D82E7CD08134F1F479D0182F8CD012385E
+:1000800089F480E013C083E790E0DACF179A2EEC72
+:1000900036E5A8959091240897FDE8CF21503109C5
+:1000A000C1F7E1CF89E0113809F083E058D080E151
+:1000B00056D0DFCF823419F484E175D0F8CF85347F
+:1000C00011F485E0FACF853531F450D0C82F4ED0E9
+:1000D000D82F61D0ECCF863519F484E064D0D1CF2D
+:1000E0008436B9F443D042D0182F40D0863479F406
+:1000F000D05C3CD0888321961150D9F74CD004BFF6
+:10010000D0920010809102108370E1F7D0CFDC5EB6
+:10011000F0CF843791F42AD029D0182F27D0F82E89
+:100120003AD086E4F81207C0D05C8881219617D0B7
+:100130001150D9F7BCCFDC5EF8CF853751F42BD006
+:10014000809100110CD08091011109D08091021191
+:10015000ADCF813509F0BDCF81E014D0BACF9091F9
+:10016000240895FFFCCF80932208089580912408ED
+:1001700087FFFCCF909121088091200892FD01C05B
+:10018000A89508959091010190FDFCCF98ED94BF42
+:10019000809300010895EADF803219F081E0F2DFF8
+:1001A000FFCF84E1DCCFCF93C82FE0DFC150E9F768
+:1001B000CF91F1CF683048F48DE984BF609300108F
+:1001C000809102108370E1F70895FC014083089547
+:0201FE000009F6
+:00000001FF
diff --git a/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART2_ALT_115200_A7.hex b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART2_ALT_115200_A7.hex
new file mode 100644
index 0000000..0442ebf
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART2_ALT_115200_A7.hex
@@ -0,0 +1,32 @@
+:1000000001C0D9C0112480914000882369F0282FB5
+:1000100030E083FD03C02C7F232B31F4809340001C
+:100020008CBB80E0B0D0ECC0A895A49AAC9A80E1DB
+:100030008093E205809182128370813029F58CE5EE
+:1000400090E0809348089093490881E080934B08A2
+:1000500083E0809347081092450880EC809346081F
+:1000600088E091D0079A87E0815089F4A8950DE93E
+:1000700083E0D82E7CD08134F1F479D0182F8CD045
+:10008000123889F480E013C083E790E0DACF179A42
+:100090002EEC36E5A8959091440897FDE8CF2150C5
+:1000A0003109C1F7E1CF89E0113809F083E058D078
+:1000B00080E156D0DFCF823419F484E175D0F8CFD7
+:1000C000853411F485E0FACF853531F450D0C82F4E
+:1000D0004ED0D82F61D0ECCF863519F484E064D0AF
+:1000E000D1CF8436B9F443D042D0182F40D08634D3
+:1000F00079F4D05C3CD0888321961150D9F74CD04C
+:1001000004BFD0920010809102108370E1F7D0CF2D
+:10011000DC5EF0CF843791F42AD029D0182F27D075
+:10012000F82E3AD086E4F81207C0D05C8881219678
+:1001300017D01150D9F7BCCFDC5EF8CF853751F41A
+:100140002BD0809100110CD08091011109D08091A9
+:100150000211ADCF813509F0BDCF81E014D0BACF07
+:100160009091440895FFFCCF8093420808958091B8
+:10017000440887FFFCCF909141088091400892FD90
+:1001800001C0A89508959091010190FDFCCF98EDD4
+:1001900094BF809300010895EADF803219F081E076
+:1001A000F2DFFFCF84E1DCCFCF93C82FE0DFC15077
+:1001B000E9F7CF91F1CF683048F48DE984BF6093BF
+:1001C0000010809102108370E1F70895FC014083D4
+:0201D000089590
+:0201FE000009F6
+:00000001FF
diff --git a/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART2_DEF_115200_A7.hex b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART2_DEF_115200_A7.hex
new file mode 100644
index 0000000..ac3719b
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART2_DEF_115200_A7.hex
@@ -0,0 +1,31 @@
+:1000000001C0D8C0112480914000882369F0282FB6
+:1000100030E083FD03C02C7F232B31F4809340001C
+:100020008CBB80E0AFD0ECC0A895A09AA89A1092A3
+:10003000E205809182128370813029F58CE590E091
+:10004000809348089093490881E080934B0883E0AF
+:10005000809347081092450880EC8093460888E01A
+:1000600091D0079A87E0815089F4A8950DE983E043
+:10007000D82E7CD08134F1F479D0182F8CD012385E
+:1000800089F480E013C083E790E0DACF179A2EEC72
+:1000900036E5A8959091440897FDE8CF21503109A5
+:1000A000C1F7E1CF89E0113809F083E058D080E151
+:1000B00056D0DFCF823419F484E175D0F8CF85347F
+:1000C00011F485E0FACF853531F450D0C82F4ED0E9
+:1000D000D82F61D0ECCF863519F484E064D0D1CF2D
+:1000E0008436B9F443D042D0182F40D0863479F406
+:1000F000D05C3CD0888321961150D9F74CD004BFF6
+:10010000D0920010809102108370E1F7D0CFDC5EB6
+:10011000F0CF843791F42AD029D0182F27D0F82E89
+:100120003AD086E4F81207C0D05C8881219617D0B7
+:100130001150D9F7BCCFDC5EF8CF853751F42BD006
+:10014000809100110CD08091011109D08091021191
+:10015000ADCF813509F0BDCF81E014D0BACF9091F9
+:10016000440895FFFCCF809342080895809144088D
+:1001700087FFFCCF909141088091400892FD01C01B
+:10018000A89508959091010190FDFCCF98ED94BF42
+:10019000809300010895EADF803219F081E0F2DFF8
+:1001A000FFCF84E1DCCFCF93C82FE0DFC150E9F768
+:1001B000CF91F1CF683048F48DE984BF609300108F
+:1001C000809102108370E1F70895FC014083089547
+:0201FE000009F6
+:00000001FF
diff --git a/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART3_ALT_115200_A7.hex b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART3_ALT_115200_A7.hex
new file mode 100644
index 0000000..3d026f0
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART3_ALT_115200_A7.hex
@@ -0,0 +1,32 @@
+:1000000001C0D9C0112480914000882369F0282FB5
+:1000100030E083FD03C02C7F232B31F4809340001C
+:100020008CBB80E0B0D0ECC0A895249A2C9A80E4D8
+:100030008093E205809182128370813029F58CE5EE
+:1000400090E0809368089093690881E080936B0842
+:1000500083E0809367081092650880EC80936608BF
+:1000600088E091D0079A87E0815089F4A8950DE93E
+:1000700083E0D82E7CD08134F1F479D0182F8CD045
+:10008000123889F480E013C083E790E0DACF179A42
+:100090002EEC36E5A8959091640897FDE8CF2150A5
+:1000A0003109C1F7E1CF89E0113809F083E058D078
+:1000B00080E156D0DFCF823419F484E175D0F8CFD7
+:1000C000853411F485E0FACF853531F450D0C82F4E
+:1000D0004ED0D82F61D0ECCF863519F484E064D0AF
+:1000E000D1CF8436B9F443D042D0182F40D08634D3
+:1000F00079F4D05C3CD0888321961150D9F74CD04C
+:1001000004BFD0920010809102108370E1F7D0CF2D
+:10011000DC5EF0CF843791F42AD029D0182F27D075
+:10012000F82E3AD086E4F81207C0D05C8881219678
+:1001300017D01150D9F7BCCFDC5EF8CF853751F41A
+:100140002BD0809100110CD08091011109D08091A9
+:100150000211ADCF813509F0BDCF81E014D0BACF07
+:100160009091640895FFFCCF809362080895809178
+:10017000640887FFFCCF909161088091600892FD30
+:1001800001C0A89508959091010190FDFCCF98EDD4
+:1001900094BF809300010895EADF803219F081E076
+:1001A000F2DFFFCF84E1DCCFCF93C82FE0DFC15077
+:1001B000E9F7CF91F1CF683048F48DE984BF6093BF
+:1001C0000010809102108370E1F70895FC014083D4
+:0201D000089590
+:0201FE000009F6
+:00000001FF
diff --git a/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART3_DEF_115200_A7.hex b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART3_DEF_115200_A7.hex
new file mode 100644
index 0000000..f654a0c
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/bootloaders/mega0/115200/Optiboot_mega0_UART3_DEF_115200_A7.hex
@@ -0,0 +1,31 @@
+:1000000001C0D8C0112480914000882369F0282FB6
+:1000100030E083FD03C02C7F232B31F4809340001C
+:100020008CBB80E0AFD0ECC0A895209A289A1092A3
+:10003000E205809182128370813029F58CE590E091
+:10004000809368089093690881E080936B0883E04F
+:10005000809367081092650880EC8093660888E0BA
+:1000600091D0079A87E0815089F4A8950DE983E043
+:10007000D82E7CD08134F1F479D0182F8CD012385E
+:1000800089F480E013C083E790E0DACF179A2EEC72
+:1000900036E5A8959091640897FDE8CF2150310985
+:1000A000C1F7E1CF89E0113809F083E058D080E151
+:1000B00056D0DFCF823419F484E175D0F8CF85347F
+:1000C00011F485E0FACF853531F450D0C82F4ED0E9
+:1000D000D82F61D0ECCF863519F484E064D0D1CF2D
+:1000E0008436B9F443D042D0182F40D0863479F406
+:1000F000D05C3CD0888321961150D9F74CD004BFF6
+:10010000D0920010809102108370E1F7D0CFDC5EB6
+:10011000F0CF843791F42AD029D0182F27D0F82E89
+:100120003AD086E4F81207C0D05C8881219617D0B7
+:100130001150D9F7BCCFDC5EF8CF853751F42BD006
+:10014000809100110CD08091011109D08091021191
+:10015000ADCF813509F0BDCF81E014D0BACF9091F9
+:10016000640895FFFCCF809362080895809164082D
+:1001700087FFFCCF909161088091600892FD01C0DB
+:10018000A89508959091010190FDFCCF98ED94BF42
+:10019000809300010895EADF803219F081E0F2DFF8
+:1001A000FFCF84E1DCCFCF93C82FE0DFC150E9F768
+:1001B000CF91F1CF683048F48DE984BF609300108F
+:1001C000809102108370E1F70895FC014083089547
+:0201FE000009F6
+:00000001FF
diff --git a/megaavr/bootloaders/optiboot/makeall b/megaavr/bootloaders/optiboot/makeall
new file mode 100755
index 0000000..95c1b1c
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/makeall
@@ -0,0 +1,9 @@
+# Build for 115200 baud
+make mega0 UARTTX=A0 TIMEOUT=1 LED=A7 BAUD_RATE=115200 SKIP_BOOTLOADER_ON_POR=1
+make mega0 UARTTX=A4 TIMEOUT=1 LED=A7 BAUD_RATE=115200 SKIP_BOOTLOADER_ON_POR=1
+make mega0 UARTTX=B0 TIMEOUT=1 LED=A7 BAUD_RATE=115200 SKIP_BOOTLOADER_ON_POR=1
+make mega0 UARTTX=B4 TIMEOUT=1 LED=A7 BAUD_RATE=115200 SKIP_BOOTLOADER_ON_POR=1
+make mega0 UARTTX=C0 TIMEOUT=1 LED=A7 BAUD_RATE=115200 SKIP_BOOTLOADER_ON_POR=1
+make mega0 UARTTX=C4 TIMEOUT=1 LED=A7 BAUD_RATE=115200 SKIP_BOOTLOADER_ON_POR=1
+make mega0 UARTTX=F0 TIMEOUT=1 LED=A7 BAUD_RATE=115200 SKIP_BOOTLOADER_ON_POR=1
+make mega0 UARTTX=F4 TIMEOUT=1 LED=A7 BAUD_RATE=115200 SKIP_BOOTLOADER_ON_POR=1
diff --git a/megaavr/bootloaders/optiboot/omake b/megaavr/bootloaders/optiboot/omake
new file mode 100755
index 0000000..59d23d9
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/omake
@@ -0,0 +1,9 @@
+#%/bin/bash
+if [ -d ../../../tools ]; then
+ mypath=../../../tools/avr/bin
+else
+ mypath=../../../../tools/avr/bin
+fi
+
+echo $mypath/make OS=macosx ENV=arduino $*
+$mypath/make OS=macosx ENV=arduino $*
diff --git a/megaavr/bootloaders/optiboot/omake.bat b/megaavr/bootloaders/optiboot/omake.bat
new file mode 100755
index 0000000..83538ca
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/omake.bat
@@ -0,0 +1,2 @@
+call .\install-avr-tools.bat
+make %*
diff --git a/megaavr/bootloaders/optiboot/optiboot_x.c b/megaavr/bootloaders/optiboot/optiboot_x.c
new file mode 100755
index 0000000..607d682
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/optiboot_x.c
@@ -0,0 +1,734 @@
+/************************************************************/
+/* Optiboot bootloader for Mega0, Tiny0, Tiny1 */
+/* */
+/* https://github.com/optiboot/optiboot */
+/* */
+/* Heavily optimised bootloader that is fast and small */
+/* (512 bytes, 115200bps */
+/* */
+/* Written almost entirely in C */
+/* Customisable timeout with accurate timeconstant */
+/* */
+/* */
+/* Copyright 2013-2020 by Bill Westfield. */
+/* Copyright 2010 by Peter Knight. */
+/* */
+/* This program is free software; you can redistribute it */
+/* and/or modify it under the terms of the GNU General */
+/* Public License as published by the Free Software */
+/* Foundation; either version 2 of the License, or */
+/* (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will */
+/* be useful, but WITHOUT ANY WARRANTY; without even the */
+/* implied warranty of MERCHANTABILITY or FITNESS FOR A */
+/* PARTICULAR PURPOSE. See the GNU General Public */
+/* License for more details. */
+/* */
+/* You should have received a copy of the GNU General */
+/* Public License along with this program; if not, write */
+/* to the Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/* */
+/* Licence can be viewed at */
+/* https://github.com/Optiboot/optiboot/blob/master/LICENSE */
+/* */
+/************************************************************/
+
+
+/************************************************************/
+/* */
+/* Optional defines: */
+/* */
+/************************************************************/
+/* */
+/* BIGBOOT: */
+/* Build a 1k bootloader, not 512 bytes. This turns on */
+/* extra functionality. */
+/* */
+/* BAUD_RATE: */
+/* Set bootloader baud rate. */
+/* */
+/* LED_START_FLASHES: */
+/* Number of LED flashes on bootup. */
+/* */
+/* LED_DATA_FLASH: */
+/* Flash LED when transferring data. For boards without */
+/* TX or RX LEDs, or for people who like blinky lights. */
+/* */
+/* TIMEOUT_MS: */
+/* Bootloader timeout period, in milliseconds. */
+/* 500,1000,2000,4000,8000 supported. */
+/* */
+/* UARTTX: */
+/* UART TX pin (B0, etc) for devices with more than */
+/* one hardware uart, or alternative pins */
+/* */
+/************************************************************/
+
+/************************************************************/
+/* Version Numbers! */
+/* */
+/* Optiboot now includes a Version number in the source */
+/* and object code, and returns this value via STK500 */
+/* */
+/* The iniital Mega0/Xtiny support is version 9. */
+/* This is very different from normal AVR because of */
+/* changed peripherals and unified address space. */
+/* */
+/* It would be good if versions implemented outside the */
+/* official repository used an out-of-seqeunce version */
+/* number (like 104.6 if based on based on 4.5) to */
+/* prevent collisions. The CUSTOM_VERSION=n option */
+/* adds n to the high version to facilitate this. */
+/* */
+/************************************************************/
+
+/************************************************************/
+/* Edit History: */
+/* */
+/* Aug 2019 */
+/* 9.0 Refactored for Mega0/Xtiny from optiboot.c */
+/* : */
+/* 4.1 WestfW: put version number in binary. */
+/************************************************************/
+
+#define OPTIBOOT_MAJVER 9
+#define OPTIBOOT_MINVER 0
+
+/*
+ * OPTIBOOT_CUSTOMVER should be defined (by the makefile) for custom edits
+ * of optiboot. That way you don't wind up with very different code that
+ * matches the version number of a "released" optiboot.
+ */
+
+#if !defined(OPTIBOOT_CUSTOMVER)
+# define OPTIBOOT_CUSTOMVER 0
+#endif
+
+unsigned const int __attribute__((section(".version"))) __attribute__((used))
+optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER;
+
+
+#include
+#include
+
+#if (!defined(__AVR_XMEGA__)) || (__AVR_ARCH__ != 103)
+#error CPU not supported by this version of Optiboot.
+#include // include a non-existent file to stop compilation
+#endif
+
+/*
+ * Fuses.
+ * This is an example of what they'd be like, but some should not
+ * necessarilly be under control of the bootloader. You'll need a
+ * a programmer that processes the .fuses section to actually get
+ * these programmed into the chip.
+ * The fuses actually REQUIRED by Optiboot are:
+ * BOOTEND=2, SYSCFG0=(CRC off, RSTPIN as appropriate)
+ * On some chips, the "reset" pin can be either RESET or GPIO.
+ * Other also have the UPDI option. If RESET is not enabled we won't be
+ * able to auto-reset. But if the UPDI pin is set to cause RESET, we
+ * won't be able to reprogram the chip without HV UPDI (which is uncommon.)
+ * The settings show will set chips (ie m4809) with RESET/GPIO to use RESET,
+ * and chips with RESET/GPIO/UPDI to leave it in UPDI mode - the bootloader
+ * can still be started by a power-on RESET.
+ */
+FUSES = {
+ .WDTCFG = 0, /* Watchdog Configuration */
+ .BODCFG = FUSE_BODCFG_DEFAULT, /* BOD Configuration */
+ .OSCCFG = FREQSEL_20MHZ_gc, /* 20MHz */
+#ifdef FUSE_TCD0CFG_DEFAULT
+ .TCD0CFG = FUSE_TCD0CFG_DEFAULT, /* TCD0 Configuration */
+#endif
+#ifdef RSTPIN
+ .SYSCFG0 = CRCSRC_NOCRC_gc | RSTPINCFG_RST_gc, /* RESET is enabled */
+#else
+# ifdef FUSE_RSTPINCFG_gm // group mask will be defined for triple-func pins
+ .SYSCFG0 = CRCSRC_NOCRC_gc | RSTPINCFG_UPDI_gc, /* RESET is not yet */
+# else
+ .SYSCFG0 = CRCSRC_NOCRC_gc, /* RESET is not yet */
+# endif
+#endif
+ .SYSCFG1 = 0x06, /* startup 32ms */
+ .APPEND = 0, /* Application Code Section End */
+ .BOOTEND = 2 /* Boot Section End */
+};
+
+
+/*
+ * optiboot uses several "address" variables that are sometimes byte pointers,
+ * sometimes word pointers. sometimes 16bit quantities, and sometimes built
+ * up from 8bit input characters. avr-gcc is not great at optimizing the
+ * assembly of larger words from bytes, but we can use the usual union to
+ * do this manually. Expanding it a little, we can also get rid of casts.
+ */
+typedef union {
+ uint8_t *bptr;
+ uint16_t *wptr;
+ uint16_t word;
+ uint8_t bytes[2];
+} addr16_t;
+
+
+/*
+ * pin_defs.h
+ * This contains most of the rather ugly defines that implement our
+ * ability to use UART=n and LED=D3, and some avr family bit name differences.
+ */
+#include "pin_defs_x.h"
+
+/*
+ * stk500.h contains the constant definitions for the stk500v1 comm protocol
+ */
+#include "stk500.h"
+
+#ifndef LED_START_FLASHES
+# define LED_START_FLASHES 0
+#endif
+
+/*
+ * The mega-0, tiny-0, and tiny-1 chips all reset to running on the
+ * internal oscillator, with a prescaler of 6. The internal oscillator
+ * is either 20MHz or 16MHz, depending on a fuse setting - we can read
+ * the fuse to figure our which.
+ * The BRG divisor is also fractional, permitting (afaik) any reasonable
+ * bit rate between about 1000bps and 1Mbps.
+ * This makes the BRG generation a bit different than for prior processors.
+ */
+/* set the UART baud rate defaults */
+#ifndef BAUD_RATE
+# define BAUD_RATE 115200L // Highest rate Avrdude win32 will support
+#endif
+#ifdef F_CPU
+# warning F_CPU is ignored for this chip (run from internal osc.)
+#endif
+#ifdef SINGLESPEED
+# warning SINGLESPEED ignored for this chip. (Fractional BRG)
+#endif
+#ifdef UART
+# warning UART is ignored for this chip (use UARTTX=PortPin instead)
+#endif
+
+#define BAUD_SETTING_16 (((16000000/6)*64) / (16L*BAUD_RATE))
+#define BAUD_ACTUAL_16 ((64L*(16000000/6)) / (16L*BAUD_SETTING))
+#define BAUD_SETTING_20 (((20000000/6)*64) / (16L*BAUD_RATE))
+#define BAUD_ACTUAL_20 ((64L*(20000000/6)) / (16L*BAUD_SETTING))
+
+#if BAUD_SETTING_16 < 64 // divisor must be > 1. Low bits are fraction.
+# error Unachievable baud rate (too fast) BAUD_RATE
+#endif
+
+#if BAUD_SETTING > 65635
+# error Unachievable baud rate (too slow) BAUD_RATE
+#endif // baud rate slow check
+
+/*
+ * Watchdog timeout translations from human readable to config vals
+ */
+#ifndef WDTTIME
+# define WDTPERIOD WDT_PERIOD_1KCLK_gc // 1 second
+#elif WDTTIME == 1
+# define WDTPERIOD WDT_PERIOD_1KCLK_gc // 1 second
+#elif WDTTIME == 2
+# define WDTPERIOD WDT_PERIOD_2KCLK_gc // 2 seconds
+#elif WDTTIME == 4
+# define WDTPERIOD WDT_PERIOD_4KCLK_gc // 4 seconds
+#elif WDTTIME == 8
+# define WDTPERIOD WDT_PERIOD_8KCLK_gc // 8 seconds
+#else
+#endif
+
+/*
+ * We can never load flash with more than 1 page at a time, so we can save
+ * some code space on parts with smaller pagesize by using a smaller int.
+ */
+#if MAPPED_PROGMEM_PAGE_SIZE > 255
+typedef uint16_t pagelen_t;
+# define GETLENGTH(len) len = getch()<<8; len |= getch()
+#else
+typedef uint8_t pagelen_t;
+# define GETLENGTH(len) (void) getch() /* skip high byte */; len = getch()
+#endif
+
+
+/* Function Prototypes
+ * The main() function is in init9, which removes the interrupt vector table
+ * we don't need. It is also 'OS_main', which means the compiler does not
+ * generate any entry or exit code itself (but unlike 'naked', it doesn't
+ * supress some compile-time options we want.)
+ */
+
+void pre_main(void) __attribute__ ((naked)) __attribute__ ((section (".init8")));
+int main(void) __attribute__ ((OS_main)) __attribute__ ((section (".init9"))) __attribute__((used));
+
+void __attribute__((noinline)) __attribute__((leaf)) putch(char);
+uint8_t __attribute__((noinline)) __attribute__((leaf)) getch(void) ;
+void __attribute__((noinline)) verifySpace();
+void __attribute__((noinline)) watchdogConfig(uint8_t x);
+
+static void getNch(uint8_t);
+
+#if LED_START_FLASHES > 0
+static inline void flash_led(uint8_t);
+#endif
+
+#define watchdogReset() __asm__ __volatile__ ("wdr\n")
+
+/*
+ * RAMSTART should be self-explanatory. It's bigger on parts with a
+ * lot of peripheral registers.
+ * Note that RAMSTART (for optiboot) need not be exactly at the start of RAM.
+ */
+#if !defined(RAMSTART) // newer versions of gcc avr-libc define RAMSTART
+#error RAMSTART not defined.
+#endif
+
+/* everything that needs to run VERY early */
+void pre_main (void) {
+ // Allow convenient way of calling do_spm function - jump table,
+ // so entry to this function will always be here, indepedent
+ // of compilation, features, etc
+ __asm__ __volatile__ (
+ " rjmp 1f\n"
+#ifndef APP_NOSPM
+ " rjmp do_nvmctrl\n"
+#else
+ " ret\n" // if do_spm isn't include, return without doing anything
+#endif
+ "1:\n"
+ );
+}
+
+/* main program starts here */
+int main (void) {
+ uint8_t ch;
+
+ /*
+ * Making these local and in registers prevents the need for initializing
+ * them, and also saves space because code no longer stores to memory.
+ * (initializing address keeps the compiler happy, but isn't really
+ * necessary, and uses 4 bytes of flash.)
+ */
+ register addr16_t address;
+ register pagelen_t length;
+
+ // This is the first code to run.
+ //
+ // Optiboot C code makes the following assumptions:
+ // No interrupts will execute
+ // SP points to RAMEND
+
+ __asm__ __volatile__ ("clr __zero_reg__"); // known-zero required by avr-libc
+#define RESET_EXTERNAL (RSTCTRL_EXTRF_bm|RSTCTRL_UPDIRF_bm|RSTCTRL_SWRF_bm)
+#ifndef FANCY_RESET_LOGIC
+ ch = RSTCTRL.RSTFR; // get reset cause
+#ifdef START_APP_ON_POR
+ /*
+ * If WDRF is set OR nothing except BORF and PORF are set, that's
+ * not bootloader entry condition so jump to app - this is for when
+ * UPDI pin is used as reset, so we go straight to app on start.
+ * 11/14: NASTY bug - we also need to check for no reset flags being
+ * set (ie, direct entry) and run bootloader in that case, otherwise
+ * bootloader won't run, among other things, after fresh bootloading!
+ */
+
+ if (ch && (ch & RSTCTRL_WDRF_bm ||
+ (!(ch & (~(RSTCTRL_BORF_bm | RSTCTRL_PORF_bm)))))) {
+#else
+ /*
+ * If WDRF is set OR nothing except BORF is set, that's not
+ * bootloader entry condition so jump to app - let's see if this
+ * works okay or not...
+ */
+ if (ch && (ch & RSTCTRL_WDRF_bm || (!(ch & (~RSTCTRL_BORF_bm))))) {
+#endif
+ /* Start the app.
+ * Dont bother trying to stuff it in r2, which requires heroic
+ * effort to fish out we'll put it in GPIOR0 where it won't get
+ * stomped on.
+ */
+ // __asm__ __volatile__ (" mov r2, %0\n" :: "r" (ch));
+ RSTCTRL.RSTFR = ch; //clear the reset causes before jumping to app...
+ GPIOR0 = ch; // but, stash the reset cause in GPIOR0 for use by app...
+ watchdogConfig(WDT_PERIOD_OFF_gc);
+ __asm__ __volatile__(
+ " jmp app\n"
+ );
+ }
+#else
+ /*
+ * Protect as much Reset Cause as possible for application
+ * and still skip bootloader if not necessary
+ */
+ ch = RSTCTRL.RSTFR;
+ if (ch != 0) {
+ /*
+ * We want to run the bootloader when an external reset has occurred.
+ * On these mega0/XTiny chips, there are three types of ext reset:
+ * reset pin (may not exist), UPDI reset, and SW-request reset.
+ * One of these reset causes, together with watchdog reset, should
+ * mean that Optiboot timed out, and it's time to run the app.
+ * Other reset causes (notably poweron) should run the app directly.
+ * If a user app wants to utilize and detect watchdog resets, it
+ * must make sure that the other reset causes are cleared.
+ */
+ if (ch & RSTCTRL_WDRF_bm) {
+ if (ch & RESET_EXTERNAL) {
+ /*
+ * Clear WDRF because it was most probably set by wdr in
+ * bootloader. It's also needed to avoid loop by broken
+ * application which could prevent entering bootloader.
+ */
+ RSTCTRL.RSTFR = RSTCTRL_WDRF_bm;
+ }
+ }
+ if (!(ch & RESET_EXTERNAL)) {
+ /*
+ * save the reset flags in the designated register.
+ * This can be saved in a main program by putting code in
+ * .init0 (which executes before normal c init code) to save R2
+ * to a global variable.
+ */
+ __asm__ __volatile__(" mov r2, %0\n" :: "r"(ch));
+
+ // switch off watchdog
+ watchdogConfig(WDT_PERIOD_OFF_gc);
+ __asm__ __volatile__(
+ " jmp app\n"
+ );
+ }
+ }
+#endif // Fancy reset cause stuff
+
+ watchdogReset();
+// _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, 0); // full speed clock
+
+ MYUART_TXPORT.DIR |= MYUART_TXPIN; // set TX pin to output
+ MYUART_TXPORT.OUT |= MYUART_TXPIN; // and "1" as per datasheet
+#if defined (MYUART_PMUX_VAL)
+ MYPMUX_REG = MYUART_PMUX_VAL; // alternate pinout to use
+#endif
+ if ((FUSE_OSCCFG & FUSE_FREQSEL_gm) == FREQSEL_16MHZ_gc) {
+ MYUART.BAUD = BAUD_SETTING_16;
+ } else {
+ MYUART.BAUD = BAUD_SETTING_20;
+ }
+ MYUART.DBGCTRL = 1; // run during debug
+ MYUART.CTRLC = (USART_CHSIZE_gm & USART_CHSIZE_8BIT_gc); // Async, Parity Disabled, 1 StopBit
+ MYUART.CTRLA = 0; // Interrupts: all off
+ MYUART.CTRLB = USART_RXEN_bm | USART_TXEN_bm;
+
+ // Set up watchdog to trigger after a bit
+ // (nominally:, 1s for autoreset, longer for manual)
+ watchdogConfig(WDTPERIOD);
+
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
+ /* Set LED pin as output */
+ LED_PORT.DIR |= LED;
+#endif
+
+#if LED_START_FLASHES > 0
+ /* Flash onboard LED to signal entering of bootloader */
+# ifdef LED_INVERT
+ flash_led(LED_START_FLASHES * 2+1);
+# else
+ flash_led(LED_START_FLASHES * 2);
+# endif
+#else
+#if defined(LED_START_ON)
+# ifndef LED_INVERT
+ /* Turn on LED to indicate starting bootloader (less code!) */
+ LED_PORT.OUT |= LED;
+# endif
+#endif
+#endif
+
+ /* Forever loop: exits by causing WDT reset */
+ for (;;) {
+ /* get character from UART */
+ ch = getch();
+
+ if(ch == STK_GET_PARAMETER) {
+ unsigned char which = getch();
+ verifySpace();
+ /*
+ * Send optiboot version as "SW version"
+ * Note that the references to memory are optimized away.
+ */
+ if (which == STK_SW_MINOR) {
+ putch(optiboot_version & 0xFF);
+ } else if (which == STK_SW_MAJOR) {
+ putch(optiboot_version >> 8);
+ } else {
+ /*
+ * GET PARAMETER returns a generic 0x03 reply for
+ * other parameters - enough to keep Avrdude happy
+ */
+ putch(0x03);
+ }
+ }
+ else if(ch == STK_SET_DEVICE) {
+ // SET DEVICE is ignored
+ getNch(20);
+ }
+ else if(ch == STK_SET_DEVICE_EXT) {
+ // SET DEVICE EXT is ignored
+ getNch(5);
+ }
+ else if(ch == STK_LOAD_ADDRESS) {
+ // LOAD ADDRESS
+ address.bytes[0] = getch();
+ address.bytes[1] = getch();
+ // ToDo: will there be mega-0 chips with >128k of RAM?
+/* UPDI chips apparently have byte-addressable FLASH ?
+ address.word *= 2; // Convert from word address to byte address
+*/
+ verifySpace();
+ }
+ else if(ch == STK_UNIVERSAL) {
+#ifndef RAMPZ
+ // UNIVERSAL command is ignored
+ getNch(4);
+ putch(0x00);
+#endif
+ }
+ /* Write memory, length is big endian and is in bytes */
+ else if(ch == STK_PROG_PAGE) {
+ // PROGRAM PAGE - any kind of page!
+ uint8_t desttype;
+
+ GETLENGTH(length);
+ desttype = getch();
+
+ if (desttype == 'F') {
+ address.word += MAPPED_PROGMEM_START;
+ } else {
+ address.word += MAPPED_EEPROM_START;
+ }
+ // TODO: user row?
+
+ do {
+ *(address.bptr++) = getch();
+ } while (--length);
+
+ // Read command terminator, start reply
+ verifySpace();
+ /*
+ * Actually Write the buffer to flash (and wait for it to finish.)
+ */
+ _PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);
+ while (NVMCTRL.STATUS & (NVMCTRL_FBUSY_bm|NVMCTRL_EEBUSY_bm))
+ ; // wait for flash and EEPROM not busy, just in case.
+ }
+ /* Read memory block mode, length is big endian. */
+ else if(ch == STK_READ_PAGE) {
+ uint8_t desttype;
+ GETLENGTH(length);
+
+ desttype = getch();
+
+ verifySpace();
+ if (desttype == 'F') {
+ address.word += MAPPED_PROGMEM_START;
+ } else {
+ address.word += MAPPED_EEPROM_START;
+ }
+ // TODO: user row?
+
+ do {
+ putch(*(address.bptr++));
+ } while (--length);
+ }
+
+ /* Get device signature bytes */
+ else if(ch == STK_READ_SIGN) {
+ // READ SIGN - return actual device signature from SIGROW
+ // This enables the same binary to be ued on multiple chips.
+ verifySpace();
+ putch(SIGROW_DEVICEID0);
+ putch(SIGROW_DEVICEID1);
+ putch(SIGROW_DEVICEID2);
+ }
+ else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+ // Adaboot no-wait mod
+ watchdogConfig(WDT_PERIOD_8CLK_gc);
+ verifySpace();
+ }
+ else {
+ // This covers the response to commands like STK_ENTER_PROGMODE
+ verifySpace();
+ }
+ putch(STK_OK);
+ }
+}
+
+void putch (char ch) {
+ while (0 == (MYUART.STATUS & USART_DREIF_bm))
+ ;
+ MYUART.TXDATAL = ch;
+}
+
+uint8_t getch (void) {
+ uint8_t ch, flags;
+ while (!(MYUART.STATUS & USART_RXCIF_bm))
+ ;
+ flags = MYUART.RXDATAH;
+ ch = MYUART.RXDATAL;
+ if ((flags & USART_FERR_bm) == 0)
+ watchdogReset();
+#ifdef LED_DATA_FLASH
+ LED_PORT.IN |= LED;
+#endif
+
+ return ch;
+}
+
+void getNch (uint8_t count) {
+ do getch(); while (--count);
+ verifySpace();
+}
+
+void verifySpace () {
+ if (getch() != CRC_EOP) {
+ watchdogConfig(WDT_PERIOD_8CLK_gc); // shorten WD timeout
+ while (1) // and busy-loop so that WD causes
+ ; // a reset and app start.
+ }
+ putch(STK_INSYNC);
+}
+
+#if LED_START_FLASHES > 0
+void flash_led (uint8_t count) {
+ uint16_t delay; // at 20MHz/6, a 16bit delay counter is enough
+ while (count--) {
+ LED_PORT.IN |= LED;
+ // delay assuming 20Mhz OSC. It's only to "look about right", anyway.
+ for (delay = ((20E6/6)/150); delay; delay--) {
+ watchdogReset();
+ if (MYUART.STATUS & USART_RXCIF_bm)
+ return;
+ }
+ }
+ watchdogReset(); // for breakpointing
+}
+#endif
+
+
+/*
+ * Change the watchdog configuration.
+ * Could be a new timeout, could be off...
+ */
+void watchdogConfig (uint8_t x) {
+ while(WDT.STATUS & WDT_SYNCBUSY_bm)
+ ; // Busy wait for sycnhronization is required!
+ _PROTECTED_WRITE(WDT.CTRLA, x);
+}
+
+
+#ifndef APP_NOSPM
+
+/*
+ * Separate function for doing nvmctrl stuff.
+ * It's needed for application to do manipulate flash, since only the
+ * bootloader can write or erase flash, or write to the flash alias areas.
+ * Note that this is significantly different in the details than the
+ * do_spm() function provided on older AVRs. Same "vector", though.
+ *
+ * How it works:
+ * - if the "command" is legal, write it to NVMCTRL.CTRLA
+ * - if the command is not legal, store data to *address
+ * - wait for NVM to complete
+ *
+ * For example, to write a flash page:
+ *
+ */
+static void do_nvmctrl(uint16_t address, uint8_t command, uint8_t data) __attribute__ ((used));
+static void do_nvmctrl (uint16_t address, uint8_t command, uint8_t data) {
+ if (command <= NVMCTRL_CMD_gm) {
+ _PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, command);
+ while (NVMCTRL.STATUS & (NVMCTRL_FBUSY_bm|NVMCTRL_EEBUSY_bm))
+ ; // wait for flash and EEPROM not busy, just in case.
+ } else {
+ *(uint8_t *)address = data;
+ }
+}
+#endif
+
+
+#ifdef BIGBOOT
+/*
+ * Optiboot is designed to fit in 512 bytes, with a minimum feature set.
+ * Some chips have a minimum bootloader size of 1024 bytes, and sometimes
+ * it is desirable to add extra features even though 512bytes is exceedded.
+ * In that case, the BIGBOOT can be used.
+ * Our extra features so far don't come close to filling 1k, so we can
+ * add extra "frivolous" data to the image. In particular, we can add
+ * information about how Optiboot was built (which options were selected,
+ * what version, all in human-readable form (and extractable from the
+ * binary with avr-strings.)
+ *
+ * This can always be removed or trimmed if more actual program space
+ * is needed in the future. Currently the data occupies about 160 bytes,
+ */
+#define xstr(s) str(s)
+#define str(s) #s
+#define OPTFLASHSECT __attribute__((section(".fini8")))
+#define OPT2FLASH(o) OPTFLASHSECT const char f##o[] = #o "=" xstr(o)
+
+
+#ifdef LED_START_FLASHES
+OPT2FLASH(LED_START_FLASHES);
+#endif
+#ifdef LED_DATA_FLASH
+OPT2FLASH(LED_DATA_FLASH);
+#endif
+#ifdef LED_START_ON
+OPT2FLASH(LED_START_ON);
+#endif
+#ifdef LED_NAME
+OPTFLASHSECT const char f_LED[] = "LED=" LED_NAME;
+#endif
+
+#ifdef SUPPORT_EEPROM
+OPT2FLASH(SUPPORT_EEPROM);
+#endif
+
+#ifdef BAUD_RATE
+OPT2FLASH(BAUD_RATE);
+#endif
+#ifdef UARTTX
+OPTFLASHSECT const char f_uart[] = "UARTTX=" UART_NAME;
+#endif
+
+OPTFLASHSECT const char f_date[] = "Built:" __DATE__ ":" __TIME__;
+#ifdef BIGBOOT
+OPT2FLASH(BIGBOOT);
+#endif
+OPTFLASHSECT const char f_device[] = "Device=" xstr(__AVR_DEVICE_NAME__);
+#ifdef OPTIBOOT_CUSTOMVER
+# if OPTIBOOT_CUSTOMVER != 0
+OPT2FLASH(OPTIBOOT_CUSTOMVER);
+# endif
+#endif
+OPTFLASHSECT const char f_version[] = "Version=" xstr(OPTIBOOT_MAJVER) "." xstr(OPTIBOOT_MINVER);
+
+#endif
+
+// Dummy application that will loop back into the bootloader if not overwritten
+// This gives the bootloader somewhere to jump, and by referencing otherwise
+// unused variables/functions in the bootloader, it prevents them from being
+// omitted by the linker, with fewer mysterious link options.
+void __attribute__((section( ".application")))
+ __attribute__((naked)) app();
+void app()
+{
+ uint8_t ch;
+
+ ch = RSTCTRL.RSTFR;
+ RSTCTRL.RSTFR = ch; // reset causes
+ *(volatile uint16_t *)(&optiboot_version); // reference the version
+ do_nvmctrl(0, NVMCTRL_CMD_PAGEBUFCLR_gc, 0); // reference this function!
+ __asm__ __volatile__ ("jmp 0"); // similar to running off end of memory
+// _PROTECTED_WRITE(RSTCTRL.SWRR, 1); // cause new reset
+}
diff --git a/megaavr/bootloaders/optiboot/parse_options.mk b/megaavr/bootloaders/optiboot/parse_options.mk
new file mode 100755
index 0000000..3905200
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/parse_options.mk
@@ -0,0 +1,142 @@
+# Make command-line Options for Optiboot, Optiboot-Mega0
+# Permit commands like "make atmega4809 LED_START_FLASHES=10" to pass the
+# appropriate parameters ("-DLED_START_FLASHES=10") to gcc
+#
+
+ifdef PRODUCTION
+ifneq ($(PRODUCTION),0)
+VERSION_CMD = -DPRODUCTION=1
+endif
+dummy = FORCE
+endif
+
+
+# Build Options
+
+ifdef CUSTOM_VERSION
+ifneq ($(CUSTOM_VERSION), 0)
+VERSION_CMD = -DOPTIBOOT_CUSTOMVER=$(CUSTOM_VERSION)
+else
+VERSION_CMD = -DPRODUCTION=1
+endif
+dummy = FORCE
+endif
+
+# BIGBOOT: Include extra features, up to 1K.
+ifdef BIGBOOT
+ifneq ($(BIGBOOT), 0)
+BIGBOOT_CMD = -DBIGBOOT=1
+dummy = FORCE
+endif
+endif
+
+ifdef SUPPORT_EEPROM
+ifneq ($(SUPPORT_EEPROM), 0)
+SUPPORT_EEPROM_CMD = -DSUPPORT_EEPROM
+dummy = FORCE
+endif
+endif
+
+ifdef NO_APP_SPM
+ifneq ($(NO_APP_SPM),0)
+APPSPM_CMD = -DAPP_NOSPM=1
+endif
+endif
+
+
+# LED options
+
+ifdef LED
+LED_CMD = -DLED=$(LED)
+dummy = FORCE
+endif
+
+ifdef LED_START_FLASHES
+LED_START_FLASHES_CMD = -DLED_START_FLASHES=$(LED_START_FLASHES)
+dummy = FORCE
+else
+LED_START_FLASHES_CMD = -DLED_START_FLASHES=3
+endif
+
+ifdef LED_DATA_FLASH
+ifneq ($(LED_DATA_FLASH), 0)
+LED_DATA_FLASH_CMD = -DLED_DATA_FLASH=1
+dummy = FORCE
+endif
+endif
+
+ifdef LED_START_ON
+ifneq ($(LED_START_ON), 0)
+LED_START_ON_CMD = -DLED_START_ON=1
+endif
+dummy = FORCE
+endif
+
+ifdef LED_INVERT
+ifneq ($(LED_INVERT), 0)
+LEDINV_CMD = -DLED_INVERT=1
+endif
+dummy = FORCE
+endif
+
+
+# UART options
+
+ifdef BAUD_RATE
+BAUD_RATE_CMD = -DBAUD_RATE=$(BAUD_RATE)
+dummy = FORCE
+else
+BAUD_RATE_CMD = -DBAUD_RATE=115200
+endif
+
+ifdef SOFT_UART
+ifneq ($(SOFT_UART), 0)
+SOFT_UART_CMD = -DSOFT_UART=1
+dummy = FORCE
+endif
+endif
+
+ifdef SINGLESPEED
+ifneq ($(SINGLESPEED), 0)
+SS_CMD = -DSINGLESPEED=1
+endif
+endif
+
+
+#CPU Options
+
+ifdef TIMEOUT
+TIMEOUT_CMD = -DWDTTIME=$(TIMEOUT)
+dummy = FORCE
+endif
+
+ifdef RESETPIN
+RESETPIN_CMD = -DRSTPIN=$(RESETPIN)
+dummy = FORCE
+endif
+
+ifdef AVR_FREQ
+FCPU_CMD = -DF_CPU=$(AVR_FREQ)
+dummy = FORCE
+endif
+
+
+
+LED_OPTIONS = $(LED_START_FLASHES_CMD) $(LED_DATA_FLASH_CMD) $(LED_CMD) $(LED_START_ON_CMD) $(LEDINV_CMD)
+CPU_OPTIONS = $(RESETPIN_CMD) $(TIMEOUT_CMD) $(FCPU_CMD)
+COMMON_OPTIONS = $(BIGBOOT_CMD) $(APPSPM_CMD) $(VERSION_CMD)
+COMMON_OPTIONS += $(SUPPORT_EEPROM_CMD)
+
+#UART is handled separately and only passed for devices with more than one.
+ifdef UART
+UART_CMD = -DUART=$(UART)
+endif
+ifdef UARTTX
+UART_CMD = -DUARTTX=$(UARTTX)
+endif
+
+UART_OPTIONS = $(UART_CMD) $(BAUD_RATE_CMD) $(SOFT_UART_CMD) $(SS_CMD)
+
+ifneq ($(SKIP_BOOTLOADER_ON_POR),0)
+POR = -DSTART_APP_ON_POR
+endif
diff --git a/megaavr/bootloaders/optiboot/pin_defs_x.h b/megaavr/bootloaders/optiboot/pin_defs_x.h
new file mode 100755
index 0000000..a51c0f0
--- /dev/null
+++ b/megaavr/bootloaders/optiboot/pin_defs_x.h
@@ -0,0 +1,815 @@
+/*
+ * pin_defs.h
+ * optiboot helper defining the default pin assignments (LED, SOFT_UART)
+ * for the various chips that are supported. This also has some ugly macros
+ * for selecting among various UARTs and LED possibilities using command-line
+ * defines like "UART=2 LED=B5"
+ *
+ * Copyright 2013-2015 by Bill Westfield.
+ * Copyright 2010 by Peter Knight.
+ * This software is licensed under version 2 of the Gnu Public Licence.
+ * See optiboot.c for details.
+ */
+
+
+/*
+ * ------------------------------------------------------------------------
+ * A bunch of macros to enable the LED to be specifed as "B5" for bit 5
+ * of port B, and similar.
+ * We define symbols for all the legal combination of port/bit on a chip,
+ * and do pre-processor tests to see if there's a match. This ends up
+ * being very verbose, but it is pretty easy to generate semi-automatically.
+ * (We wouldn't need this if the preprocessor could do string compares.)
+ */
+
+// Symbols for each PortA bit.
+#define A0 0x100
+#define A1 0x101
+#define A2 0x102
+#define A3 0x103
+#define A4 0x104
+#define A5 0x105
+#define A6 0x106
+#define A7 0x107
+// If there is no PORTA on this chip, don't allow these to be used
+// (and indicate the error by redefining LED)
+#if !defined(PORTA)
+#if LED >= A0 && LED <= A7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define B0 0x200
+#define B1 0x201
+#define B2 0x202
+#define B3 0x203
+#define B4 0x204
+#define B5 0x205
+#define B6 0x206
+#define B7 0x207
+#if !defined(PORTB)
+#if LED >= B0 && LED <= B7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define C0 0x300
+#define C1 0x301
+#define C2 0x302
+#define C3 0x303
+#define C4 0x304
+#define C5 0x305
+#define C6 0x306
+#define C7 0x307
+#if !(defined(PORTC))
+#if LED >= C0 && LED <= C7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define D0 0x400
+#define D1 0x401
+#define D2 0x402
+#define D3 0x403
+#define D4 0x404
+#define D5 0x405
+#define D6 0x406
+#define D7 0x407
+#if !(defined(PORTD))
+#if LED >= D0 && LED <= D7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define E0 0x500
+#define E1 0x501
+#define E2 0x502
+#define E3 0x503
+#define E4 0x504
+#define E5 0x505
+#define E6 0x506
+#define E7 0x507
+#if !(defined(PORTE))
+#if LED >= E0 && LED <= E7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define F0 0x600
+#define F1 0x601
+#define F2 0x602
+#define F3 0x603
+#define F4 0x604
+#define F5 0x605
+#define F6 0x606
+#define F7 0x607
+#if !(defined(PORTF))
+#if LED >= F0 && LED <= F7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define G0 0x700
+#define G1 0x701
+#define G2 0x702
+#define G3 0x703
+#define G4 0x704
+#define G5 0x705
+#define G6 0x706
+#define G7 0x707
+#if !defined(PORTG)
+#if LED >= G0 && LED <= G7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define H0 0x800
+#define H1 0x801
+#define H2 0x802
+#define H3 0x803
+#define H4 0x804
+#define H5 0x805
+#define H6 0x806
+#define H7 0x807
+#if !(defined(PORTH))
+#if LED >= H0 && LED <= H7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define J0 0xA00
+#define J1 0xA01
+#define J2 0xA02
+#define J3 0xA03
+#define J4 0xA04
+#define J5 0xA05
+#define J6 0xA06
+#define J7 0xA07
+#if !(defined(PORTJ))
+#if LED >= J0 && LED <= J7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define K0 0xB00
+#define K1 0xB01
+#define K2 0xB02
+#define K3 0xB03
+#define K4 0xB04
+#define K5 0xB05
+#define K6 0xB06
+#define K7 0xB07
+#if !(defined(PORTK))
+#if LED >= K0 && LED <= K7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+#define L0 0xC00
+#define L1 0xC01
+#define L2 0xC02
+#define L3 0xC03
+#define L4 0xC04
+#define L5 0xC05
+#define L6 0xC06
+#define L7 0xC07
+#if !(defined(PORTL))
+#if LED >= L0 && LED <= L7
+#undef LED
+#define LED -1
+#endif
+#endif
+
+
+/*
+ * A statement like "#if LED == B0" will evaluation (in the preprocessor)
+ * to #if C0 == B0, and then to #if 0x301 == 0x201
+ */
+#if LED == B0
+#define LED_NAME "B0"
+#undef LED
+#define LED_PORT VPORTB
+#define LED (1<
#include
+
#ifdef __cplusplus
extern "C"{
#endif
-/* Analog reference options */
-
-/* Change in mega4809: two places to define analog reference
- - VREF peripheral defines internal reference
- - analog peripherals define internal/Vdd/external
-*/
-
- // internal from VREF
-
- /* Values shifted to avoid clashing with ADC REFSEL defines
- Will shift back in analog_reference function
- */
-#define INTERNAL0V55 (VREF_ADC0REFSEL_0V55_gc >> VREF_ADC0REFSEL_gp)
-#define INTERNAL1V1 (VREF_ADC0REFSEL_1V1_gc >> VREF_ADC0REFSEL_gp)
-#define INTERNAL2V5 (VREF_ADC0REFSEL_2V5_gc >> VREF_ADC0REFSEL_gp)
-#define INTERNAL4V3 (VREF_ADC0REFSEL_4V34_gc >> VREF_ADC0REFSEL_gp)
-#define INTERNAL1V5 (VREF_ADC0REFSEL_1V5_gc >> VREF_ADC0REFSEL_gp)
-
-#define DEFAULT INTERNAL0V55
-#define INTERNAL ADC_REFSEL_INTREF_gc
-#define VDD ADC_REFSEL_VDDREF_gc
-#define EXTERNAL ADC_REFSEL_VREFA_gc
+// Analog reference options
+#define INTERNAL0V55 (VREF_ADC0REFSEL_0V55_gc >> VREF_ADC0REFSEL_gp)
+#define INTERNAL1V1 (VREF_ADC0REFSEL_1V1_gc >> VREF_ADC0REFSEL_gp)
+#define INTERNAL1V5 (VREF_ADC0REFSEL_1V5_gc >> VREF_ADC0REFSEL_gp)
+#define INTERNAL2V5 (VREF_ADC0REFSEL_2V5_gc >> VREF_ADC0REFSEL_gp)
+#define INTERNAL4V3 (VREF_ADC0REFSEL_4V34_gc >> VREF_ADC0REFSEL_gp)
+#define INTERNAL4V34 INTERNAL4V3
+#define DEFAULT ADC_REFSEL_VDDREF_gc
+#define INTERNAL ADC_REFSEL_INTREF_gc
+#define VDD ADC_REFSEL_VDDREF_gc
+#define EXTERNAL ADC_REFSEL_VREFA_gc
+#define ADC_TEMPERATURE ADC_MUXPOS_TEMPSENSE_gc
+#define VCC_5V0 2
+#define VCC_3V3 1
+#define VCC_1V8 0
-#define VCC_5V0 2
-#define VCC_3V3 1
-#define VCC_1V8 0
-
-#define interrupts() sei()
-#define noInterrupts() cli()
+#define interrupts() sei()
+#define noInterrupts() cli()
// avr-libc defines _NOP() since 1.6.2
#ifndef _NOP
-#define _NOP() do { __asm__ volatile ("nop"); } while (0)
+ #define _NOP() do { __asm__ volatile ("nop"); } while (0)
#endif
-/* Allows performing a correction on the CPU value using the signature row
- values indicating oscillator error provided from the device manufacturer */
+/* Allows performing a correction on the CPU value using the signature row
+ values indicating oscillator error provided from the device manufacturer */
#define PERFORM_SIGROW_CORRECTION_F_CPU 0
/* Variable containing corrected F_CPU value, after checks for safe operating
- frequency vs supply voltage, oscillator fuse setting and MCLK divider.
- Also includes the correction from signature row values if above #define
- PERFORM_SIGROW_CORRECTION_F_CPU = 1 */
+ frequency vs supply voltage, oscillator fuse setting and MCLK divider.
+ Also includes the correction from signature row values if above #define
+ PERFORM_SIGROW_CORRECTION_F_CPU = 1 */
extern uint32_t F_CPU_CORRECTED;
uint16_t clockCyclesPerMicrosecondComp(uint32_t clk);
@@ -83,10 +73,10 @@ unsigned long microsecondsToClockCycles(unsigned long microseconds);
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
-extern const uint8_t PROGMEM digital_pin_to_port[];
-extern const uint8_t PROGMEM digital_pin_to_bit_mask[];
-extern const uint8_t PROGMEM digital_pin_to_bit_position[];
-extern const uint8_t PROGMEM digital_pin_to_timer[];
+extern const uint8_t digital_pin_to_port[];
+extern const uint8_t digital_pin_to_bit_mask[];
+extern const uint8_t digital_pin_to_bit_position[];
+extern const uint8_t digital_pin_to_timer[];
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
@@ -113,19 +103,18 @@ extern const uint8_t PROGMEM digital_pin_to_timer[];
#define TIMERB3 5
void setup_timers();
-bool isDoubleBondedActive(uint8_t pin);
-#define digitalPinToPort(pin) ( (pin < NUM_TOTAL_PINS) ? pgm_read_byte(digital_pin_to_port + pin) : NOT_A_PIN )
-#define digitalPinToBitPosition(pin) ( (pin < NUM_TOTAL_PINS) ? pgm_read_byte(digital_pin_to_bit_position + pin) : NOT_A_PIN )
-#define analogPinToBitPosition(pin) ( (pin < NUM_ANALOG_INPUTS) ? pgm_read_byte(digital_pin_to_bit_position + pin + ANALOG_INPUT_OFFSET) : NOT_A_PIN )
-#define digitalPinToBitMask(pin) ( (pin < NUM_TOTAL_PINS) ? pgm_read_byte(digital_pin_to_bit_mask + pin) : NOT_A_PIN )
-#define analogPinToBitMask(pin) ( (pin < NUM_ANALOG_INPUTS) ? pgm_read_byte(digital_pin_to_bit_mask + pin + ANALOG_INPUT_OFFSET) : NOT_A_PIN )
-#define digitalPinToTimer(pin) ( (pin < NUM_TOTAL_PINS) ? pgm_read_byte(digital_pin_to_timer + pin) : NOT_ON_TIMER )
+#define digitalPinToPort(pin) ( (pin < NUM_TOTAL_PINS) ? digital_pin_to_port[pin] : NOT_A_PIN )
+#define digitalPinToBitPosition(pin) ( (pin < NUM_TOTAL_PINS) ? digital_pin_to_bit_position[pin] : NOT_A_PIN )
+#define digitalPinToBitMask(pin) ( (pin < NUM_TOTAL_PINS) ? digital_pin_to_bit_mask[pin] : NOT_A_PIN )
+#define digitalPinToTimer(pin) ( (pin < NUM_TOTAL_PINS) ? digital_pin_to_timer[pin] : NOT_ON_TIMER )
+#define analogPinToBitPosition(pin) ( (digitalOrAnalogPinToDigital(pin) != NOT_A_PIN) ? digital_pin_to_bit_position[digitalOrAnalogPinToDigital(pin)] : NOT_A_PIN )
+#define analogPinToBitMask(pin) ( (digitalOrAnalogPinToDigital(pin) != NOT_A_PIN) ? digital_pin_to_bit_mask[digitalOrAnalogPinToDigital(pin)] : NOT_A_PIN )
#define portToPortStruct(port) ( (port < NUM_TOTAL_PORTS) ? ((PORT_t *)&PORTA + port) : NULL)
#define digitalPinToPortStruct(pin) ( (pin < NUM_TOTAL_PINS) ? ((PORT_t *)&PORTA + digitalPinToPort(pin)) : NULL)
#define getPINnCTRLregister(port, bit_pos) ( ((port != NULL) && (bit_pos < NOT_A_PIN)) ? ((volatile uint8_t *)&(port->PIN0CTRL) + bit_pos) : NULL )
-#define digitalPinToInterrupt(p) (P)
+#define digitalPinToInterrupt(P) (P)
#define portOutputRegister(P) ( (volatile uint8_t *)( &portToPortStruct(P)->OUT ) )
#define portInputRegister(P) ( (volatile uint8_t *)( &portToPortStruct(P)->IN ) )
@@ -147,6 +136,207 @@ bool isDoubleBondedActive(uint8_t pin);
#error "Targets with both UART0 and CDC serial not supported"
#endif
+enum timers_prescaler_t : uint8_t {
+ TCA_DIV1 = 0x00,
+ TCA_DIV2 = 0x02,
+ TCA_DIV4 = 0x04,
+ TCA_DIV8 = 0x06,
+ TCA_DIV16 = 0x08,
+ TCA_DIV64 = 0x0A,
+ TCA_DIV256 = 0x0C,
+ TCA_DIV1024 = 0x0E,
+ TCB_DIV1 = 0x00,
+ TCB_DIV2 = 0x20,
+ TCB_CLKTCA = 0x40,
+};
+
+void pwmWrite(pwm_timers_t pwmTimer, uint16_t value, timers_route_t timerRoute = ROUTE_UNTOUCHED);
+void pwmPrescaler(pwm_timers_t pwmTimer, timers_prescaler_t prescaler);
+void pwmSetResolution(pwm_timers_t pwmTimer, uint8_t maxValue);
+
+// These are used as the second to N argument to pinConfigure(pin, ...)
+// Directives are handled in the order they show up on this list, by pin function:
+// PIN_DIR Direction
+// PIN_OUT Output value
+// PIN_ISC Enable and interrupt mode. If interrupts are turned on w/out the ISR, it will trigger dirty reset.
+// PIN_PULLUP Pullups
+// PIN_INLVL Input levels (MVIO parts only - everything else is schmitt trigger only, except on I2C pins acting as I2C with SMBus levels enabled. )
+// PIN_INVERT Invert pin
+//
+// Systematically named constants can be made by combining those names with the postfixes here
+// except for PIN_ISC which is not a non-binary option. Valid values are listed below.
+// _SET, _CLR, and _TGL can be used as a postfix on all binary options.
+// _TOGGLE and _TGL are interchangeable as well.
+// Additional names are defined where they might be easier to remember.
+typedef enum : uint16_t
+{
+ // OUTPUT
+ PIN_DIR_SET = 0x0001,
+ PIN_DIRSET = 0x0001,
+ PIN_DIR_OUTPUT = 0x0001,
+ PIN_DIR_OUT = 0x0001,
+ // INPUT
+ PIN_DIR_CLR = 0x0002,
+ PIN_DIRCLR = 0x0002,
+ PIN_DIR_INPUT = 0x0002,
+ PIN_DIR_IN = 0x0002,
+ // TOGGLE INPUT/OUTPUT
+ PIN_DIR_TGL = 0x0003,
+ PIN_DIRTGL = 0x0003,
+ PIN_DIR_TOGGLE = 0x0003,
+ // HIGH
+ PIN_OUT_SET = 0x0004,
+ PIN_OUTSET = 0x0004,
+ PIN_OUT_HIGH = 0x0004,
+ // LOW
+ PIN_OUT_CLR = 0x0008,
+ PIN_OUTCLR = 0x0008,
+ PIN_OUT_LOW = 0x0008,
+// CHANGE/TOGGLE
+ PIN_OUT_TGL = 0x000C,
+ PIN_OUTTGL = 0x000C,
+ PIN_OUT_TOGGLE = 0x000C,
+//Interrupt disabled but input buffer enabled
+ PIN_ISC_ENABLE = 0x0080,
+ PIN_INPUT_ENABLE = 0x0080,
+ // Interrupt on change
+ PIN_ISC_CHANGE = 0x0090,
+ PIN_INT_CHANGE = 0x0090,
+// Interrupt on rising edge
+ PIN_ISC_RISE = 0x00A0,
+ PIN_INT_RISE = 0x00A0,
+// Interrupt on falling edge
+ PIN_ISC_FALL = 0x00B0,
+ PIN_INT_FALL = 0x00B0,
+// Interrupt and input buffer disabled
+ PIN_ISC_DISABLE = 0x00C0,
+ PIN_INPUT_DISABLE = 0x00C0,
+// Interrupt enabled with sense on low level
+ PIN_ISC_LEVEL = 0x00D0,
+ PIN_INT_LEVEL = 0x00D0,
+// PULLUP ON
+ PIN_PULLUP_ON = 0x0100,
+ PIN_PULLUP = 0x0100,
+ PIN_PULLUP_SET = 0x0100,
+// PULLUP OFF
+ PIN_PULLUP_OFF = 0x0200,
+ PIN_PULLUP_CLR = 0x0200,
+ PIN_NOPULLUP = 0x0200,
+// PULLUP TOGGLE
+ PIN_PULLUP_TGL = 0x0300,
+ PIN_PULLUP_TOGGLE = 0x0300,
+// PIN INVERT ON
+ PIN_INVERT_ON = 0x4000,
+ PIN_INVERT_SET = 0x4000,
+// PIN INVERT OFF
+ PIN_INVERT_OFF = 0x8000,
+ PIN_INVERT_CLR = 0x8000,
+// PIN_INVERT_TOGGLE
+ PIN_INVERT_TGL = 0xC000,
+ PIN_INVERT_TOGGLE = 0xC000,
+} pin_configure_t;
+
+/**
+ * @brief Helper functions to catch the last argument in the pincfg recursion loop
+ *
+ * @param mode Mode parameter
+ * @return pin_configure_t
+ */
+
+inline pin_configure_t pincfg(const pin_configure_t mode)
+{
+ return mode;
+}
+
+/**
+ * @brief Helper functions to catch the nth in the pincfg recursion loop
+ *
+ * @param digital_pin Arduino pin
+ * @param mode First "mode" parameter
+ * @param modes Nth "mode" parameter
+ * @return uint16_t pin configuration or'ed together
+ */
+template
+uint16_t pincfg(const pin_configure_t mode, const MODES&... modes)
+{
+ return mode | pincfg(modes...);
+}
+
+
+/**
+ * @brief Variadic template function for configuring a pin
+ *
+ * @param digital_pin Arduino pin number
+ * @param mode First "mode" parameter
+ * @param modes Nth "mode" parameter
+ */
+template
+void pinConfigure(const uint8_t digital_pin, const pin_configure_t mode, const MODES&... modes)
+{
+ // Or-ing together the arguments using recursion
+ uint16_t pin_config = pincfg(mode, modes...);
+
+ uint8_t bit_mask = digitalPinToBitMask(digital_pin);
+ if(bit_mask == NOT_A_PIN || !pin_config) // Return if digital pin is invalid or the other parameters or out to zero
+ return;
+
+ uint8_t bit_pos = digitalPinToBitPosition(digital_pin);
+ volatile uint8_t *portbase = (volatile uint8_t*) digitalPinToPortStruct(digital_pin);
+
+ // Write to selected pin direction register
+ uint8_t setting = pin_config & 0x03; // Mask out direction bits (DIR, DIRSET, DIRCLR, DIRTGL)
+ if(setting)
+ *(portbase + setting) = bit_mask;
+
+ // Write to selected output register
+ pin_config >>= 2;
+ setting = pin_config & 0x03;
+ if(setting)
+ *(portbase + 4 + setting) = bit_mask;
+
+ // Return if there is nothing more to configure
+ if(!(pin_config & 0x3FFC))
+ return;
+
+ uint8_t oldSREG = SREG; // Store SREG
+ cli(); // Disable interrupts
+
+ // PINnCTRL register
+ pin_config >>= 2;
+ uint8_t pinncfg = *(portbase + 0x10 + bit_pos);
+ // Input sense configuration (ISC)
+ if(pin_config & 0x08)
+ pinncfg = (pinncfg & 0xF8) | (pin_config & PORT_ISC_gm);
+ // Pullup resistor
+ uint8_t temp = pin_config & 0x30;
+ if(temp)
+ {
+ if(temp == 0x30)
+ pinncfg ^= PORT_PULLUPEN_bm; // Toggle pullup
+ else if(temp == 0x20)
+ pinncfg &= ~(PORT_PULLUPEN_bm); // Clear pullup
+ else
+ pinncfg |= PORT_PULLUPEN_bm; // Set pullup
+ }
+ // Invert pin
+ pin_config >>= 8;
+ temp = pin_config & 0x0C;
+ if(temp)
+ {
+ if(temp == 0x0C)
+ pinncfg ^= PORT_INVEN_bm; // Toggle invert
+ else if(temp == 0x08)
+ pinncfg &= ~(PORT_INVEN_bm); // Clear
+ else
+ pinncfg |= PORT_INVEN_bm; // Set
+ }
+ // Write to PINnCTRL register
+ *(portbase + 0x10 + bit_pos) = pinncfg;
+
+ // Restore SREG
+ SREG = oldSREG;
+}
+
#endif
#include "pins_arduino.h"
diff --git a/megaavr/cores/coreX-corefiles/CDC.cpp b/megaavr/cores/coreX-corefiles/CDC.cpp
index 9c2b947..7c5cc04 100644
--- a/megaavr/cores/coreX-corefiles/CDC.cpp
+++ b/megaavr/cores/coreX-corefiles/CDC.cpp
@@ -28,11 +28,11 @@
typedef struct
{
- uint32_t dwDTERate;
- uint8_t bCharFormat;
- uint8_t bParityType;
- uint8_t bDataBits;
- uint8_t lineState;
+ uint32_t dwDTERate;
+ uint8_t bCharFormat;
+ uint8_t bParityType;
+ uint8_t bDataBits;
+ uint8_t lineState;
} LineInfo;
static volatile LineInfo _usbLineInfo = { 57600, 0x00, 0x00, 0x00, 0x00 };
@@ -45,137 +45,140 @@ static uint8_t wdtcsr_save;
extern const CDCDescriptor _cdcInterface PROGMEM;
const CDCDescriptor _cdcInterface =
{
- D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
-
- // CDC communication interface
- D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
- D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
- D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
- D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
- D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
- D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40),
-
- // CDC data interface
- D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
- D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0),
- D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0)
+ D_IAD(0,2,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,1),
+
+ // CDC communication interface
+ D_INTERFACE(CDC_ACM_INTERFACE,1,CDC_COMMUNICATION_INTERFACE_CLASS,CDC_ABSTRACT_CONTROL_MODEL,0),
+ D_CDCCS(CDC_HEADER,0x10,0x01), // Header (1.10 bcd)
+ D_CDCCS(CDC_CALL_MANAGEMENT,1,1), // Device handles call management (not)
+ D_CDCCS4(CDC_ABSTRACT_CONTROL_MANAGEMENT,6), // SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported
+ D_CDCCS(CDC_UNION,CDC_ACM_INTERFACE,CDC_DATA_INTERFACE), // Communication interface is master, data interface is slave 0
+ D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_ACM),USB_ENDPOINT_TYPE_INTERRUPT,0x10,0x40),
+
+ // CDC data interface
+ D_INTERFACE(CDC_DATA_INTERFACE,2,CDC_DATA_INTERFACE_CLASS,0,0),
+ D_ENDPOINT(USB_ENDPOINT_OUT(CDC_ENDPOINT_OUT),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0),
+ D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,USB_EP_SIZE,0)
};
bool isLUFAbootloader()
{
- return pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE;
+ return pgm_read_word(FLASHEND - 1) == NEW_LUFA_SIGNATURE;
}
int CDC_GetInterface(uint8_t* interfaceNum)
{
- interfaceNum[0] += 2; // uses 2
- return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface));
+ interfaceNum[0] += 2; // Uses 2
+ return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface));
}
-bool CDC_Setup(USBSetup& setup)
+bool CDC_Setup(USBSetup &setup)
{
- uint8_t r = setup.bRequest;
- uint8_t requestType = setup.bmRequestType;
-
- if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
- {
- if (CDC_GET_LINE_CODING == r)
- {
- USB_SendControl(0,(void*)&_usbLineInfo,7);
- return true;
- }
- }
-
- if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
- {
- if (CDC_SEND_BREAK == r)
- {
- breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
- }
-
- if (CDC_SET_LINE_CODING == r)
- {
- USB_RecvControl((void*)&_usbLineInfo,7);
- }
-
- if (CDC_SET_CONTROL_LINE_STATE == r)
- {
- _usbLineInfo.lineState = setup.wValueL;
-
- // auto-reset into the bootloader is triggered when the port, already
- // open at 1200 bps, is closed. this is the signal to start the watchdog
- // with a relatively long period so it can finish housekeeping tasks
- // like servicing endpoints before the sketch ends
-
- uint16_t magic_key_pos = MAGIC_KEY_POS;
+ uint8_t r = setup.bRequest;
+ uint8_t requestType = setup.bmRequestType;
+
+ if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)
+ {
+ if (CDC_GET_LINE_CODING == r)
+ {
+ USB_SendControl(0, (void *)&_usbLineInfo, 7);
+ return true;
+ }
+ }
+
+ if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
+ {
+ if (CDC_SEND_BREAK == r)
+ {
+ breakValue = ((uint16_t)setup.wValueH << 8) | setup.wValueL;
+ }
+
+ if (CDC_SET_LINE_CODING == r)
+ {
+ USB_RecvControl((void *)&_usbLineInfo, 7);
+ }
+
+ if (CDC_SET_CONTROL_LINE_STATE == r)
+ {
+ _usbLineInfo.lineState = setup.wValueL;
+
+ // auto-reset into the bootloader is triggered when the port, already
+ // open at 1200 bps, is closed. this is the signal to start the watchdog
+ // with a relatively long period so it can finish housekeeping tasks
+ // like servicing endpoints before the sketch ends
+
+ uint16_t magic_key_pos = MAGIC_KEY_POS;
// If we don't use the new RAMEND directly, check manually if we have a newer bootloader.
// This is used to keep compatible with the old leonardo bootloaders.
// You are still able to set the magic key position manually to RAMEND-1 to save a few bytes for this check.
-#if MAGIC_KEY_POS != (RAMEND-1)
- // For future boards save the key in the inproblematic RAMEND
- // Which is reserved for the main() return value (which will never return)
- if (isLUFAbootloader()) {
- // horray, we got a new bootloader!
- magic_key_pos = (RAMEND-1);
- }
+#if MAGIC_KEY_POS != (RAMEND - 1)
+ // For future boards save the key in the inproblematic RAMEND
+ // Which is reserved for the main() return value (which will never return)
+ if (isLUFAbootloader())
+ {
+ // horray, we got a new bootloader!
+ magic_key_pos = (RAMEND - 1);
+ }
#endif
- // We check DTR state to determine if host port is open (bit 0 of lineState).
- if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
- {
-#if MAGIC_KEY_POS != (RAMEND-1)
- // Backup ram value if its not a newer bootloader and it hasn't already been saved.
- // This should avoid memory corruption at least a bit, not fully
- if (magic_key_pos != (RAMEND-1) && *(uint16_t *)magic_key_pos != MAGIC_KEY) {
- *(uint16_t *)(RAMEND-1) = *(uint16_t *)magic_key_pos;
- }
+ // We check DTR state to determine if host port is open (bit 0 of lineState).
+ if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
+ {
+#if MAGIC_KEY_POS != (RAMEND - 1)
+ // Backup ram value if its not a newer bootloader and it hasn't already been saved.
+ // This should avoid memory corruption at least a bit, not fully
+ if (magic_key_pos != (RAMEND - 1) && *(uint16_t *)magic_key_pos != MAGIC_KEY)
+ {
+ *(uint16_t *)(RAMEND - 1) = *(uint16_t *)magic_key_pos;
+ }
#endif
- // Store boot key
- *(uint16_t *)magic_key_pos = MAGIC_KEY;
- // Save the watchdog state in case the reset is aborted.
- wdtcsr_save = WDTCSR;
- wdt_enable(WDTO_120MS);
- }
- else if (*(uint16_t *)magic_key_pos == MAGIC_KEY)
- {
- // Most OSs do some intermediate steps when configuring ports and DTR can
- // twiggle more than once before stabilizing.
- // To avoid spurious resets we set the watchdog to 120ms and eventually
- // cancel if DTR goes back high.
- // Cancellation is only done if an auto-reset was started, which is
- // indicated by the magic key having been set.
-
- wdt_reset();
- // Restore the watchdog state in case the sketch was using it.
- WDTCSR |= (1<= 0) {
- return 1 + USB_Available(CDC_RX);
- }
- return USB_Available(CDC_RX);
+ if (peek_buffer >= 0)
+ return 1 + USB_Available(CDC_RX);
+ return USB_Available(CDC_RX);
}
int Serial_::peek(void)
{
- if (peek_buffer < 0)
- peek_buffer = USB_Recv(CDC_RX);
- return peek_buffer;
+ if (peek_buffer < 0)
+ peek_buffer = USB_Recv(CDC_RX);
+ return peek_buffer;
}
int Serial_::read(void)
{
- if (peek_buffer >= 0) {
- int c = peek_buffer;
- peek_buffer = -1;
- return c;
- }
- return USB_Recv(CDC_RX);
+ if (peek_buffer >= 0)
+ {
+ int c = peek_buffer;
+ peek_buffer = -1;
+ return c;
+ }
+ return USB_Recv(CDC_RX);
}
int Serial_::availableForWrite(void)
{
- return USB_SendSpace(CDC_TX);
+ return USB_SendSpace(CDC_TX);
}
void Serial_::flush(void)
{
- USB_Flush(CDC_TX);
+ USB_Flush(CDC_TX);
}
size_t Serial_::write(uint8_t c)
{
- return write(&c, 1);
+ return write(&c, 1);
}
size_t Serial_::write(const uint8_t *buffer, size_t size)
{
- /* only try to send bytes if the high-level CDC connection itself
- is open (not just the pipe) - the OS should set lineState when the port
- is opened and clear lineState when the port is closed.
- bytes sent before the user opens the connection or after
- the connection is closed are lost - just like with a UART. */
-
- // TODO - ZE - check behavior on different OSes and test what happens if an
- // open connection isn't broken cleanly (cable is yanked out, host dies
- // or locks up, or host virtual serial port hangs)
- if (_usbLineInfo.lineState > 0) {
- int r = USB_Send(CDC_TX,buffer,size);
- if (r > 0) {
- return r;
- } else {
- setWriteError();
- return 0;
- }
- }
- setWriteError();
- return 0;
+ /* only try to send bytes if the high-level CDC connection itself
+ is open (not just the pipe) - the OS should set lineState when the port
+ is opened and clear lineState when the port is closed.
+ bytes sent before the user opens the connection or after
+ the connection is closed are lost - just like with a UART. */
+
+ // TODO - ZE - check behavior on different OSes and test what happens if an
+ // open connection isn't broken cleanly (cable is yanked out, host dies
+ // or locks up, or host virtual serial port hangs)
+ if (_usbLineInfo.lineState > 0)
+ {
+ int r = USB_Send(CDC_TX, buffer, size);
+ if (r > 0)
+ {
+ return r;
+ }
+ else
+ {
+ setWriteError();
+ return 0;
+ }
+ }
+ setWriteError();
+ return 0;
}
// This operator is a convenient way for a sketch to check whether the
// port has actually been configured and opened by the host (as opposed
-// to just being connected to the host). It can be used, for example, in
+// to just being connected to the host). It can be used, for example, in
// setup() before printing to ensure that an application on the host is
// actually ready to receive and display the data.
// We add a short delay before returning to fix a bug observed by Federico
// where the port is configured (lineState != 0) but not quite opened.
-Serial_::operator bool() {
- bool result = false;
- if (_usbLineInfo.lineState > 0)
- result = true;
- delay(10);
- return result;
+Serial_::operator bool()
+{
+ bool result = false;
+ if (_usbLineInfo.lineState > 0)
+ result = true;
+ delay(10);
+ return result;
}
-unsigned long Serial_::baud() {
- // Disable interrupts while reading a multi-byte value
- uint32_t baudrate;
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- baudrate = _usbLineInfo.dwDTERate;
- }
- return baudrate;
+unsigned long Serial_::baud()
+{
+ // Disable interrupts while reading a multi-byte value
+ uint32_t baudrate;
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ baudrate = _usbLineInfo.dwDTERate;
+ }
+ return baudrate;
}
-uint8_t Serial_::stopbits() {
- return _usbLineInfo.bCharFormat;
+uint8_t Serial_::stopbits()
+{
+ return _usbLineInfo.bCharFormat;
}
-uint8_t Serial_::paritytype() {
- return _usbLineInfo.bParityType;
+uint8_t Serial_::paritytype()
+{
+ return _usbLineInfo.bParityType;
}
-uint8_t Serial_::numbits() {
- return _usbLineInfo.bDataBits;
+uint8_t Serial_::numbits()
+{
+ return _usbLineInfo.bDataBits;
}
-bool Serial_::dtr() {
- return _usbLineInfo.lineState & 0x1;
+bool Serial_::dtr()
+{
+ return _usbLineInfo.lineState & 0x1;
}
-bool Serial_::rts() {
- return _usbLineInfo.lineState & 0x2;
+bool Serial_::rts()
+{
+ return _usbLineInfo.lineState & 0x2;
}
-int32_t Serial_::readBreak() {
- int32_t ret;
- // Disable IRQs while reading and clearing breakValue to make
- // sure we don't overwrite a value just set by the ISR.
- ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
- ret = breakValue;
- breakValue = -1;
- }
- return ret;
+int32_t Serial_::readBreak()
+{
+ int32_t ret;
+ // Disable IRQs while reading and clearing breakValue to make
+ // sure we don't overwrite a value just set by the ISR.
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ ret = breakValue;
+ breakValue = -1;
+ }
+ return ret;
}
Serial_ Serial;
diff --git a/megaavr/cores/coreX-corefiles/CDC.h b/megaavr/cores/coreX-corefiles/CDC.h
index 43b382e..4df6459 100644
--- a/megaavr/cores/coreX-corefiles/CDC.h
+++ b/megaavr/cores/coreX-corefiles/CDC.h
@@ -4,11 +4,11 @@
#include "api/Stream.h"
#include "api/USBAPI.h"
-#if defined (USBCON)
+#if defined(USBCON)
//================================================================================
//================================================================================
-// Serial over CDC (Serial1 is the physical port)
+// Serial over CDC (Serial1 is the physical port)
#define RINGBUFFER_FORCE_SMALL_SIZE
#include "api/RingBuffer.h"
@@ -26,65 +26,67 @@
class Serial_ : public Stream
{
-private:
- int peek_buffer;
-public:
- Serial_() { peek_buffer = -1; };
- void begin(unsigned long);
- void begin(unsigned long, uint8_t);
- void end(void);
-
- virtual int available(void);
- virtual int peek(void);
- virtual int read(void);
- virtual int availableForWrite(void);
- virtual void flush(void);
- virtual size_t write(uint8_t);
- virtual size_t write(const uint8_t*, size_t);
- using Print::write; // pull in write(str) and write(buf, size) from Print
- operator bool();
-
- //RingBuffer _rx_buffer(SERIAL_BUFFER_SIZE);
-
- // This method allows processing "SEND_BREAK" requests sent by
- // the USB host. Those requests indicate that the host wants to
- // send a BREAK signal and are accompanied by a single uint16_t
- // value, specifying the duration of the break. The value 0
- // means to end any current break, while the value 0xffff means
- // to start an indefinite break.
- // readBreak() will return the value of the most recent break
- // request, but will return it at most once, returning -1 when
- // readBreak() is called again (until another break request is
- // received, which is again returned once).
- // This also mean that if two break requests are received
- // without readBreak() being called in between, the value of the
- // first request is lost.
- // Note that the value returned is a long, so it can return
- // 0-0xffff as well as -1.
- int32_t readBreak();
-
- // These return the settings specified by the USB host for the
- // serial port. These aren't really used, but are offered here
- // in case a sketch wants to act on these settings.
- uint32_t baud();
- uint8_t stopbits();
- uint8_t paritytype();
- uint8_t numbits();
- bool dtr();
- bool rts();
- enum {
- ONE_STOP_BIT = 0,
- ONE_AND_HALF_STOP_BIT = 1,
- TWO_STOP_BITS = 2,
- };
- enum {
- NO_PARITY = 0,
- ODD_PARITY = 1,
- EVEN_PARITY = 2,
- MARK_PARITY = 3,
- SPACE_PARITY = 4,
- };
-
+ private:
+ int peek_buffer;
+
+ public:
+ Serial_() { peek_buffer = -1; };
+ void begin(unsigned long);
+ void begin(unsigned long, uint8_t);
+ void end(void);
+
+ virtual int available(void);
+ virtual int peek(void);
+ virtual int read(void);
+ virtual int availableForWrite(void);
+ virtual void flush(void);
+ virtual size_t write(uint8_t);
+ virtual size_t write(const uint8_t*, size_t);
+ using Print::write; // pull in write(str) and write(buf, size) from Print
+ operator bool();
+
+ //RingBuffer _rx_buffer(SERIAL_BUFFER_SIZE);
+
+ // This method allows processing "SEND_BREAK" requests sent by
+ // the USB host. Those requests indicate that the host wants to
+ // send a BREAK signal and are accompanied by a single uint16_t
+ // value, specifying the duration of the break. The value 0
+ // means to end any current break, while the value 0xffff means
+ // to start an indefinite break.
+ // readBreak() will return the value of the most recent break
+ // request, but will return it at most once, returning -1 when
+ // readBreak() is called again (until another break request is
+ // received, which is again returned once).
+ // This also mean that if two break requests are received
+ // without readBreak() being called in between, the value of the
+ // first request is lost.
+ // Note that the value returned is a long, so it can return
+ // 0-0xffff as well as -1.
+ int32_t readBreak();
+
+ // These return the settings specified by the USB host for the
+ // serial port. These aren't really used, but are offered here
+ // in case a sketch wants to act on these settings.
+ uint32_t baud();
+ uint8_t stopbits();
+ uint8_t paritytype();
+ uint8_t numbits();
+ bool dtr();
+ bool rts();
+ enum
+ {
+ ONE_STOP_BIT = 0,
+ ONE_AND_HALF_STOP_BIT = 1,
+ TWO_STOP_BITS = 2,
+ };
+ enum
+ {
+ NO_PARITY = 0,
+ ODD_PARITY = 1,
+ EVEN_PARITY = 2,
+ MARK_PARITY = 3,
+ SPACE_PARITY = 4,
+ };
};
extern Serial_ Serial;
@@ -92,11 +94,11 @@ extern Serial_ Serial;
//================================================================================
//================================================================================
-// CSC 'Driver'
+// CSC 'Driver'
-int CDC_GetInterface(uint8_t* interfaceNum);
-int CDC_GetDescriptor(int i);
-bool CDC_Setup(USBSetup& setup);
+int CDC_GetInterface(uint8_t* interfaceNum);
+int CDC_GetDescriptor(int i);
+bool CDC_Setup(USBSetup& setup);
#endif
diff --git a/megaavr/cores/coreX-corefiles/MSC.h b/megaavr/cores/coreX-corefiles/MSC.h
index 96028e1..3705587 100644
--- a/megaavr/cores/coreX-corefiles/MSC.h
+++ b/megaavr/cores/coreX-corefiles/MSC.h
@@ -1,4 +1,4 @@
-#if defined (USBCON)
+#if defined(USBCON)
#ifndef __MSC_H__
#define __MSC_H__
@@ -7,12 +7,12 @@
//================================================================================
//================================================================================
-// MSC 'Driver'
+// MSC 'Driver'
-int MSC_GetInterface(uint8_t* interfaceNum);
-int MSC_GetDescriptor(int i);
-bool MSC_Setup(USBSetup& setup);
-bool MSC_Data(uint8_t rx,uint8_t tx);
+int MSC_GetInterface(uint8_t* interfaceNum);
+int MSC_GetDescriptor(int i);
+bool MSC_Setup(USBSetup& setup);
+bool MSC_Data(uint8_t rx, uint8_t tx);
#endif
diff --git a/megaavr/cores/coreX-corefiles/Tone.cpp b/megaavr/cores/coreX-corefiles/Tone.cpp
index 1102462..791154f 100644
--- a/megaavr/cores/coreX-corefiles/Tone.cpp
+++ b/megaavr/cores/coreX-corefiles/Tone.cpp
@@ -36,29 +36,30 @@
#include
#include
+
#include "Arduino.h"
#include "pins_arduino.h"
/* For more than one tone, change AVAILABLE_TONE_PINS and uncomment the correct
number of timers
*/
-#define AVAILABLE_TONE_PINS 1
+#define AVAILABLE_TONE_PINS 1
-#define USE_TIMERB1 // interferes with PWM on pin 3
+#define USE_TIMERB1 // interferes with TCB1 PWM
/*
-#define USE_TIMERB2 // interferes with PWM on pin 11
-#define USE_TIMERB0 // interferes with PWM on pin 6
+#define USE_TIMERB2 // interferes with TCB2 PWM, and timer in many configurations
+#define USE_TIMERB0 // interferes with TCB0 PWM
*/
-#if !defined(USE_TIMERB1) && !defined(USE_TIMERB2) && !defined(USE_TIMERB0)
- # error "No timers allowed for tone()"
- /* Please uncomment a timer above and rebuild */
+#if !defined(USE_TIMERB0) && !defined(USE_TIMERB1) && !defined(USE_TIMERB2) && !defined(USE_TIMERB3)
+#error "No timers allowed for tone()"
+/* Please uncomment a timer above and rebuild */
#endif
-// Can't use TIMERB3 -- used for application time tracking
+// Can't use timer assigned for application time tracking (usually TIMERB2 or TIMERB3)
// Using TIMERA0 NOT RECOMMENDED -- all other timers use its clock!
-static volatile TCB_t* _timer =
+static volatile TCB_t *_timer =
#if defined(USE_TIMERB0)
-&TCB0;
+ &TCB0;
#endif
#if defined(USE_TIMERB1)
&TCB1;
@@ -66,6 +67,9 @@ static volatile TCB_t* _timer =
#if defined(USE_TIMERB2)
&TCB2;
#endif
+#if defined(USE_TIMERB3)
+&TCB3;
+#endif
static int _pin = NOT_A_PIN;
@@ -80,89 +84,124 @@ volatile uint8_t timer_bit_mask;
// helper functions
static void disableTimer();
+static byte timerPrescaler();
// frequency (in hertz) and duration (in milliseconds).
void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
{
- long toggle_count = 0;
- uint32_t compare_val = 0;
-
- if (_pin != pin) {
- pinMode(pin, OUTPUT);
- _pin = pin;
- }
-
- // Get pin related stuff
- PORT_t *port = digitalPinToPortStruct(_pin);
- uint8_t *port_outtgl = (uint8_t *)&(port->OUTTGL);
- uint8_t bit_mask = digitalPinToBitMask(_pin);
-
- if (frequency == 0) {
- bit_mask = 0;
- frequency = 1;
- }
-
- // Calculate compare value
- compare_val = F_CPU_CORRECTED / frequency / 2 - 1;
- // If compare larger than 16bits, need to prescale (will be DIV64)
- uint8_t prescaler_needed = 0;
- if (compare_val > 0xFFFF){
- // recalculate with new prescaler
- compare_val = F_CPU_CORRECTED / frequency / 2 / 64 - 1;
- prescaler_needed = 1;
- }
-
- // Calculate the toggle count
- if (duration > 0){ // Duration defined
- toggle_count = 2 * frequency * duration / 1000;
- } else { // Duration not defined -- tone until noTone() call
- toggle_count = -1;
- }
-
- // Timer settings -- will be type B
- uint8_t status = SREG;
- cli();
-
- // Disable for now, set clk according to 'prescaler_needed'
- // (Prescaled clock will come from TCA --
- // by default it should have a prescaler of 64 (250kHz clock)
- // TCA default initialization is in wiring.c -- init() )
- if(prescaler_needed){
- _timer->CTRLA = TCB_CLKSEL_CLKTCA_gc;
- } else {
- _timer->CTRLA = TCB_CLKSEL_CLKDIV1_gc;
- }
-
- // Timer to Periodic interrupt mode
- // This write will also disable any active PWM outputs
- _timer->CTRLB = TCB_CNTMODE_INT_gc;
-
- // Write compare register
- _timer->CCMP = compare_val;
-
- // Enable interrupt
- _timer->INTCTRL = TCB_CAPTEI_bm;
-
- timer_outtgl_reg = port_outtgl;
- timer_bit_mask = bit_mask;
- timer_toggle_count = toggle_count;
-
- // Enable timer
- _timer->CTRLA |= TCB_ENABLE_bm;
-
- SREG = status;
+ long toggle_count = 0;
+ uint32_t compare_val = 0;
+
+ if (_pin != pin)
+ {
+ pinMode(pin, OUTPUT);
+ _pin = pin;
+ }
+
+ // Get pin related stuff
+ PORT_t *port = digitalPinToPortStruct(_pin);
+ uint8_t *port_outtgl = (uint8_t *)&(port->OUTTGL);
+ uint8_t bit_mask = digitalPinToBitMask(_pin);
+
+ if (frequency == 0)
+ {
+ bit_mask = 0;
+ frequency = 1;
+ }
+
+ // Calculate compare value, assuming F_CPU/2 used as clock
+ compare_val = F_CPU / frequency / 4 - 1;
+ // If compare larger than 16bits, need to prescale (will be DIV64)
+ uint8_t prescaler = 0;
+ if (compare_val > 0xFFFF)
+ {
+ // recalculate with new prescaler
+ prescaler = timerPrescaler();
+ compare_val = F_CPU / frequency / 2 / prescaler - 1;
+ if (compare_val > 0xFFFF) compare_val = 0xFFFF; // request lower frequency than supported
+ }
+
+ // Calculate the toggle count
+ if (duration > 0)
+ { // Duration defined
+ toggle_count = 2 * frequency * duration / 1000;
+ }
+ else
+ { // Duration not defined -- tone until noTone() call
+ toggle_count = -1;
+ }
+
+ // Timer settings -- will be type B
+ uint8_t status = SREG;
+ cli();
+
+ // Disable for now, set clk according to whether 'prescaler' is zero
+ // (Prescaled clock will come from TCA --
+ // by default it should have a prescaler of 64 (250kHz clock)
+ // but this may have changed with analogWriteFrequency()
+ // TCA default initialization is in wiring.c -- init() )
+ if (prescaler != 0)
+ {
+ _timer->CTRLA = TCB_CLKSEL_CLKTCA_gc;
+ }
+ else
+ {
+ _timer->CTRLA = TCB_CLKSEL_CLKDIV2_gc;
+ }
+
+ // Timer to Periodic interrupt mode
+ // This write will also disable any active PWM outputs
+ _timer->CTRLB = TCB_CNTMODE_INT_gc;
+
+ // Write compare register
+ _timer->CCMP = compare_val;
+
+ // Enable interrupt
+ _timer->INTCTRL = TCB_CAPTEI_bm;
+
+ timer_outtgl_reg = port_outtgl;
+ timer_bit_mask = bit_mask;
+ timer_toggle_count = toggle_count;
+
+ // Enable timer
+ _timer->CTRLA |= TCB_ENABLE_bm;
+
+ SREG = status;
}
// pin which currently is being used for a tone
void noTone(uint8_t pin)
{
- if (pin == _pin) {
- timer_toggle_count = 0;
- //disableTimer();
- // Keep pin low after disabling of timer
- digitalWrite(_pin, LOW);
- _pin = NOT_A_PIN;
- }
+ if (pin == _pin)
+ {
+ timer_toggle_count = 0;
+ //disableTimer();
+ // Keep pin low after disabling of timer
+ digitalWrite(_pin, LOW);
+ _pin = NOT_A_PIN;
+ }
+}
+
+// helper function for noTone()
+// find which timer prescaler is currently used
+static byte timerPrescaler()
+{
+ byte clksel = (TCA0.SPLIT.CTRLA & TCA_SPLIT_CLKSEL_gm) >> TCA_SPLIT_CLKSEL_gp;
+
+ // the next five lines may have been a #if,
+ // but alas the C preprocessor does not understand enums
+ // they should produce no real code, though
+ if ((TCA_SPLIT_CLKSEL_DIV1_gc >> TCA_SPLIT_CLKSEL_gp) == 0
+ && (TCA_SPLIT_CLKSEL_DIV2_gc >> TCA_SPLIT_CLKSEL_gp) == 1
+ && (TCA_SPLIT_CLKSEL_DIV4_gc >> TCA_SPLIT_CLKSEL_gp) == 2
+ && (TCA_SPLIT_CLKSEL_DIV8_gc >> TCA_SPLIT_CLKSEL_gp) == 3
+ && (TCA_SPLIT_CLKSEL_DIV16_gc >> TCA_SPLIT_CLKSEL_gp) == 4
+ && clksel <= (TCA_SPLIT_CLKSEL_DIV16_gc >> TCA_SPLIT_CLKSEL_gp))
+ {
+ // non-standard TCA clock selection is used
+ return 1 << clksel;
+ }
+ return 64;
}
// helper function for noTone()
@@ -170,11 +209,11 @@ void noTone(uint8_t pin)
configuration it had to output PWM for analogWrite() */
static void disableTimer()
{
- // Reinit back to producing PWM -- timer will be type B
- // Disable interrupt
- _timer->INTCTRL = 0;
- // Disable timer
- _timer->CTRLA = 0;
+ // Reinit back to producing PWM -- timer will be type B
+ // Disable interrupt
+ _timer->INTCTRL = 0;
+ // Disable timer
+ _timer->CTRLA = 0;
#if 0
// RESTORE PWM FUNCTIONALITY:
@@ -190,7 +229,6 @@ static void disableTimer()
#endif
}
-
#if defined USE_TIMERB0
ISR(TCB0_INT_vect)
#elif defined USE_TIMERB1
@@ -199,23 +237,25 @@ ISR(TCB1_INT_vect)
ISR(TCB2_INT_vect)
#endif
{
- if (timer_toggle_count != 0){
-
- // toggle the pin
- *timer_outtgl_reg = timer_bit_mask;
-
- // If duration was defined, decrement
- if (timer_toggle_count > 0){
- timer_toggle_count--;
- }
-
- // If no duration (toggle count negative), go on until noTone() call
+ if (timer_toggle_count != 0)
+ {
+ // toggle the pin
+ *timer_outtgl_reg = timer_bit_mask;
+
+ // If duration was defined, decrement
+ if (timer_toggle_count > 0)
+ {
+ timer_toggle_count--;
+ }
- } else if (timer_toggle_count == 0) { // If toggle count = 0, stop
+ // If no duration (toggle count negative), go on until noTone() call
+ }
+ else if (timer_toggle_count == 0)
+ { // If toggle count = 0, stop
- disableTimer();
- }
+ disableTimer();
+ }
- /* Clear flag */
- _timer->INTFLAGS = TCB_CAPT_bm;
+ /* Clear flag */
+ _timer->INTFLAGS = TCB_CAPT_bm;
}
diff --git a/megaavr/cores/coreX-corefiles/UART.cpp b/megaavr/cores/coreX-corefiles/UART.cpp
index 3f4234c..1ce409d 100644
--- a/megaavr/cores/coreX-corefiles/UART.cpp
+++ b/megaavr/cores/coreX-corefiles/UART.cpp
@@ -63,16 +63,16 @@ bool Serial3_available() __attribute__((weak));
void serialEventRun(void)
{
#if defined(HAVE_HWSERIAL0)
- if (Serial0_available && serialEvent && Serial0_available()) serialEvent();
+ if (Serial0_available && serialEvent && Serial0_available()) serialEvent();
#endif
#if defined(HAVE_HWSERIAL1)
- if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1();
+ if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1();
#endif
#if defined(HAVE_HWSERIAL2)
- if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2();
+ if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2();
#endif
#if defined(HAVE_HWSERIAL3)
- if (Serial3_available && serialEvent3 && Serial3_available()) serialEvent3();
+ if (Serial3_available && serialEvent3 && Serial3_available()) serialEvent3();
#endif
}
@@ -87,271 +87,299 @@ void serialEventRun(void)
void UartClass::_tx_data_empty_irq(void)
{
- // Check if tx buffer already empty.
- // This interrupt-handler can be called "manually" from flush();
- if (_tx_buffer_head == _tx_buffer_tail) {
- // Buffer empty, so disable "data register empty" interrupt
- (*_hwserial_module).CTRLA &= (~USART_DREIE_bm);
- return;
- }
-
- // There must be more data in the output
- // buffer. Send the next byte
- unsigned char c = _tx_buffer[_tx_buffer_tail];
- _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;
+ // Check if tx buffer already empty.
+ if (_tx_buffer_head == _tx_buffer_tail)
+ {
+ // Buffer empty, so disable "data register empty" interrupt
+ (*_hwserial_module).CTRLA &= (~USART_DREIE_bm);
+ return;
+ }
- // clear the TXCIF flag -- "can be cleared by writing a one to its bit
- // location". This makes sure flush() won't return until the bytes
- // actually got written
- (*_hwserial_module).STATUS = USART_TXCIF_bm;
+ // There must be more data in the output
+ // buffer. Send the next byte
+ unsigned char c = _tx_buffer[_tx_buffer_tail];
+ _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;
- (*_hwserial_module).TXDATAL = c;
+ // clear the TXCIF flag -- "can be cleared by writing a one to its bit
+ // location". This makes sure flush() won't return until the bytes
+ // actually got written
+ (*_hwserial_module).STATUS = USART_TXCIF_bm;
- while(!((*_hwserial_module).STATUS & USART_DREIF_bm));
+ (*_hwserial_module).TXDATAL = c;
- if (_tx_buffer_head == _tx_buffer_tail) {
- // Buffer empty, so disable "data register empty" interrupt
- (*_hwserial_module).CTRLA &= (~USART_DREIE_bm);
+ if (_tx_buffer_head == _tx_buffer_tail)
+ {
+ // Buffer empty, so disable "data register empty" interrupt
+ (*_hwserial_module).CTRLA &= (~USART_DREIE_bm);
+
+ //Take the DRE interrupt back no normal priority level if it has been elevated
+ if (_hwserial_dre_interrupt_elevated)
+ {
+ CPUINT.LVL1VEC = _prev_lvl1_interrupt_vect;
+ _hwserial_dre_interrupt_elevated = 0;
+ }
+ }
+}
- //Take the DRE interrupt back no normal priority level if it has been elevated
- if(_hwserial_dre_interrupt_elevated) {
- CPUINT.LVL1VEC = _prev_lvl1_interrupt_vect;
- _hwserial_dre_interrupt_elevated = 0;
- }
+// To invoke data empty "interrupt" via a call, use this method
+void UartClass::_poll_tx_data_empty(void)
+{
+ if ((!(SREG & CPU_I_bm)) || (!((*_hwserial_module).CTRLA & USART_DREIE_bm)))
+ {
+ // Interrupts are disabled either globally or for data register empty,
+ // so we'll have to poll the "data register empty" flag ourselves.
+ // If it is set, pretend an interrupt has happened and call the handler
+ // to free up space for us.
+
+ // Invoke interrupt handler only if conditions data register is empty
+ if ((*_hwserial_module).STATUS & USART_DREIF_bm)
+ {
+ _tx_data_empty_irq();
}
+ }
+ // In case interrupts are enabled, the interrupt routine will be invoked by itself
}
// Public Methods //////////////////////////////////////////////////////////////
-void UartClass::begin(unsigned long baud, uint16_t config)
+// Invoke this function before 'begin' to define the pins used
+bool UartClass::pins(uint8_t tx, uint8_t rx)
{
- // Make sure no transmissions are ongoing and USART is disabled in case begin() is called by accident
- // without first calling end()
- if(_written) {
- this->end();
+ for (_pin_set = 0; _pin_set < SERIAL_PIN_SETS; ++_pin_set)
+ {
+ if (tx == _hw_set[_pin_set].tx_pin && rx == _hw_set[_pin_set].rx_pin)
+ {
+ // We are good, this set of pins is supported
+ return true;
}
+ }
+ _pin_set = 0; // Default to standard
+ return false;
+}
- // Setup default port mux
- PORTMUX.USARTROUTEA |= _uart_mux;
+bool UartClass::swap(uint8_t state)
+{
+ if (state == 1) // Use alternative pin position
+ {
+ _pin_set = state;
+ return true;
+ }
+ else if (state == 0) // Use default pin position
+ {
+ _pin_set = 0;
+ return true;
+ }
+ else // Invalid swap value. Use default position
+ {
+ _pin_set = 0;
+ return false;
+ }
+}
- int32_t baud_setting = 0;
+void UartClass::begin(unsigned long baud, uint16_t config)
+{
+ // Make sure no transmissions are ongoing and USART is disabled in case begin() is called by accident
+ // without first calling end()
+ if (_written)
+ {
+ this->end();
+ }
- //Make sure global interrupts are disabled during initialization
- uint8_t oldSREG = SREG;
- cli();
+ struct UartPinSet *set = &_hw_set[_pin_set];
- baud_setting = (((8 * F_CPU_CORRECTED) / baud) + 1) / 2;
- // Disable CLK2X
- (*_hwserial_module).CTRLB &= (~USART_RXMODE_CLK2X_gc);
- (*_hwserial_module).CTRLB |= USART_RXMODE_NORMAL_gc;
+ int32_t baud_setting = 0;
- _written = false;
+ //Make sure global interrupts are disabled during initialization
+ uint8_t oldSREG = SREG;
+ cli();
- //Set up the rx pin
- pinMode(_hwserial_rx_pin, INPUT_PULLUP);
+ baud_setting = (((8 * F_CPU) / baud) + 1) / 2;
+ // Disable CLK2X
+ (*_hwserial_module).CTRLB &= (~USART_RXMODE_CLK2X_gc);
+ (*_hwserial_module).CTRLB |= USART_RXMODE_NORMAL_gc;
- //Set up the tx pin
- digitalWrite(_hwserial_tx_pin, HIGH);
- pinMode(_hwserial_tx_pin, OUTPUT);
+ _written = false;
- int8_t sigrow_val = SIGROW.OSC16ERR5V;
- baud_setting *= (1024 + sigrow_val);
- baud_setting /= (1024 - abs(sigrow_val));
+ int8_t sigrow_val = 0;
- // assign the baud_setting, a.k.a. BAUD (USART Baud Rate Register)
- (*_hwserial_module).BAUD = (int16_t) baud_setting;
+// Use error compensation if internal oscillator is used
+#if !defined(USE_EXTERNAL_OSCILLATOR)
+#if F_CPU == 20000000L
+ sigrow_val = SIGROW.OSC20ERR5V;
+#else
+ sigrow_val = SIGROW.OSC16ERR5V;
+#endif
+#endif
- // Set USART mode of operation
- (*_hwserial_module).CTRLC = config;
+ baud_setting += (baud_setting * sigrow_val) / 1024;
- // Enable transmitter and receiver
- (*_hwserial_module).CTRLB |= (USART_RXEN_bm | USART_TXEN_bm);
+ // assign the baud_setting, a.k.a. BAUD (USART Baud Rate Register)
+ (*_hwserial_module).BAUD = (uint16_t)baud_setting;
- (*_hwserial_module).CTRLA |= USART_RXCIE_bm;
+ // Set USART mode of operation
+ (*_hwserial_module).CTRLC = config;
- // Restore SREG content
- SREG = oldSREG;
-}
+ // Enable transmitter and receiver
+ (*_hwserial_module).CTRLB |= (USART_RXEN_bm | USART_TXEN_bm);
-void UartClass::swap(uint8_t shouldSwap)
-{
- if(shouldSwap == true)
- {
- // Let PORTMUX pont to alternative UART pins
- if(_uart_mux_swap > 0)
- PORTMUX.USARTROUTEA |= _uart_mux;
- else
- PORTMUX.USARTROUTEA &= ~_uart_mux;
-
- // Set pin state for alternative UART pins
- pinMode(_hwserial_rx_pin_swap, INPUT_PULLUP);
- digitalWrite(_hwserial_tx_pin_swap, HIGH);
- pinMode(_hwserial_tx_pin_swap, OUTPUT);
-
- // Set previous pins to high Z
- pinMode(_hwserial_rx_pin, INPUT);
- pinMode(_hwserial_tx_pin, INPUT);
- }
- else //if(shouldSwap == false)
- {
- if(_uart_mux > 0)
- PORTMUX.USARTROUTEA |= _uart_mux;
- else
- PORTMUX.USARTROUTEA &= ~_uart_mux;
-
- // Set pin state for default UART pins
- pinMode(_hwserial_rx_pin, INPUT_PULLUP);
- digitalWrite(_hwserial_tx_pin, HIGH);
- pinMode(_hwserial_tx_pin, OUTPUT);
-
- // Set previous pins to high Z
- pinMode(_hwserial_rx_pin_swap, INPUT);
- pinMode(_hwserial_tx_pin_swap, INPUT);
- }
+ (*_hwserial_module).CTRLA |= USART_RXCIE_bm;
+
+ // Let PORTMUX point to alternative UART pins as requested
+ PORTMUX.USARTROUTEA = set->mux | (PORTMUX.USARTROUTEA & ~_hw_set[1].mux);
+
+ // Set pin state for swapped UART pins
+ pinMode(set->rx_pin, INPUT_PULLUP);
+ digitalWrite(set->tx_pin, HIGH);
+ pinMode(set->tx_pin, OUTPUT);
+
+ // Restore SREG content
+ SREG = oldSREG;
}
void UartClass::end()
{
- // wait for transmission of outgoing data
- flush();
+ // wait for transmission of outgoing data
+ flush();
- // Disable receiver and transmitter as well as the RX complete and
- // data register empty interrupts.
- (*_hwserial_module).CTRLB &= ~(USART_RXEN_bm | USART_TXEN_bm);
- (*_hwserial_module).CTRLA &= ~(USART_RXCIE_bm | USART_DREIE_bm);
+ // Disable receiver and transmitter as well as the RX complete and
+ // data register empty interrupts.
+ (*_hwserial_module).CTRLB &= ~(USART_RXEN_bm | USART_TXEN_bm);
+ (*_hwserial_module).CTRLA &= ~(USART_RXCIE_bm | USART_DREIE_bm);
- // clear any received data
- _rx_buffer_head = _rx_buffer_tail;
+ // clear any received data
+ _rx_buffer_head = _rx_buffer_tail;
- _written = false;
+ // Note: Does not change output pins
+ _written = false;
}
int UartClass::available(void)
{
- return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
+ return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
}
int UartClass::peek(void)
{
- if (_rx_buffer_head == _rx_buffer_tail) {
- return -1;
- } else {
- return _rx_buffer[_rx_buffer_tail];
- }
+ if (_rx_buffer_head == _rx_buffer_tail)
+ {
+ return -1;
+ }
+ else
+ {
+ return _rx_buffer[_rx_buffer_tail];
+ }
}
int UartClass::read(void)
{
- // if the head isn't ahead of the tail, we don't have any characters
- if (_rx_buffer_head == _rx_buffer_tail) {
- return -1;
- } else {
- unsigned char c = _rx_buffer[_rx_buffer_tail];
- _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
- return c;
- }
+ // if the head isn't ahead of the tail, we don't have any characters
+ if (_rx_buffer_head == _rx_buffer_tail)
+ {
+ return -1;
+ }
+ else
+ {
+ unsigned char c = _rx_buffer[_rx_buffer_tail];
+ _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
+ return c;
+ }
}
int UartClass::availableForWrite(void)
{
- tx_buffer_index_t head;
- tx_buffer_index_t tail;
+ tx_buffer_index_t head;
+ tx_buffer_index_t tail;
- TX_BUFFER_ATOMIC {
- head = _tx_buffer_head;
- tail = _tx_buffer_tail;
- }
- if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
- return tail - head - 1;
+ TX_BUFFER_ATOMIC
+ {
+ head = _tx_buffer_head;
+ tail = _tx_buffer_tail;
+ }
+ if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
+ return tail - head - 1;
}
void UartClass::flush()
{
- // If we have never written a byte, no need to flush. This special
- // case is needed since there is no way to force the TXCIF (transmit
- // complete) bit to 1 during initialization
- if (!_written) {
- return;
- }
-
- //Check if we are inside an ISR already (e.g. connected to a different peripheral then UART), in which case the UART ISRs will not be called.
- //Temporarily elevate the DRE interrupt to allow it to run.
- if(CPUINT.STATUS & CPUINT_LVL0EX_bm) {
- //Elevate the priority level of the Data Register Empty Interrupt vector
- //and copy whatever vector number that might be in the register already.
- _prev_lvl1_interrupt_vect = CPUINT.LVL1VEC;
- CPUINT.LVL1VEC = _hwserial_dre_interrupt_vect_num;
+ // If we have never written a byte, no need to flush. This special
+ // case is needed since there is no way to force the TXCIF (transmit
+ // complete) bit to 1 during initialization
+ if (!_written)
+ {
+ return;
+ }
- _hwserial_dre_interrupt_elevated = 1;
- }
+ //Check if we are inside an ISR already (e.g. connected to a different peripheral then UART), in which case the UART ISRs will not be called.
+ //Temporarily elevate the DRE interrupt to allow it to run.
+ if (CPUINT.STATUS & CPUINT_LVL0EX_bm)
+ {
+ //Elevate the priority level of the Data Register Empty Interrupt vector
+ //and copy whatever vector number that might be in the register already.
+ _prev_lvl1_interrupt_vect = CPUINT.LVL1VEC;
+ CPUINT.LVL1VEC = _hwserial_dre_interrupt_vect_num;
- // Spin until the data-register-empty-interrupt is disabled and TX complete interrupt flag is raised
- while ( ((*_hwserial_module).CTRLA & USART_DREIE_bm) || (!((*_hwserial_module).STATUS & USART_TXCIF_bm)) ) {
+ _hwserial_dre_interrupt_elevated = 1;
+ }
- // If interrupts are globally disabled or the and DR empty interrupt is disabled,
- // poll the "data register empty" interrupt flag to prevent deadlock
- if ( (!(SREG & CPU_I_bm)) || (!((*_hwserial_module).CTRLA & USART_DREIE_bm)) ) {
- _tx_data_empty_irq();
- }
- }
- // If we get here, nothing is queued anymore (DREIE is disabled) and
- // the hardware finished transmission (TXCIF is set).
+ // Spin until the data-register-empty-interrupt is disabled and TX complete interrupt flag is raised
+ while (((*_hwserial_module).CTRLA & USART_DREIE_bm) || (!((*_hwserial_module).STATUS & USART_TXCIF_bm)))
+ {
+ // If interrupts are globally disabled or the and DR empty interrupt is disabled,
+ // poll the "data register empty" interrupt flag to prevent deadlock
+ _poll_tx_data_empty();
+ }
+ // If we get here, nothing is queued anymore (DREIE is disabled) and
+ // the hardware finished transmission (TXCIF is set).
}
size_t UartClass::write(uint8_t c)
{
- _written = true;
+ _written = true;
- // If the buffer and the data register is empty, just write the byte
- // to the data register and be done. This shortcut helps
- // significantly improve the effective data rate at high (>
- // 500kbit/s) bit rates, where interrupt overhead becomes a slowdown.
- if ( (_tx_buffer_head == _tx_buffer_tail) && ((*_hwserial_module).STATUS & USART_DREIF_bm) ) {
- (*_hwserial_module).TXDATAL = c;
- (*_hwserial_module).STATUS = USART_TXCIF_bm;
+ // If the buffer and the data register is empty, just write the byte
+ // to the data register and be done. This shortcut helps
+ // significantly improve the effective data rate at high (>
+ // 500kbit/s) bit rates, where interrupt overhead becomes a slowdown.
+ if ((_tx_buffer_head == _tx_buffer_tail) && ((*_hwserial_module).STATUS & USART_DREIF_bm))
+ {
+ (*_hwserial_module).TXDATAL = c;
+ (*_hwserial_module).STATUS = USART_TXCIF_bm;
- // Make sure data register empty interrupt is disabled to avoid
- // that the interrupt handler is called in this situation
- (*_hwserial_module).CTRLA &= (~USART_DREIE_bm);
+ // Make sure data register empty interrupt is disabled to avoid
+ // that the interrupt handler is called in this situation
+ (*_hwserial_module).CTRLA &= (~USART_DREIE_bm);
- return 1;
- }
+ return 1;
+ }
- //Check if we are inside an ISR already (could be from by a source other than UART),
- // in which case the UART ISRs will be blocked.
- if(CPUINT.STATUS & CPUINT_LVL0EX_bm) {
- //Elevate the priority level of the Data Register Empty Interrupt vector
- //and copy whatever vector number that might be in the register already.
- _prev_lvl1_interrupt_vect = CPUINT.LVL1VEC;
- CPUINT.LVL1VEC = _hwserial_dre_interrupt_vect_num;
+ //Check if we are inside an ISR already (could be from by a source other than UART),
+ // in which case the UART ISRs will be blocked.
+ if (CPUINT.STATUS & CPUINT_LVL0EX_bm)
+ {
+ //Elevate the priority level of the Data Register Empty Interrupt vector
+ //and copy whatever vector number that might be in the register already.
+ _prev_lvl1_interrupt_vect = CPUINT.LVL1VEC;
+ CPUINT.LVL1VEC = _hwserial_dre_interrupt_vect_num;
- _hwserial_dre_interrupt_elevated = 1;
- }
+ _hwserial_dre_interrupt_elevated = 1;
+ }
- tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
-
- //If the output buffer is full, there's nothing for it other than to
- //wait for the interrupt handler to empty it a bit
- while (i == _tx_buffer_tail) {
- if ( ( !(SREG & CPU_I_bm) ) || ( !((*_hwserial_module).CTRLA & USART_DREIE_bm) ) ) {
- // Interrupts are disabled either globally or for data register empty,
- // so we'll have to poll the "data register empty" flag ourselves.
- // If it is set, pretend an interrupt has happened and call the handler
- //to free up space for us.
-
- _tx_data_empty_irq();
- } else {
- // nop, the interrupt handler will free up space for us
- }
- }
+ tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
- _tx_buffer[_tx_buffer_head] = c;
- _tx_buffer_head = i;
+ //If the output buffer is full, there's nothing for it other than to
+ //wait for the interrupt handler to empty it a bit (or emulate interrupts)
+ while (i == _tx_buffer_tail)
+ {
+ _poll_tx_data_empty();
+ }
- // Enable data "register empty interrupt"
- (*_hwserial_module).CTRLA |= USART_DREIE_bm;
+ _tx_buffer[_tx_buffer_head] = c;
+ _tx_buffer_head = i;
- return 1;
+ // Enable data "register empty interrupt"
+ (*_hwserial_module).CTRLA |= USART_DREIE_bm;
+
+ return 1;
}
#endif // whole file
diff --git a/megaavr/cores/coreX-corefiles/UART.h b/megaavr/cores/coreX-corefiles/UART.h
index 4ae9c06..896a8db 100644
--- a/megaavr/cores/coreX-corefiles/UART.h
+++ b/megaavr/cores/coreX-corefiles/UART.h
@@ -120,18 +120,20 @@ typedef uint8_t rx_buffer_index_t;
#define SERIAL_7O2 (USART_CMODE_ASYNCHRONOUS_gc | USART_CHSIZE_7BIT_gc | USART_PMODE_ODD_gc | USART_SBMODE_2BIT_gc)
#define SERIAL_8O2 (USART_CMODE_ASYNCHRONOUS_gc | USART_CHSIZE_8BIT_gc | USART_PMODE_ODD_gc | USART_SBMODE_2BIT_gc)
+#define SERIAL_PIN_SETS 2
+
class UartClass : public HardwareSerial
{
protected:
volatile USART_t * const _hwserial_module;
- volatile uint8_t const _hwserial_rx_pin;
- volatile uint8_t const _hwserial_tx_pin;
- volatile uint8_t const _hwserial_rx_pin_swap;
- volatile uint8_t const _hwserial_tx_pin_swap;
+ struct UartPinSet {
+ uint8_t const rx_pin;
+ uint8_t const tx_pin;
+ uint8_t const mux;
+ } _hw_set[SERIAL_PIN_SETS];
- volatile uint8_t const _uart_mux;
- volatile uint8_t const _uart_mux_swap;
+ uint8_t _pin_set;
// Has any byte been written to the UART since begin()
bool _written;
@@ -148,14 +150,15 @@ class UartClass : public HardwareSerial
// Don't put any members after these buffers, since only the first
// 32 bytes of this struct can be accessed quickly using the ldd
// instruction.
- unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
- unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
+ volatile unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
+ volatile unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
public:
inline UartClass(volatile USART_t *hwserial_module, uint8_t hwserial_rx_pin, uint8_t hwserial_tx_pin, uint8_t hwserial_rx_pin_swap, uint8_t hwserial_tx_pin_swap, uint8_t dre_vect_num, uint8_t uart_mux, uint8_t uart_mux_swap);
+ bool pins(uint8_t tx, uint8_t rx);
+ bool swap(uint8_t state = 1);
void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
void begin(unsigned long, uint16_t);
- void swap(uint8_t shouldSwap = true);
void end();
virtual int available(void);
virtual int peek(void);
@@ -168,11 +171,14 @@ class UartClass : public HardwareSerial
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
using Print::write; // pull in write(str) and write(buf, size) from Print
- operator bool() { return true; }
+ explicit operator bool() { return true; }
// Interrupt handlers - Not intended to be called externally
inline void _rx_complete_irq(void);
void _tx_data_empty_irq(void);
+
+ private:
+ void _poll_tx_data_empty(void);
};
#if defined(HWSERIAL0)
diff --git a/megaavr/cores/coreX-corefiles/UART0.cpp b/megaavr/cores/coreX-corefiles/UART0.cpp
index 50b2264..9f8686a 100644
--- a/megaavr/cores/coreX-corefiles/UART0.cpp
+++ b/megaavr/cores/coreX-corefiles/UART0.cpp
@@ -51,16 +51,17 @@ ISR(HWSERIAL0_DRE_VECTOR)
Serial._tx_data_empty_irq();
}
#else
-#error "Don't know what the Data Received interrupt vector is called for Serial"
+#error "Don't know what the Data Register Empty interrupt vector is called for Serial"
#endif
#if defined(HWSERIAL0)
- UartClass Serial(HWSERIAL0, PIN_WIRE_HWSERIAL0_RX, PIN_WIRE_HWSERIAL0_TX, PIN_WIRE_HWSERIAL0_RX_PINSWAP_1, PIN_WIRE_HWSERIAL0_TX_PINSWAP_1, HWSERIAL0_DRE_VECTOR_NUM, HWSERIAL0_MUX, HWSERIAL0_MUX_PINSWAP_1);
+UartClass Serial(HWSERIAL0, PIN_HWSERIAL0_RX, PIN_HWSERIAL0_TX, PIN_HWSERIAL0_RX_PINSWAP_1, PIN_HWSERIAL0_TX_PINSWAP_1, HWSERIAL0_DRE_VECTOR_NUM, HWSERIAL0_MUX, HWSERIAL0_MUX_PINSWAP_1);
#endif
// Function that can be weakly referenced by serialEventRun to prevent
// pulling in this file if it's not otherwise used.
-bool Serial0_available() {
+bool Serial0_available()
+{
return Serial.available();
}
diff --git a/megaavr/cores/coreX-corefiles/UART1.cpp b/megaavr/cores/coreX-corefiles/UART1.cpp
index c15332e..99cc22e 100644
--- a/megaavr/cores/coreX-corefiles/UART1.cpp
+++ b/megaavr/cores/coreX-corefiles/UART1.cpp
@@ -55,12 +55,13 @@ ISR(HWSERIAL1_DRE_VECTOR)
#endif
#if defined(HWSERIAL1)
- UartClass Serial1(HWSERIAL1, PIN_WIRE_HWSERIAL1_RX, PIN_WIRE_HWSERIAL1_TX, PIN_WIRE_HWSERIAL1_RX_PINSWAP_1, PIN_WIRE_HWSERIAL1_TX_PINSWAP_1, HWSERIAL1_DRE_VECTOR_NUM, HWSERIAL1_MUX, HWSERIAL1_MUX_PINSWAP_1);
+UartClass Serial1(HWSERIAL1, PIN_HWSERIAL1_RX, PIN_HWSERIAL1_TX, PIN_HWSERIAL1_RX_PINSWAP_1, PIN_HWSERIAL1_TX_PINSWAP_1, HWSERIAL1_DRE_VECTOR_NUM, HWSERIAL1_MUX, HWSERIAL1_MUX_PINSWAP_1);
#endif
// Function that can be weakly referenced by serialEventRun to prevent
// pulling in this file if it's not otherwise used.
-bool Serial1_available() {
+bool Serial1_available()
+{
return Serial1.available();
}
diff --git a/megaavr/cores/coreX-corefiles/UART2.cpp b/megaavr/cores/coreX-corefiles/UART2.cpp
index 4fc9940..203f0a3 100644
--- a/megaavr/cores/coreX-corefiles/UART2.cpp
+++ b/megaavr/cores/coreX-corefiles/UART2.cpp
@@ -55,12 +55,13 @@ ISR(HWSERIAL2_DRE_VECTOR)
#endif
#if defined(HWSERIAL2)
- UartClass Serial2(HWSERIAL2, PIN_WIRE_HWSERIAL2_RX, PIN_WIRE_HWSERIAL2_TX, PIN_WIRE_HWSERIAL2_RX_PINSWAP_1, PIN_WIRE_HWSERIAL2_TX_PINSWAP_1, HWSERIAL2_DRE_VECTOR_NUM, HWSERIAL2_MUX, HWSERIAL2_MUX_PINSWAP_1);
+UartClass Serial2(HWSERIAL2, PIN_HWSERIAL2_RX, PIN_HWSERIAL2_TX, PIN_HWSERIAL2_RX_PINSWAP_1, PIN_HWSERIAL2_TX_PINSWAP_1, HWSERIAL2_DRE_VECTOR_NUM, HWSERIAL2_MUX, HWSERIAL2_MUX_PINSWAP_1);
#endif
// Function that can be weakly referenced by serialEventRun to prevent
// pulling in this file if it's not otherwise used.
-bool Serial2_available() {
+bool Serial2_available()
+{
return Serial2.available();
}
diff --git a/megaavr/cores/coreX-corefiles/UART3.cpp b/megaavr/cores/coreX-corefiles/UART3.cpp
index d6d60b8..6a12e55 100644
--- a/megaavr/cores/coreX-corefiles/UART3.cpp
+++ b/megaavr/cores/coreX-corefiles/UART3.cpp
@@ -55,12 +55,13 @@ ISR(HWSERIAL3_DRE_VECTOR)
#endif
#if defined(HWSERIAL3)
- UartClass Serial3(HWSERIAL3, PIN_WIRE_HWSERIAL3_RX, PIN_WIRE_HWSERIAL3_TX, PIN_WIRE_HWSERIAL3_RX_PINSWAP_1, PIN_WIRE_HWSERIAL3_TX_PINSWAP_1, HWSERIAL3_DRE_VECTOR_NUM, HWSERIAL3_MUX, HWSERIAL3_MUX_PINSWAP_1);
+UartClass Serial3(HWSERIAL3, PIN_HWSERIAL3_RX, PIN_HWSERIAL3_TX, PIN_HWSERIAL3_RX_PINSWAP_1, PIN_HWSERIAL3_TX_PINSWAP_1, HWSERIAL3_DRE_VECTOR_NUM, HWSERIAL3_MUX, HWSERIAL3_MUX_PINSWAP_1);
#endif
// Function that can be weakly referenced by serialEventRun to prevent
// pulling in this file if it's not otherwise used.
-bool Serial3_available() {
+bool Serial3_available()
+{
return Serial3.available();
}
diff --git a/megaavr/cores/coreX-corefiles/UART_private.h b/megaavr/cores/coreX-corefiles/UART_private.h
index a7b6664..72845eb 100644
--- a/megaavr/cores/coreX-corefiles/UART_private.h
+++ b/megaavr/cores/coreX-corefiles/UART_private.h
@@ -39,12 +39,10 @@ UartClass::UartClass(
volatile uint8_t uart_mux,
volatile uint8_t uart_mux_swap) :
_hwserial_module(hwserial_module),
- _hwserial_rx_pin(hwserial_rx_pin),
- _hwserial_tx_pin(hwserial_tx_pin),
- _hwserial_rx_pin_swap(hwserial_rx_pin_swap),
- _hwserial_tx_pin_swap(hwserial_tx_pin_swap),
- _uart_mux(uart_mux),
- _uart_mux_swap(uart_mux_swap),
+ _hw_set { { hwserial_rx_pin, hwserial_tx_pin, uart_mux },
+ { hwserial_rx_pin_swap, hwserial_tx_pin_swap, uart_mux_swap } },
+ _pin_set(0),
+ _written(false),
_rx_buffer_head(0), _rx_buffer_tail(0),
_tx_buffer_head(0), _tx_buffer_tail(0),
_hwserial_dre_interrupt_vect_num(hwserial_dre_interrupt_vect_num),
@@ -68,11 +66,14 @@ void UartClass::_rx_complete_irq(void)
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
- if (i != _rx_buffer_tail) {
+ if (i != _rx_buffer_tail)
+ {
_rx_buffer[_rx_buffer_head] = c;
_rx_buffer_head = i;
}
- } else {
+ }
+ else
+ {
// Parity error, read byte but discard it
(*_hwserial_module).RXDATAL;
}
diff --git a/megaavr/cores/coreX-corefiles/UNO_compat.h b/megaavr/cores/coreX-corefiles/UNO_compat.h
index 1aad58d..42f43c4 100644
--- a/megaavr/cores/coreX-corefiles/UNO_compat.h
+++ b/megaavr/cores/coreX-corefiles/UNO_compat.h
@@ -40,241 +40,296 @@
A5 PC5 PD5
*/
-#define PORTA_ARDUINO (*(PORT_t *) 0x0400) /* I/O Ports */
-#define PORTB_ARDUINO (*(PORT_t *) 0x0420) /* I/O Ports */
-#define PORTC_ARDUINO (*(PORT_t *) 0x0440) /* I/O Ports */
-#define PORTD_ARDUINO (*(PORT_t *) 0x0460) /* I/O Ports */
-#define PORTE_ARDUINO (*(PORT_t *) 0x0480) /* I/O Ports */
-#define PORTF_ARDUINO (*(PORT_t *) 0x04A0) /* I/O Ports */
+#define PORTA_ARDUINO (*(PORT_t*)0x0400) /* I/O Ports */
+#define PORTB_ARDUINO (*(PORT_t*)0x0420) /* I/O Ports */
+#define PORTC_ARDUINO (*(PORT_t*)0x0440) /* I/O Ports */
+#define PORTD_ARDUINO (*(PORT_t*)0x0460) /* I/O Ports */
+#define PORTE_ARDUINO (*(PORT_t*)0x0480) /* I/O Ports */
+#define PORTF_ARDUINO (*(PORT_t*)0x04A0) /* I/O Ports */
#undef PORTB
#undef PORTC
#undef PORTD
-#define SET_PORT_REGISTER(inPosition, port, position) if ((1 << inPosition) & (uint8_t)value) { port.OUTSET = (1 << position);}
-#define CLEAR_PORT_REGISTER(inPosition, port, position) if ((uint8_t)~(1 << inPosition) == (uint8_t)value) { port.OUTCLR = (1 << position);}
-#define SET_OR_CLEAR_PORT_REGISTER(inPosition, port, position) if ((uint8_t)~(1 << inPosition) & (uint8_t)value) { port.OUTSET = (1 << position); } else {port.OUTCLR = (1 << position); }
-
-#define SET_DIR_REGISTER(inPosition, port, position) if ((1 << inPosition) & (uint8_t)value) { port.DIRSET = (1 << position);}
-#define CLEAR_DIR_REGISTER(inPosition, port, position) if ((uint8_t)~(1 << inPosition) == (uint8_t)value) { port.DIRCLR = (1 << position);}
-#define SET_OR_CLEAR_DIR_REGISTER(inPosition, port, position) if ((uint8_t)~(1 << inPosition) & (uint8_t)value) { port.DIRSET = (1 << position); } else {port.DIRCLR = (1 << position); }
+#define SET_PORT_REGISTER(inPosition, port, position) \
+ if ((1 << inPosition) & (uint8_t)value) \
+ { \
+ port.OUTSET = (1 << position); \
+ }
+#define CLEAR_PORT_REGISTER(inPosition, port, position) \
+ if ((uint8_t) ~(1 << inPosition) == (uint8_t)value) \
+ { \
+ port.OUTCLR = (1 << position); \
+ }
+#define SET_OR_CLEAR_PORT_REGISTER(inPosition, port, position) \
+ if ((uint8_t) ~(1 << inPosition) & (uint8_t)value) \
+ { \
+ port.OUTSET = (1 << position); \
+ } \
+ else \
+ { \
+ port.OUTCLR = (1 << position); \
+ }
+#define SET_DIR_REGISTER(inPosition, port, position) \
+ if ((1 << inPosition) & (uint8_t)value) \
+ { \
+ port.DIRSET = (1 << position); \
+ }
+#define CLEAR_DIR_REGISTER(inPosition, port, position) \
+ if ((uint8_t) ~(1 << inPosition) == (uint8_t)value) \
+ { \
+ port.DIRCLR = (1 << position); \
+ }
+#define SET_OR_CLEAR_DIR_REGISTER(inPosition, port, position) \
+ if ((uint8_t) ~(1 << inPosition) & (uint8_t)value) \
+ { \
+ port.DIRSET = (1 << position); \
+ } \
+ else \
+ { \
+ port.DIRCLR = (1 << position); \
+ }
/** DDR Classes**/
-class DDRBClass {
- public:
- DDRBClass() {}
- DDRBClass& operator=(uint8_t value) {
- SET_OR_CLEAR_DIR_REGISTER(0, PORTE_ARDUINO, 3);
- SET_OR_CLEAR_DIR_REGISTER(1, PORTB_ARDUINO, 0);
- SET_OR_CLEAR_DIR_REGISTER(2, PORTB_ARDUINO, 1);
- SET_OR_CLEAR_DIR_REGISTER(3, PORTE_ARDUINO, 0);
- SET_OR_CLEAR_DIR_REGISTER(4, PORTE_ARDUINO, 1);
- SET_OR_CLEAR_DIR_REGISTER(5, PORTE_ARDUINO, 2);
- return *this;
- }
+class DDRBClass
+{
+ public:
+ DDRBClass() {}
+ DDRBClass& operator=(uint8_t value)
+ {
+ SET_OR_CLEAR_DIR_REGISTER(0, PORTE_ARDUINO, 3);
+ SET_OR_CLEAR_DIR_REGISTER(1, PORTB_ARDUINO, 0);
+ SET_OR_CLEAR_DIR_REGISTER(2, PORTB_ARDUINO, 1);
+ SET_OR_CLEAR_DIR_REGISTER(3, PORTE_ARDUINO, 0);
+ SET_OR_CLEAR_DIR_REGISTER(4, PORTE_ARDUINO, 1);
+ SET_OR_CLEAR_DIR_REGISTER(5, PORTE_ARDUINO, 2);
+ return *this;
+ }
- DDRBClass& operator&=(uint8_t value) {
- CLEAR_DIR_REGISTER(0, PORTE_ARDUINO, 3);
- CLEAR_DIR_REGISTER(1, PORTB_ARDUINO, 0);
- CLEAR_DIR_REGISTER(2, PORTB_ARDUINO, 1);
- CLEAR_DIR_REGISTER(3, PORTE_ARDUINO, 0);
- CLEAR_DIR_REGISTER(4, PORTE_ARDUINO, 1);
- CLEAR_DIR_REGISTER(5, PORTE_ARDUINO, 2);
- return *this;
- }
+ DDRBClass& operator&=(uint8_t value)
+ {
+ CLEAR_DIR_REGISTER(0, PORTE_ARDUINO, 3);
+ CLEAR_DIR_REGISTER(1, PORTB_ARDUINO, 0);
+ CLEAR_DIR_REGISTER(2, PORTB_ARDUINO, 1);
+ CLEAR_DIR_REGISTER(3, PORTE_ARDUINO, 0);
+ CLEAR_DIR_REGISTER(4, PORTE_ARDUINO, 1);
+ CLEAR_DIR_REGISTER(5, PORTE_ARDUINO, 2);
+ return *this;
+ }
- DDRBClass& operator|=(uint8_t value) {
- SET_DIR_REGISTER(0, PORTE_ARDUINO, 3);
- SET_DIR_REGISTER(1, PORTB_ARDUINO, 0);
- SET_DIR_REGISTER(2, PORTB_ARDUINO, 1);
- SET_DIR_REGISTER(3, PORTE_ARDUINO, 0);
- SET_DIR_REGISTER(4, PORTE_ARDUINO, 1);
- SET_DIR_REGISTER(5, PORTE_ARDUINO, 2);
- return *this;
- }
+ DDRBClass& operator|=(uint8_t value)
+ {
+ SET_DIR_REGISTER(0, PORTE_ARDUINO, 3);
+ SET_DIR_REGISTER(1, PORTB_ARDUINO, 0);
+ SET_DIR_REGISTER(2, PORTB_ARDUINO, 1);
+ SET_DIR_REGISTER(3, PORTE_ARDUINO, 0);
+ SET_DIR_REGISTER(4, PORTE_ARDUINO, 1);
+ SET_DIR_REGISTER(5, PORTE_ARDUINO, 2);
+ return *this;
+ }
};
-class DDRCClass {
- public:
- DDRCClass() {}
- DDRCClass& operator=(uint8_t value) {
- SET_OR_CLEAR_DIR_REGISTER(0, PORTD_ARDUINO, 0);
- SET_OR_CLEAR_DIR_REGISTER(1, PORTD_ARDUINO, 1);
- SET_OR_CLEAR_DIR_REGISTER(2, PORTD_ARDUINO, 2);
- SET_OR_CLEAR_DIR_REGISTER(3, PORTD_ARDUINO, 3);
- SET_OR_CLEAR_DIR_REGISTER(4, PORTD_ARDUINO, 4);
- SET_OR_CLEAR_DIR_REGISTER(5, PORTD_ARDUINO, 5);
- return *this;
- }
+class DDRCClass
+{
+ public:
+ DDRCClass() {}
+ DDRCClass& operator=(uint8_t value)
+ {
+ SET_OR_CLEAR_DIR_REGISTER(0, PORTD_ARDUINO, 0);
+ SET_OR_CLEAR_DIR_REGISTER(1, PORTD_ARDUINO, 1);
+ SET_OR_CLEAR_DIR_REGISTER(2, PORTD_ARDUINO, 2);
+ SET_OR_CLEAR_DIR_REGISTER(3, PORTD_ARDUINO, 3);
+ SET_OR_CLEAR_DIR_REGISTER(4, PORTD_ARDUINO, 4);
+ SET_OR_CLEAR_DIR_REGISTER(5, PORTD_ARDUINO, 5);
+ return *this;
+ }
- DDRCClass& operator&=(uint8_t value) {
- CLEAR_DIR_REGISTER(0, PORTD_ARDUINO, 0);
- CLEAR_DIR_REGISTER(1, PORTD_ARDUINO, 1);
- CLEAR_DIR_REGISTER(2, PORTD_ARDUINO, 2);
- CLEAR_DIR_REGISTER(3, PORTD_ARDUINO, 3);
- CLEAR_DIR_REGISTER(4, PORTD_ARDUINO, 4);
- CLEAR_DIR_REGISTER(5, PORTD_ARDUINO, 5);
- return *this;
- }
+ DDRCClass& operator&=(uint8_t value)
+ {
+ CLEAR_DIR_REGISTER(0, PORTD_ARDUINO, 0);
+ CLEAR_DIR_REGISTER(1, PORTD_ARDUINO, 1);
+ CLEAR_DIR_REGISTER(2, PORTD_ARDUINO, 2);
+ CLEAR_DIR_REGISTER(3, PORTD_ARDUINO, 3);
+ CLEAR_DIR_REGISTER(4, PORTD_ARDUINO, 4);
+ CLEAR_DIR_REGISTER(5, PORTD_ARDUINO, 5);
+ return *this;
+ }
- DDRCClass& operator|=(uint8_t value) {
- SET_DIR_REGISTER(0, PORTD_ARDUINO, 0);
- SET_DIR_REGISTER(1, PORTD_ARDUINO, 1);
- SET_DIR_REGISTER(2, PORTD_ARDUINO, 2);
- SET_DIR_REGISTER(3, PORTD_ARDUINO, 3);
- SET_DIR_REGISTER(4, PORTD_ARDUINO, 4);
- SET_DIR_REGISTER(5, PORTD_ARDUINO, 5);
- return *this;
- }
+ DDRCClass& operator|=(uint8_t value)
+ {
+ SET_DIR_REGISTER(0, PORTD_ARDUINO, 0);
+ SET_DIR_REGISTER(1, PORTD_ARDUINO, 1);
+ SET_DIR_REGISTER(2, PORTD_ARDUINO, 2);
+ SET_DIR_REGISTER(3, PORTD_ARDUINO, 3);
+ SET_DIR_REGISTER(4, PORTD_ARDUINO, 4);
+ SET_DIR_REGISTER(5, PORTD_ARDUINO, 5);
+ return *this;
+ }
};
-class DDRDClass {
- public:
- DDRDClass() {}
- DDRDClass& operator=(uint8_t value) {
- SET_OR_CLEAR_DIR_REGISTER(0, PORTC_ARDUINO, 5);
- SET_OR_CLEAR_DIR_REGISTER(1, PORTC_ARDUINO, 4);
- SET_OR_CLEAR_DIR_REGISTER(2, PORTA_ARDUINO, 0);
- SET_OR_CLEAR_DIR_REGISTER(3, PORTF_ARDUINO, 5);
- SET_OR_CLEAR_DIR_REGISTER(4, PORTC_ARDUINO, 6);
- SET_OR_CLEAR_DIR_REGISTER(5, PORTB_ARDUINO, 2);
- SET_OR_CLEAR_DIR_REGISTER(6, PORTF_ARDUINO, 4);
- SET_OR_CLEAR_DIR_REGISTER(7, PORTA_ARDUINO, 1);
- return *this;
- }
+class DDRDClass
+{
+ public:
+ DDRDClass() {}
+ DDRDClass& operator=(uint8_t value)
+ {
+ SET_OR_CLEAR_DIR_REGISTER(0, PORTC_ARDUINO, 5);
+ SET_OR_CLEAR_DIR_REGISTER(1, PORTC_ARDUINO, 4);
+ SET_OR_CLEAR_DIR_REGISTER(2, PORTA_ARDUINO, 0);
+ SET_OR_CLEAR_DIR_REGISTER(3, PORTF_ARDUINO, 5);
+ SET_OR_CLEAR_DIR_REGISTER(4, PORTC_ARDUINO, 6);
+ SET_OR_CLEAR_DIR_REGISTER(5, PORTB_ARDUINO, 2);
+ SET_OR_CLEAR_DIR_REGISTER(6, PORTF_ARDUINO, 4);
+ SET_OR_CLEAR_DIR_REGISTER(7, PORTA_ARDUINO, 1);
+ return *this;
+ }
- DDRDClass& operator&=(uint8_t value) {
- CLEAR_DIR_REGISTER(0, PORTC_ARDUINO, 5);
- CLEAR_DIR_REGISTER(1, PORTC_ARDUINO, 4);
- CLEAR_DIR_REGISTER(2, PORTA_ARDUINO, 0);
- CLEAR_DIR_REGISTER(3, PORTF_ARDUINO, 5);
- CLEAR_DIR_REGISTER(4, PORTC_ARDUINO, 6);
- CLEAR_DIR_REGISTER(5, PORTB_ARDUINO, 2);
- CLEAR_DIR_REGISTER(6, PORTF_ARDUINO, 4);
- CLEAR_DIR_REGISTER(7, PORTA_ARDUINO, 1);
- return *this;
- }
+ DDRDClass& operator&=(uint8_t value)
+ {
+ CLEAR_DIR_REGISTER(0, PORTC_ARDUINO, 5);
+ CLEAR_DIR_REGISTER(1, PORTC_ARDUINO, 4);
+ CLEAR_DIR_REGISTER(2, PORTA_ARDUINO, 0);
+ CLEAR_DIR_REGISTER(3, PORTF_ARDUINO, 5);
+ CLEAR_DIR_REGISTER(4, PORTC_ARDUINO, 6);
+ CLEAR_DIR_REGISTER(5, PORTB_ARDUINO, 2);
+ CLEAR_DIR_REGISTER(6, PORTF_ARDUINO, 4);
+ CLEAR_DIR_REGISTER(7, PORTA_ARDUINO, 1);
+ return *this;
+ }
- DDRDClass& operator|=(uint8_t value) {
- SET_DIR_REGISTER(0, PORTC_ARDUINO, 5);
- SET_DIR_REGISTER(1, PORTC_ARDUINO, 4);
- SET_DIR_REGISTER(2, PORTA_ARDUINO, 0);
- SET_DIR_REGISTER(3, PORTF_ARDUINO, 5);
- SET_DIR_REGISTER(4, PORTC_ARDUINO, 6);
- SET_DIR_REGISTER(5, PORTB_ARDUINO, 2);
- SET_DIR_REGISTER(6, PORTF_ARDUINO, 4);
- SET_DIR_REGISTER(7, PORTA_ARDUINO, 1);
- return *this;
- }
+ DDRDClass& operator|=(uint8_t value)
+ {
+ SET_DIR_REGISTER(0, PORTC_ARDUINO, 5);
+ SET_DIR_REGISTER(1, PORTC_ARDUINO, 4);
+ SET_DIR_REGISTER(2, PORTA_ARDUINO, 0);
+ SET_DIR_REGISTER(3, PORTF_ARDUINO, 5);
+ SET_DIR_REGISTER(4, PORTC_ARDUINO, 6);
+ SET_DIR_REGISTER(5, PORTB_ARDUINO, 2);
+ SET_DIR_REGISTER(6, PORTF_ARDUINO, 4);
+ SET_DIR_REGISTER(7, PORTA_ARDUINO, 1);
+ return *this;
+ }
};
/** PORT Classes**/
-class PORTBClass {
- public:
- PORTBClass() {}
- PORTBClass& operator=(uint8_t value) {
- SET_OR_CLEAR_PORT_REGISTER(0, PORTE_ARDUINO, 3);
- SET_OR_CLEAR_PORT_REGISTER(1, PORTB_ARDUINO, 0);
- SET_OR_CLEAR_PORT_REGISTER(2, PORTB_ARDUINO, 1);
- SET_OR_CLEAR_PORT_REGISTER(3, PORTE_ARDUINO, 0);
- SET_OR_CLEAR_PORT_REGISTER(4, PORTE_ARDUINO, 1);
- SET_OR_CLEAR_PORT_REGISTER(5, PORTE_ARDUINO, 2);
- return *this;
- }
+class PORTBClass
+{
+ public:
+ PORTBClass() {}
+ PORTBClass& operator=(uint8_t value)
+ {
+ SET_OR_CLEAR_PORT_REGISTER(0, PORTE_ARDUINO, 3);
+ SET_OR_CLEAR_PORT_REGISTER(1, PORTB_ARDUINO, 0);
+ SET_OR_CLEAR_PORT_REGISTER(2, PORTB_ARDUINO, 1);
+ SET_OR_CLEAR_PORT_REGISTER(3, PORTE_ARDUINO, 0);
+ SET_OR_CLEAR_PORT_REGISTER(4, PORTE_ARDUINO, 1);
+ SET_OR_CLEAR_PORT_REGISTER(5, PORTE_ARDUINO, 2);
+ return *this;
+ }
- PORTBClass& operator&=(uint8_t value) {
- CLEAR_PORT_REGISTER(0, PORTE_ARDUINO, 3);
- CLEAR_PORT_REGISTER(1, PORTB_ARDUINO, 0);
- CLEAR_PORT_REGISTER(2, PORTB_ARDUINO, 1);
- CLEAR_PORT_REGISTER(3, PORTE_ARDUINO, 0);
- CLEAR_PORT_REGISTER(4, PORTE_ARDUINO, 1);
- CLEAR_PORT_REGISTER(5, PORTE_ARDUINO, 2);
- return *this;
- }
+ PORTBClass& operator&=(uint8_t value)
+ {
+ CLEAR_PORT_REGISTER(0, PORTE_ARDUINO, 3);
+ CLEAR_PORT_REGISTER(1, PORTB_ARDUINO, 0);
+ CLEAR_PORT_REGISTER(2, PORTB_ARDUINO, 1);
+ CLEAR_PORT_REGISTER(3, PORTE_ARDUINO, 0);
+ CLEAR_PORT_REGISTER(4, PORTE_ARDUINO, 1);
+ CLEAR_PORT_REGISTER(5, PORTE_ARDUINO, 2);
+ return *this;
+ }
- PORTBClass& operator|=(uint8_t value) {
- SET_PORT_REGISTER(0, PORTE_ARDUINO, 3);
- SET_PORT_REGISTER(1, PORTB_ARDUINO, 0);
- SET_PORT_REGISTER(2, PORTB_ARDUINO, 1);
- SET_PORT_REGISTER(3, PORTE_ARDUINO, 0);
- SET_PORT_REGISTER(4, PORTE_ARDUINO, 1);
- SET_PORT_REGISTER(5, PORTE_ARDUINO, 2);
- return *this;
- }
+ PORTBClass& operator|=(uint8_t value)
+ {
+ SET_PORT_REGISTER(0, PORTE_ARDUINO, 3);
+ SET_PORT_REGISTER(1, PORTB_ARDUINO, 0);
+ SET_PORT_REGISTER(2, PORTB_ARDUINO, 1);
+ SET_PORT_REGISTER(3, PORTE_ARDUINO, 0);
+ SET_PORT_REGISTER(4, PORTE_ARDUINO, 1);
+ SET_PORT_REGISTER(5, PORTE_ARDUINO, 2);
+ return *this;
+ }
};
-class PORTCClass {
- public:
- PORTCClass() {}
- PORTCClass& operator=(uint8_t value) {
- SET_OR_CLEAR_PORT_REGISTER(0, PORTD_ARDUINO, 0);
- SET_OR_CLEAR_PORT_REGISTER(1, PORTD_ARDUINO, 1);
- SET_OR_CLEAR_PORT_REGISTER(2, PORTD_ARDUINO, 2);
- SET_OR_CLEAR_PORT_REGISTER(3, PORTD_ARDUINO, 3);
- SET_OR_CLEAR_PORT_REGISTER(4, PORTD_ARDUINO, 4);
- SET_OR_CLEAR_PORT_REGISTER(5, PORTD_ARDUINO, 5);
- return *this;
- }
+class PORTCClass
+{
+ public:
+ PORTCClass() {}
+ PORTCClass& operator=(uint8_t value)
+ {
+ SET_OR_CLEAR_PORT_REGISTER(0, PORTD_ARDUINO, 0);
+ SET_OR_CLEAR_PORT_REGISTER(1, PORTD_ARDUINO, 1);
+ SET_OR_CLEAR_PORT_REGISTER(2, PORTD_ARDUINO, 2);
+ SET_OR_CLEAR_PORT_REGISTER(3, PORTD_ARDUINO, 3);
+ SET_OR_CLEAR_PORT_REGISTER(4, PORTD_ARDUINO, 4);
+ SET_OR_CLEAR_PORT_REGISTER(5, PORTD_ARDUINO, 5);
+ return *this;
+ }
- PORTCClass& operator&=(uint8_t value) {
- CLEAR_PORT_REGISTER(0, PORTD_ARDUINO, 0);
- CLEAR_PORT_REGISTER(1, PORTD_ARDUINO, 1);
- CLEAR_PORT_REGISTER(2, PORTD_ARDUINO, 2);
- CLEAR_PORT_REGISTER(3, PORTD_ARDUINO, 3);
- CLEAR_PORT_REGISTER(4, PORTD_ARDUINO, 4);
- CLEAR_PORT_REGISTER(5, PORTD_ARDUINO, 5);
- return *this;
- }
+ PORTCClass& operator&=(uint8_t value)
+ {
+ CLEAR_PORT_REGISTER(0, PORTD_ARDUINO, 0);
+ CLEAR_PORT_REGISTER(1, PORTD_ARDUINO, 1);
+ CLEAR_PORT_REGISTER(2, PORTD_ARDUINO, 2);
+ CLEAR_PORT_REGISTER(3, PORTD_ARDUINO, 3);
+ CLEAR_PORT_REGISTER(4, PORTD_ARDUINO, 4);
+ CLEAR_PORT_REGISTER(5, PORTD_ARDUINO, 5);
+ return *this;
+ }
- PORTCClass& operator|=(uint8_t value) {
- SET_PORT_REGISTER(0, PORTD_ARDUINO, 0);
- SET_PORT_REGISTER(1, PORTD_ARDUINO, 1);
- SET_PORT_REGISTER(2, PORTD_ARDUINO, 2);
- SET_PORT_REGISTER(3, PORTD_ARDUINO, 3);
- SET_PORT_REGISTER(4, PORTD_ARDUINO, 4);
- SET_PORT_REGISTER(5, PORTD_ARDUINO, 5);
- return *this;
- }
+ PORTCClass& operator|=(uint8_t value)
+ {
+ SET_PORT_REGISTER(0, PORTD_ARDUINO, 0);
+ SET_PORT_REGISTER(1, PORTD_ARDUINO, 1);
+ SET_PORT_REGISTER(2, PORTD_ARDUINO, 2);
+ SET_PORT_REGISTER(3, PORTD_ARDUINO, 3);
+ SET_PORT_REGISTER(4, PORTD_ARDUINO, 4);
+ SET_PORT_REGISTER(5, PORTD_ARDUINO, 5);
+ return *this;
+ }
};
-class PORTDClass {
- public:
- PORTDClass() {}
- PORTDClass& operator=(uint8_t value) {
- SET_OR_CLEAR_PORT_REGISTER(0, PORTC_ARDUINO, 5);
- SET_OR_CLEAR_PORT_REGISTER(1, PORTC_ARDUINO, 4);
- SET_OR_CLEAR_PORT_REGISTER(2, PORTA_ARDUINO, 0);
- SET_OR_CLEAR_PORT_REGISTER(3, PORTF_ARDUINO, 5);
- SET_OR_CLEAR_PORT_REGISTER(4, PORTC_ARDUINO, 6);
- SET_OR_CLEAR_PORT_REGISTER(5, PORTB_ARDUINO, 2);
- SET_OR_CLEAR_PORT_REGISTER(6, PORTF_ARDUINO, 4);
- SET_OR_CLEAR_PORT_REGISTER(7, PORTA_ARDUINO, 1);
- return *this;
- }
+class PORTDClass
+{
+ public:
+ PORTDClass() {}
+ PORTDClass& operator=(uint8_t value)
+ {
+ SET_OR_CLEAR_PORT_REGISTER(0, PORTC_ARDUINO, 5);
+ SET_OR_CLEAR_PORT_REGISTER(1, PORTC_ARDUINO, 4);
+ SET_OR_CLEAR_PORT_REGISTER(2, PORTA_ARDUINO, 0);
+ SET_OR_CLEAR_PORT_REGISTER(3, PORTF_ARDUINO, 5);
+ SET_OR_CLEAR_PORT_REGISTER(4, PORTC_ARDUINO, 6);
+ SET_OR_CLEAR_PORT_REGISTER(5, PORTB_ARDUINO, 2);
+ SET_OR_CLEAR_PORT_REGISTER(6, PORTF_ARDUINO, 4);
+ SET_OR_CLEAR_PORT_REGISTER(7, PORTA_ARDUINO, 1);
+ return *this;
+ }
- PORTDClass& operator&=(uint8_t value) {
- CLEAR_PORT_REGISTER(0, PORTC_ARDUINO, 5);
- CLEAR_PORT_REGISTER(1, PORTC_ARDUINO, 4);
- CLEAR_PORT_REGISTER(2, PORTA_ARDUINO, 0);
- CLEAR_PORT_REGISTER(3, PORTF_ARDUINO, 5);
- CLEAR_PORT_REGISTER(4, PORTC_ARDUINO, 6);
- CLEAR_PORT_REGISTER(5, PORTB_ARDUINO, 2);
- CLEAR_PORT_REGISTER(6, PORTF_ARDUINO, 4);
- CLEAR_PORT_REGISTER(7, PORTA_ARDUINO, 1);
- return *this;
- }
+ PORTDClass& operator&=(uint8_t value)
+ {
+ CLEAR_PORT_REGISTER(0, PORTC_ARDUINO, 5);
+ CLEAR_PORT_REGISTER(1, PORTC_ARDUINO, 4);
+ CLEAR_PORT_REGISTER(2, PORTA_ARDUINO, 0);
+ CLEAR_PORT_REGISTER(3, PORTF_ARDUINO, 5);
+ CLEAR_PORT_REGISTER(4, PORTC_ARDUINO, 6);
+ CLEAR_PORT_REGISTER(5, PORTB_ARDUINO, 2);
+ CLEAR_PORT_REGISTER(6, PORTF_ARDUINO, 4);
+ CLEAR_PORT_REGISTER(7, PORTA_ARDUINO, 1);
+ return *this;
+ }
- PORTDClass& operator|=(uint8_t value) {
- SET_PORT_REGISTER(0, PORTC_ARDUINO, 5);
- SET_PORT_REGISTER(1, PORTC_ARDUINO, 4);
- SET_PORT_REGISTER(2, PORTA_ARDUINO, 0);
- SET_PORT_REGISTER(3, PORTF_ARDUINO, 5);
- SET_PORT_REGISTER(4, PORTC_ARDUINO, 6);
- SET_PORT_REGISTER(5, PORTB_ARDUINO, 2);
- SET_PORT_REGISTER(6, PORTF_ARDUINO, 4);
- SET_PORT_REGISTER(7, PORTA_ARDUINO, 1);
- return *this;
- }
+ PORTDClass& operator|=(uint8_t value)
+ {
+ SET_PORT_REGISTER(0, PORTC_ARDUINO, 5);
+ SET_PORT_REGISTER(1, PORTC_ARDUINO, 4);
+ SET_PORT_REGISTER(2, PORTA_ARDUINO, 0);
+ SET_PORT_REGISTER(3, PORTF_ARDUINO, 5);
+ SET_PORT_REGISTER(4, PORTC_ARDUINO, 6);
+ SET_PORT_REGISTER(5, PORTB_ARDUINO, 2);
+ SET_PORT_REGISTER(6, PORTF_ARDUINO, 4);
+ SET_PORT_REGISTER(7, PORTA_ARDUINO, 1);
+ return *this;
+ }
};
extern PORTBClass PORTB;
diff --git a/megaavr/cores/coreX-corefiles/USBCore.cpp b/megaavr/cores/coreX-corefiles/USBCore.cpp
index e6ee84a..a20ce0a 100644
--- a/megaavr/cores/coreX-corefiles/USBCore.cpp
+++ b/megaavr/cores/coreX-corefiles/USBCore.cpp
@@ -17,12 +17,14 @@
** SOFTWARE.
*/
+#include "USBCore.h"
+
+#include
+
#include "Arduino.h"
-#include "api/USBAPI.h"
#include "api/PluggableUSB.h"
-#include "USBCore.h"
+#include "api/USBAPI.h"
#include "pins_arduino.h"
-#include
#if defined(USBCON)
@@ -40,152 +42,151 @@ extern const uint8_t STRING_MANUFACTURER[] PROGMEM;
extern const DeviceDescriptor USB_DeviceDescriptorIAD PROGMEM;
const uint16_t STRING_LANGUAGE[2] = {
- (3<<8) | (2+2),
- 0x0409 // English
+ (3 << 8) | (2 + 2),
+ 0x0409 // English
};
#ifndef USB_PRODUCT
// If no product is provided, use USB IO Board
-#define USB_PRODUCT "USB IO Board"
+#define USB_PRODUCT "USB IO Board"
#endif
const uint8_t STRING_PRODUCT[] PROGMEM = USB_PRODUCT;
#if USB_VID == 0x2341
-# if defined(USB_MANUFACTURER)
-# undef USB_MANUFACTURER
-# endif
-# define USB_MANUFACTURER "Arduino LLC"
+#if defined(USB_MANUFACTURER)
+#undef USB_MANUFACTURER
+#endif
+#define USB_MANUFACTURER "Arduino LLC"
#elif USB_VID == 0x1b4f
-# if defined(USB_MANUFACTURER)
-# undef USB_MANUFACTURER
-# endif
-# define USB_MANUFACTURER "SparkFun"
+#if defined(USB_MANUFACTURER)
+#undef USB_MANUFACTURER
+#endif
+#define USB_MANUFACTURER "SparkFun"
#elif !defined(USB_MANUFACTURER)
// Fall through to unknown if no manufacturer name was provided in a macro
-# define USB_MANUFACTURER "Unknown"
+#define USB_MANUFACTURER "Unknown"
#endif
const uint8_t STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER;
-
#define DEVICE_CLASS 0x02
-// DEVICE DESCRIPTOR
+// DEVICE DESCRIPTOR
const DeviceDescriptor USB_DeviceDescriptorIAD =
- D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,ISERIAL,1);
+ D_DEVICE(0xEF, 0x02, 0x01, 64, USB_VID, USB_PID, 0x100, IMANUFACTURER, IPRODUCT, ISERIAL, 1);
//==================================================================
//==================================================================
volatile uint8_t _usbConfiguration = 0;
volatile uint8_t _usbCurrentStatus = 0; // meaning of bits see usb_20.pdf, Figure 9-4. Information Returned by a GetStatus() Request to a Device
-volatile uint8_t _usbSuspendState = 0; // copy of UDINT to check SUSPI and WAKEUPI bits
+volatile uint8_t _usbSuspendState = 0; // copy of UDINT to check SUSPI and WAKEUPI bits
static inline void WaitIN(void)
{
- while (!(UEINTX & (1< len) {
- n = len;
- }
-
- {
- LockEP lock(ep);
- // Frame may have been released by the SOF interrupt handler
- if (!ReadWriteAllowed())
- continue;
-
- len -= n;
- if (ep & TRANSFER_ZERO)
- {
- while (n--)
- Send8(0);
- }
- else if (ep & TRANSFER_PGM)
- {
- while (n--)
- Send8(pgm_read_byte(data++));
- }
- else
- {
- while (n--)
- Send8(*data++);
- }
-
- if (sendZlp) {
- ReleaseTX();
- sendZlp = false;
- } else if (!ReadWriteAllowed()) { // ...release if buffer is full...
- ReleaseTX();
- if (len == 0) sendZlp = true;
- } else if ((len == 0) && (ep & TRANSFER_RELEASE)) { // ...or if forced with TRANSFER_RELEASE
- // XXX: TRANSFER_RELEASE is never used can be removed?
- ReleaseTX();
- }
- }
- }
- TXLED1; // light the TX LED
- TxLEDPulse = TX_RX_LED_PULSE_MS;
- return r;
+ if (!_usbConfiguration)
+ return -1;
+
+ if (_usbSuspendState & (1 << SUSPI))
+ {
+ //send a remote wakeup
+ UDCON |= (1 << RMWKUP);
+ }
+
+ int r = len;
+ const uint8_t* data = (const uint8_t*)d;
+ uint8_t timeout = 250; // 250ms timeout on send? TODO
+ bool sendZlp = false;
+
+ while (len || sendZlp)
+ {
+ uint8_t n = USB_SendSpace(ep);
+ if (n == 0)
+ {
+ if (!(--timeout))
+ return -1;
+ delay(1);
+ continue;
+ }
+
+ if (n > len)
+ {
+ n = len;
+ }
+
+ {
+ LockEP lock(ep);
+ // Frame may have been released by the SOF interrupt handler
+ if (!ReadWriteAllowed())
+ continue;
+
+ len -= n;
+ if (ep & TRANSFER_ZERO)
+ {
+ while (n--)
+ Send8(0);
+ }
+ else if (ep & TRANSFER_PGM)
+ {
+ while (n--)
+ Send8(pgm_read_byte(data++));
+ }
+ else
+ {
+ while (n--)
+ Send8(*data++);
+ }
+
+ if (sendZlp)
+ {
+ ReleaseTX();
+ sendZlp = false;
+ }
+ else if (!ReadWriteAllowed())
+ { // ...release if buffer is full...
+ ReleaseTX();
+ if (len == 0) sendZlp = true;
+ }
+ else if ((len == 0) && (ep & TRANSFER_RELEASE))
+ { // ...or if forced with TRANSFER_RELEASE
+ // XXX: TRANSFER_RELEASE is never used can be removed?
+ ReleaseTX();
+ }
+ }
+ }
+ TXLED1; // light the TX LED
+ TxLEDPulse = TX_RX_LED_PULSE_MS;
+ return r;
}
uint16_t _initEndpoints[USB_ENDPOINTS] =
-{
- 0, // Control Endpoint
-
- EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
- EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
- EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
+ {
+ 0, // Control Endpoint
+
+ EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
+ EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
+ EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
- // Following endpoints are automatically initialized to 0
+ // Following endpoints are automatically initialized to 0
};
-#define EP_SINGLE_64 0x32 // EP0
-#define EP_DOUBLE_64 0x36 // Other endpoints
+#define EP_SINGLE_64 0x32 // EP0
+#define EP_DOUBLE_64 0x36 // Other endpoints
#define EP_SINGLE_16 0x12
-void* epBuffer(unsigned int lastEp) {
- return &(_initEndpoints[lastEp]);
+void* epBuffer(unsigned int lastEp)
+{
+ return &(_initEndpoints[lastEp]);
}
-static
-void InitEP(uint8_t index, uint8_t type, uint8_t size)
+static void InitEP(uint8_t index, uint8_t type, uint8_t size)
{
- UENUM = index;
- UECONX = (1< 64){
- recvLength = 64;
- }
-
- // Write data to fit to the end (not the beginning) of the array
- WaitOUT();
- Recv((uint8_t*)d + len - length, recvLength);
- ClearOUT();
- length -= recvLength;
- }
- return len;
+ auto length = len;
+ while (length)
+ {
+ // Dont receive more than the USB Control EP has to offer
+ // Use fixed 64 because control EP always have 64 bytes even on 16u2.
+ auto recvLength = length;
+ if (recvLength > 64)
+ {
+ recvLength = 64;
+ }
+
+ // Write data to fit to the end (not the beginning) of the array
+ WaitOUT();
+ Recv((uint8_t*)d + len - length, recvLength);
+ ClearOUT();
+ length -= recvLength;
+ }
+ return len;
}
static uint8_t SendInterfaces()
{
- uint8_t interfaces = 0;
+ uint8_t interfaces = 0;
- CDC_GetInterface(&interfaces);
+ CDC_GetInterface(&interfaces);
#ifdef PLUGGABLE_USB_ENABLED
- PluggableUSB().getInterface(&interfaces);
+ PluggableUSB().getInterface(&interfaces);
#endif
- return interfaces;
+ return interfaces;
}
-// Construct a dynamic configuration descriptor
-// This really needs dynamic endpoint allocation etc
-// TODO
-static
-bool SendConfiguration(int maxlen)
+// Construct a dynamic configuration descriptor
+// This really needs dynamic endpoint allocation etc
+// TODO
+static bool SendConfiguration(int maxlen)
{
- // Count and measure interfaces
- InitControl(0);
- uint8_t interfaces = SendInterfaces();
- ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
+ // Count and measure interfaces
+ InitControl(0);
+ uint8_t interfaces = SendInterfaces();
+ ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor), interfaces);
- // Now send them
- InitControl(maxlen);
- USB_SendControl(0,&config,sizeof(ConfigDescriptor));
- SendInterfaces();
- return true;
+ // Now send them
+ InitControl(maxlen);
+ USB_SendControl(0, &config, sizeof(ConfigDescriptor));
+ SendInterfaces();
+ return true;
}
-static
-bool SendDescriptor(USBSetup& setup)
+static bool SendDescriptor(USBSetup& setup)
{
- int ret;
- uint8_t t = setup.wValueH;
- if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
- return SendConfiguration(setup.wLength);
+ int ret;
+ uint8_t t = setup.wValueH;
+ if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
+ return SendConfiguration(setup.wLength);
- InitControl(setup.wLength);
+ InitControl(setup.wLength);
#ifdef PLUGGABLE_USB_ENABLED
- ret = PluggableUSB().getDescriptor(setup);
- if (ret != 0) {
- return (ret > 0 ? true : false);
- }
+ ret = PluggableUSB().getDescriptor(setup);
+ if (ret != 0)
+ {
+ return (ret > 0 ? true : false);
+ }
#endif
- const uint8_t* desc_addr = 0;
- if (USB_DEVICE_DESCRIPTOR_TYPE == t)
- {
- desc_addr = (const uint8_t*)&USB_DeviceDescriptorIAD;
- }
- else if (USB_STRING_DESCRIPTOR_TYPE == t)
- {
- if (setup.wValueL == 0) {
- desc_addr = (const uint8_t*)&STRING_LANGUAGE;
- }
- else if (setup.wValueL == IPRODUCT) {
- return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM);
- }
- else if (setup.wValueL == IMANUFACTURER) {
- return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER), TRANSFER_PGM);
- }
- else if (setup.wValueL == ISERIAL) {
+ const uint8_t* desc_addr = 0;
+ if (USB_DEVICE_DESCRIPTOR_TYPE == t)
+ {
+ desc_addr = (const uint8_t*)&USB_DeviceDescriptorIAD;
+ }
+ else if (USB_STRING_DESCRIPTOR_TYPE == t)
+ {
+ if (setup.wValueL == 0)
+ {
+ desc_addr = (const uint8_t*)&STRING_LANGUAGE;
+ }
+ else if (setup.wValueL == IPRODUCT)
+ {
+ return USB_SendStringDescriptor(STRING_PRODUCT, strlen(USB_PRODUCT), TRANSFER_PGM);
+ }
+ else if (setup.wValueL == IMANUFACTURER)
+ {
+ return USB_SendStringDescriptor(STRING_MANUFACTURER, strlen(USB_MANUFACTURER), TRANSFER_PGM);
+ }
+ else if (setup.wValueL == ISERIAL)
+ {
#ifdef PLUGGABLE_USB_ENABLED
- char name[ISERIAL_MAX_LEN];
- PluggableUSB().getShortName(name);
- return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0);
+ char name[ISERIAL_MAX_LEN];
+ PluggableUSB().getShortName(name);
+ return USB_SendStringDescriptor((uint8_t*)name, strlen(name), 0);
#endif
- }
- else
- return false;
- }
+ }
+ else
+ return false;
+ }
- if (desc_addr == 0)
- return false;
- uint8_t desc_length = pgm_read_byte(desc_addr);
+ if (desc_addr == 0)
+ return false;
+ uint8_t desc_length = pgm_read_byte(desc_addr);
- USB_SendControl(TRANSFER_PGM,desc_addr,desc_length);
- return true;
+ USB_SendControl(TRANSFER_PGM, desc_addr, desc_length);
+ return true;
}
-// Endpoint 0 interrupt
+// Endpoint 0 interrupt
ISR(USB_COM_vect)
{
- SetEP(0);
- if (!ReceivedSetupInt())
- return;
-
- USBSetup setup;
- Recv((uint8_t*)&setup,8);
- ClearSetupInt();
-
- uint8_t requestType = setup.bmRequestType;
- if (requestType & REQUEST_DEVICETOHOST)
- WaitIN();
- else
- ClearIN();
-
- bool ok = true;
- if (REQUEST_STANDARD == (requestType & REQUEST_TYPE))
- {
- // Standard Requests
- uint8_t r = setup.bRequest;
- uint16_t wValue = setup.wValueL | (setup.wValueH << 8);
- if (GET_STATUS == r)
- {
- if (requestType == (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_DEVICE))
- {
- Send8(_usbCurrentStatus);
- Send8(0);
- }
- else
- {
- // TODO: handle the HALT state of an endpoint here
- // see "Figure 9-6. Information Returned by a GetStatus() Request to an Endpoint" in usb_20.pdf for more information
- Send8(0);
- Send8(0);
- }
- }
- else if (CLEAR_FEATURE == r)
- {
- if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
- && (wValue == DEVICE_REMOTE_WAKEUP))
- {
- _usbCurrentStatus &= ~FEATURE_REMOTE_WAKEUP_ENABLED;
- }
- }
- else if (SET_FEATURE == r)
- {
- if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE))
- && (wValue == DEVICE_REMOTE_WAKEUP))
- {
- _usbCurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED;
- }
- }
- else if (SET_ADDRESS == r)
- {
- WaitIN();
- UDADDR = setup.wValueL | (1<
#include
#include
+#include
class USBDevice_
{
-public:
- USBDevice_();
- bool configured();
-
- void attach();
- void detach(); // Serial port goes down too...
- void poll();
- bool wakeupHost(); // returns false, when wakeup cannot be processed
+ public:
+ USBDevice_();
+ bool configured();
+
+ void attach();
+ void detach(); // Serial port goes down too...
+ void poll();
+ bool wakeupHost(); // returns false, when wakeup cannot be processed
};
extern USBDevice_ USBDevice;
-// Standard requests
-#define GET_STATUS 0
-#define CLEAR_FEATURE 1
-#define SET_FEATURE 3
-#define SET_ADDRESS 5
-#define GET_DESCRIPTOR 6
-#define SET_DESCRIPTOR 7
-#define GET_CONFIGURATION 8
-#define SET_CONFIGURATION 9
-#define GET_INTERFACE 10
-#define SET_INTERFACE 11
+// Standard requests
+#define GET_STATUS 0
+#define CLEAR_FEATURE 1
+#define SET_FEATURE 3
+#define SET_ADDRESS 5
+#define GET_DESCRIPTOR 6
+#define SET_DESCRIPTOR 7
+#define GET_CONFIGURATION 8
+#define SET_CONFIGURATION 9
+#define GET_INTERFACE 10
+#define SET_INTERFACE 11
// bmRequestType
-#define REQUEST_HOSTTODEVICE 0x00
-#define REQUEST_DEVICETOHOST 0x80
-#define REQUEST_DIRECTION 0x80
-
-#define REQUEST_STANDARD 0x00
-#define REQUEST_CLASS 0x20
-#define REQUEST_VENDOR 0x40
-#define REQUEST_TYPE 0x60
-
-#define REQUEST_DEVICE 0x00
-#define REQUEST_INTERFACE 0x01
-#define REQUEST_ENDPOINT 0x02
-#define REQUEST_OTHER 0x03
-#define REQUEST_RECIPIENT 0x03
-
-#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE)
-#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE)
+#define REQUEST_HOSTTODEVICE 0x00
+#define REQUEST_DEVICETOHOST 0x80
+#define REQUEST_DIRECTION 0x80
+
+#define REQUEST_STANDARD 0x00
+#define REQUEST_CLASS 0x20
+#define REQUEST_VENDOR 0x40
+#define REQUEST_TYPE 0x60
+
+#define REQUEST_DEVICE 0x00
+#define REQUEST_INTERFACE 0x01
+#define REQUEST_ENDPOINT 0x02
+#define REQUEST_OTHER 0x03
+#define REQUEST_RECIPIENT 0x03
+
+#define REQUEST_DEVICETOHOST_CLASS_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_CLASS | REQUEST_INTERFACE)
+#define REQUEST_HOSTTODEVICE_CLASS_INTERFACE (REQUEST_HOSTTODEVICE | REQUEST_CLASS | REQUEST_INTERFACE)
#define REQUEST_DEVICETOHOST_STANDARD_INTERFACE (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_INTERFACE)
-// Class requests
+// Class requests
-#define CDC_SET_LINE_CODING 0x20
-#define CDC_GET_LINE_CODING 0x21
-#define CDC_SET_CONTROL_LINE_STATE 0x22
-#define CDC_SEND_BREAK 0x23
+#define CDC_SET_LINE_CODING 0x20
+#define CDC_GET_LINE_CODING 0x21
+#define CDC_SET_CONTROL_LINE_STATE 0x22
+#define CDC_SEND_BREAK 0x23
-#define MSC_RESET 0xFF
-#define MSC_GET_MAX_LUN 0xFE
+#define MSC_RESET 0xFF
+#define MSC_GET_MAX_LUN 0xFE
-// Descriptors
+// Descriptors
#define USB_DEVICE_DESC_SIZE 18
#define USB_CONFIGUARTION_DESC_SIZE 9
#define USB_INTERFACE_DESC_SIZE 9
#define USB_ENDPOINT_DESC_SIZE 7
-#define USB_DEVICE_DESCRIPTOR_TYPE 1
-#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
-#define USB_STRING_DESCRIPTOR_TYPE 3
-#define USB_INTERFACE_DESCRIPTOR_TYPE 4
-#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
+#define USB_DEVICE_DESCRIPTOR_TYPE 1
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2
+#define USB_STRING_DESCRIPTOR_TYPE 3
+#define USB_INTERFACE_DESCRIPTOR_TYPE 4
+#define USB_ENDPOINT_DESCRIPTOR_TYPE 5
// usb_20.pdf Table 9.6 Standard Feature Selectors
-#define DEVICE_REMOTE_WAKEUP 1
-#define ENDPOINT_HALT 2
-#define TEST_MODE 3
+#define DEVICE_REMOTE_WAKEUP 1
+#define ENDPOINT_HALT 2
+#define TEST_MODE 3
// usb_20.pdf Figure 9-4. Information Returned by a GetStatus() Request to a Device
-#define FEATURE_SELFPOWERED_ENABLED (1 << 0)
-#define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1)
+#define FEATURE_SELFPOWERED_ENABLED (1 << 0)
+#define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1)
-#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
-#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
-#define USB_DEVICE_CLASS_STORAGE 0x08
-#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
+#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
+#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
+#define USB_DEVICE_CLASS_STORAGE 0x08
+#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
-#define USB_CONFIG_POWERED_MASK 0x40
-#define USB_CONFIG_BUS_POWERED 0x80
-#define USB_CONFIG_SELF_POWERED 0xC0
-#define USB_CONFIG_REMOTE_WAKEUP 0x20
+#define USB_CONFIG_POWERED_MASK 0x40
+#define USB_CONFIG_BUS_POWERED 0x80
+#define USB_CONFIG_SELF_POWERED 0xC0
+#define USB_CONFIG_REMOTE_WAKEUP 0x20
// bMaxPower in Configuration Descriptor
-#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
+#define USB_CONFIG_POWER_MA(mA) ((mA) / 2)
// bEndpointAddress in Endpoint Descriptor
-#define USB_ENDPOINT_DIRECTION_MASK 0x80
-#define USB_ENDPOINT_OUT(addr) (lowByte((addr) | 0x00))
-#define USB_ENDPOINT_IN(addr) (lowByte((addr) | 0x80))
+#define USB_ENDPOINT_DIRECTION_MASK 0x80
+#define USB_ENDPOINT_OUT(addr) (lowByte((addr) | 0x00))
+#define USB_ENDPOINT_IN(addr) (lowByte((addr) | 0x80))
-#define USB_ENDPOINT_TYPE_MASK 0x03
-#define USB_ENDPOINT_TYPE_CONTROL 0x00
-#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
-#define USB_ENDPOINT_TYPE_BULK 0x02
-#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
+#define USB_ENDPOINT_TYPE_MASK 0x03
+#define USB_ENDPOINT_TYPE_CONTROL 0x00
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
+#define USB_ENDPOINT_TYPE_BULK 0x02
+#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
-#define TOBYTES(x) ((x) & 0xFF),(((x) >> 8) & 0xFF)
+#define TOBYTES(x) ((x)&0xFF), (((x) >> 8) & 0xFF)
-#define CDC_V1_10 0x0110
-#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
+#define CDC_V1_10 0x0110
+#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02
-#define CDC_CALL_MANAGEMENT 0x01
-#define CDC_ABSTRACT_CONTROL_MODEL 0x02
-#define CDC_HEADER 0x00
-#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
-#define CDC_UNION 0x06
-#define CDC_CS_INTERFACE 0x24
-#define CDC_CS_ENDPOINT 0x25
-#define CDC_DATA_INTERFACE_CLASS 0x0A
+#define CDC_CALL_MANAGEMENT 0x01
+#define CDC_ABSTRACT_CONTROL_MODEL 0x02
+#define CDC_HEADER 0x00
+#define CDC_ABSTRACT_CONTROL_MANAGEMENT 0x02
+#define CDC_UNION 0x06
+#define CDC_CS_INTERFACE 0x24
+#define CDC_CS_ENDPOINT 0x25
+#define CDC_DATA_INTERFACE_CLASS 0x0A
-#define MSC_SUBCLASS_SCSI 0x06
-#define MSC_PROTOCOL_BULK_ONLY 0x50
+#define MSC_SUBCLASS_SCSI 0x06
+#define MSC_PROTOCOL_BULK_ONLY 0x50
#ifndef USB_VERSION
#define USB_VERSION 0x200
#endif
-#define TRANSFER_PGM 0x80
-#define TRANSFER_RELEASE 0x40
-#define TRANSFER_ZERO 0x20
-
-// Device
-typedef struct {
- uint8_t len; // 18
- uint8_t dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
- uint16_t usbVersion; // 0x200 or 0x210
- uint8_t deviceClass;
- uint8_t deviceSubClass;
- uint8_t deviceProtocol;
- uint8_t packetSize0; // Packet 0
- uint16_t idVendor;
- uint16_t idProduct;
- uint16_t deviceVersion; // 0x100
- uint8_t iManufacturer;
- uint8_t iProduct;
- uint8_t iSerialNumber;
- uint8_t bNumConfigurations;
+#define TRANSFER_PGM 0x80
+#define TRANSFER_RELEASE 0x40
+#define TRANSFER_ZERO 0x20
+
+// Device
+typedef struct
+{
+ uint8_t len; // 18
+ uint8_t dtype; // 1 USB_DEVICE_DESCRIPTOR_TYPE
+ uint16_t usbVersion; // 0x200 or 0x210
+ uint8_t deviceClass;
+ uint8_t deviceSubClass;
+ uint8_t deviceProtocol;
+ uint8_t packetSize0; // Packet 0
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t deviceVersion; // 0x100
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
} DeviceDescriptor;
-// Config
-typedef struct {
- uint8_t len; // 9
- uint8_t dtype; // 2
- uint16_t clen; // total length
- uint8_t numInterfaces;
- uint8_t config;
- uint8_t iconfig;
- uint8_t attributes;
- uint8_t maxPower;
+// Config
+typedef struct
+{
+ uint8_t len; // 9
+ uint8_t dtype; // 2
+ uint16_t clen; // total length
+ uint8_t numInterfaces;
+ uint8_t config;
+ uint8_t iconfig;
+ uint8_t attributes;
+ uint8_t maxPower;
} ConfigDescriptor;
-// String
+// String
-// Interface
+// Interface
typedef struct
{
- uint8_t len; // 9
- uint8_t dtype; // 4
- uint8_t number;
- uint8_t alternate;
- uint8_t numEndpoints;
- uint8_t interfaceClass;
- uint8_t interfaceSubClass;
- uint8_t protocol;
- uint8_t iInterface;
+ uint8_t len; // 9
+ uint8_t dtype; // 4
+ uint8_t number;
+ uint8_t alternate;
+ uint8_t numEndpoints;
+ uint8_t interfaceClass;
+ uint8_t interfaceSubClass;
+ uint8_t protocol;
+ uint8_t iInterface;
} InterfaceDescriptor;
-// Endpoint
+// Endpoint
typedef struct
{
- uint8_t len; // 7
- uint8_t dtype; // 5
- uint8_t addr;
- uint8_t attr;
- uint16_t packetSize;
- uint8_t interval;
+ uint8_t len; // 7
+ uint8_t dtype; // 5
+ uint8_t addr;
+ uint8_t attr;
+ uint16_t packetSize;
+ uint8_t interval;
} EndpointDescriptor;
// Interface Association Descriptor
// Used to bind 2 interfaces together in CDC compostite device
typedef struct
{
- uint8_t len; // 8
- uint8_t dtype; // 11
- uint8_t firstInterface;
- uint8_t interfaceCount;
- uint8_t functionClass;
- uint8_t funtionSubClass;
- uint8_t functionProtocol;
- uint8_t iInterface;
+ uint8_t len; // 8
+ uint8_t dtype; // 11
+ uint8_t firstInterface;
+ uint8_t interfaceCount;
+ uint8_t functionClass;
+ uint8_t funtionSubClass;
+ uint8_t functionProtocol;
+ uint8_t iInterface;
} IADDescriptor;
-// CDC CS interface descriptor
+// CDC CS interface descriptor
typedef struct
{
- uint8_t len; // 5
- uint8_t dtype; // 0x24
- uint8_t subtype;
- uint8_t d0;
- uint8_t d1;
+ uint8_t len; // 5
+ uint8_t dtype; // 0x24
+ uint8_t subtype;
+ uint8_t d0;
+ uint8_t d1;
} CDCCSInterfaceDescriptor;
typedef struct
{
- uint8_t len; // 4
- uint8_t dtype; // 0x24
- uint8_t subtype;
- uint8_t d0;
+ uint8_t len; // 4
+ uint8_t dtype; // 0x24
+ uint8_t subtype;
+ uint8_t d0;
} CDCCSInterfaceDescriptor4;
-typedef struct
+typedef struct
{
- uint8_t len;
- uint8_t dtype; // 0x24
- uint8_t subtype; // 1
- uint8_t bmCapabilities;
- uint8_t bDataInterface;
+ uint8_t len;
+ uint8_t dtype; // 0x24
+ uint8_t subtype; // 1
+ uint8_t bmCapabilities;
+ uint8_t bDataInterface;
} CMFunctionalDescriptor;
-
-typedef struct
+
+typedef struct
{
- uint8_t len;
- uint8_t dtype; // 0x24
- uint8_t subtype; // 1
- uint8_t bmCapabilities;
+ uint8_t len;
+ uint8_t dtype; // 0x24
+ uint8_t subtype; // 1
+ uint8_t bmCapabilities;
} ACMFunctionalDescriptor;
-typedef struct
+typedef struct
{
- // IAD
- IADDescriptor iad; // Only needed on compound device
-
- // Control
- InterfaceDescriptor cif; //
- CDCCSInterfaceDescriptor header;
- CMFunctionalDescriptor callManagement; // Call Management
- ACMFunctionalDescriptor controlManagement; // ACM
- CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION
- EndpointDescriptor cifin;
-
- // Data
- InterfaceDescriptor dif;
- EndpointDescriptor in;
- EndpointDescriptor out;
+ // IAD
+ IADDescriptor iad; // Only needed on compound device
+
+ // Control
+ InterfaceDescriptor cif; //
+ CDCCSInterfaceDescriptor header;
+ CMFunctionalDescriptor callManagement; // Call Management
+ ACMFunctionalDescriptor controlManagement; // ACM
+ CDCCSInterfaceDescriptor functionalDescriptor; // CDC_UNION
+ EndpointDescriptor cifin;
+
+ // Data
+ InterfaceDescriptor dif;
+ EndpointDescriptor in;
+ EndpointDescriptor out;
} CDCDescriptor;
-typedef struct
+typedef struct
{
- InterfaceDescriptor msc;
- EndpointDescriptor in;
- EndpointDescriptor out;
+ InterfaceDescriptor msc;
+ EndpointDescriptor in;
+ EndpointDescriptor out;
} MSCDescriptor;
+#define D_DEVICE(_class, _subClass, _proto, _packetSize0, _vid, _pid, _version, _im, _ip, _is, _configs) \
+ { \
+ 18, 1, USB_VERSION, _class, _subClass, _proto, _packetSize0, _vid, _pid, _version, _im, _ip, _is, _configs \
+ }
-#define D_DEVICE(_class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs) \
- { 18, 1, USB_VERSION, _class,_subClass,_proto,_packetSize0,_vid,_pid,_version,_im,_ip,_is,_configs }
-
-#define D_CONFIG(_totalLength,_interfaces) \
- { 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP, USB_CONFIG_POWER_MA(500) }
+#define D_CONFIG(_totalLength, _interfaces) \
+ { \
+ 9, 2, _totalLength, _interfaces, 1, 0, USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP, USB_CONFIG_POWER_MA(500) \
+ }
-#define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
- { 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }
+#define D_INTERFACE(_n, _numEndpoints, _class, _subClass, _protocol) \
+ { \
+ 9, 4, _n, 0, _numEndpoints, _class, _subClass, _protocol, 0 \
+ }
-#define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
- { 7, 5, _addr,_attr,_packetSize, _interval }
+#define D_ENDPOINT(_addr, _attr, _packetSize, _interval) \
+ { \
+ 7, 5, _addr, _attr, _packetSize, _interval \
+ }
#define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
- { 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
-
-#define D_CDCCS(_subtype,_d0,_d1) { 5, 0x24, _subtype, _d0, _d1 }
-#define D_CDCCS4(_subtype,_d0) { 4, 0x24, _subtype, _d0 }
+ { \
+ 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 \
+ }
+
+#define D_CDCCS(_subtype, _d0, _d1) \
+ { \
+ 5, 0x24, _subtype, _d0, _d1 \
+ }
+#define D_CDCCS4(_subtype, _d0) \
+ { \
+ 4, 0x24, _subtype, _d0 \
+ }
// Bootloader related fields
// Old Caterina bootloader places the MAGIC key into unsafe RAM locations (it can be rewritten
@@ -327,13 +344,13 @@ typedef struct
#define USB_ENDPOINTS 5 // AtMegaxxU2
#endif
-#define EP_TYPE_CONTROL (0x00)
-#define EP_TYPE_BULK_IN ((1<
-#include
#include
+#include
#include
+#include
#include
#include "wiring_private.h"
static volatile voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
-void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) {
-
+void attachInterrupt(uint8_t pin, void (*userFunc)(void), uint8_t mode)
+{
/* Get bit position and check pin validity */
uint8_t bit_pos = digitalPinToBitPosition(pin);
- if(bit_pos == NOT_A_PIN) return;
+ if (bit_pos == NOT_A_PIN) return;
/* Get interrupt number from pin */
uint8_t interruptNum = (digitalPinToPort(pin) * 8) + bit_pos;
/* Check interrupt number and apply function pointer to correct array index */
- if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
+ if (interruptNum < EXTERNAL_NUM_INTERRUPTS)
+ {
intFunc[interruptNum] = userFunc;
// Configure the interrupt mode (trigger on low input, any change, rising
@@ -52,7 +51,8 @@ void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) {
// to the configuration bits in the hardware register, so we simply apply
// the setting in the pin control register
- switch (mode) {
+ switch (mode)
+ {
case CHANGE:
mode = PORT_ISC_BOTHEDGES_gc;
break;
@@ -74,7 +74,7 @@ void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) {
/* Get pointer to correct pin control register */
PORT_t *port = digitalPinToPortStruct(pin);
- volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
+ volatile uint8_t *pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
/* Clear any previous setting */
*pin_ctrl_reg &= ~(PORT_ISC_gm);
@@ -84,20 +84,22 @@ void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) {
}
}
-void detachInterrupt(uint8_t pin) {
+void detachInterrupt(uint8_t pin)
+{
/* Get bit position and check pin validity */
uint8_t bit_pos = digitalPinToBitPosition(pin);
- if(bit_pos == NOT_A_PIN) return;
+ if (bit_pos == NOT_A_PIN) return;
/* Get interrupt number from pin */
uint8_t interruptNum = (digitalPinToPort(pin) * 8) + bit_pos;
- if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
+ if (interruptNum < EXTERNAL_NUM_INTERRUPTS)
+ {
// Disable the interrupt.
/* Get pointer to correct pin control register */
PORT_t *port = digitalPinToPortStruct(pin);
- volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
+ volatile uint8_t *pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
/* Clear ISC setting */
*pin_ctrl_reg &= ~(PORT_ISC_gm);
@@ -106,8 +108,8 @@ void detachInterrupt(uint8_t pin) {
}
}
-static void port_interrupt_handler(uint8_t port) {
-
+static void port_interrupt_handler(uint8_t port)
+{
PORT_t *portStruct = portToPortStruct(port);
/* Copy flags */
uint8_t int_flags = portStruct->INTFLAGS;
@@ -115,23 +117,23 @@ static void port_interrupt_handler(uint8_t port) {
uint8_t bit_pos = PIN0_bp, bit_mask = PIN0_bm;
/* Iterate through flags */
- while(bit_pos <= PIN7_bp){
-
+ while (bit_pos <= PIN7_bp)
+ {
/* Check if flag raised */
- if(int_flags & bit_mask){
-
- /* Get interrupt */
- uint8_t interrupt_num = port*8 + bit_pos;
+ if (int_flags & bit_mask)
+ {
+ /* Get interrupt */
+ uint8_t interrupt_num = port * 8 + bit_pos;
/* Check if function defined */
- if(intFunc[interrupt_num] != 0){
-
+ if (intFunc[interrupt_num] != 0)
+ {
/* Call function */
intFunc[interrupt_num]();
}
}
bit_pos++;
- bit_mask = (bit_mask << 1);
+ bit_mask = (bit_mask << 1);
}
/* Clear flags that have been handled */
@@ -139,9 +141,10 @@ static void port_interrupt_handler(uint8_t port) {
}
#define IMPLEMENT_ISR(vect, port) \
-ISR(vect) { \
- port_interrupt_handler(port);\
-} \
+ ISR(vect) \
+ { \
+ port_interrupt_handler(port); \
+ }
IMPLEMENT_ISR(PORTA_PORT_vect, PA)
IMPLEMENT_ISR(PORTB_PORT_vect, PB)
diff --git a/megaavr/cores/coreX-corefiles/WMath.cpp b/megaavr/cores/coreX-corefiles/WMath.cpp
index f4ce2b7..9a5af7d 100644
--- a/megaavr/cores/coreX-corefiles/WMath.cpp
+++ b/megaavr/cores/coreX-corefiles/WMath.cpp
@@ -1,5 +1,3 @@
-/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
-
/*
Part of the Wiring project - http://wiring.org.co
Copyright (c) 2004-06 Hernando Barragan
@@ -21,20 +19,23 @@
Boston, MA 02111-1307 USA
*/
-extern "C" {
+extern "C"
+{
#include "stdlib.h"
}
void randomSeed(unsigned long seed)
{
- if (seed != 0) {
+ if (seed != 0)
+ {
srandom(seed);
}
}
long random(long howbig)
{
- if (howbig == 0) {
+ if (howbig == 0)
+ {
return 0;
}
return random() % howbig;
@@ -42,7 +43,8 @@ long random(long howbig)
long random(long howsmall, long howbig)
{
- if (howsmall >= howbig) {
+ if (howsmall >= howbig)
+ {
return howsmall;
}
long diff = howbig - howsmall;
diff --git a/megaavr/cores/coreX-corefiles/api/ArduinoAPI.h b/megaavr/cores/coreX-corefiles/api/ArduinoAPI.h
index b737af9..1535fe9 100644
--- a/megaavr/cores/coreX-corefiles/api/ArduinoAPI.h
+++ b/megaavr/cores/coreX-corefiles/api/ArduinoAPI.h
@@ -30,23 +30,23 @@
#include "HardwareI2C.h"
#include "HardwareSerial.h"
#include "IPAddress.h"
+#include "PluggableUSB.h"
#include "Print.h"
#include "Printable.h"
-#include "PluggableUSB.h"
#include "Server.h"
-#include "String.h"
#include "Stream.h"
-#include "Udp.h"
+#include "String.h"
#include "USBAPI.h"
+#include "Udp.h"
#include "WCharacter.h"
#endif
/* Standard C library includes */
-#include
-#include
+#include
#include
+#include
+#include
#include
-#include
// Misc Arduino core functions
#include "Common.h"
diff --git a/megaavr/cores/coreX-corefiles/api/Client.h b/megaavr/cores/coreX-corefiles/api/Client.h
index c8ebc9f..e42a66a 100644
--- a/megaavr/cores/coreX-corefiles/api/Client.h
+++ b/megaavr/cores/coreX-corefiles/api/Client.h
@@ -19,16 +19,16 @@
#pragma once
-#include "Stream.h"
#include "IPAddress.h"
-
-class Client : public Stream {
-
-public:
- virtual int connect(IPAddress ip, uint16_t port) =0;
- virtual int connect(const char *host, uint16_t port) =0;
- virtual size_t write(uint8_t) =0;
- virtual size_t write(const uint8_t *buf, size_t size) =0;
+#include "Stream.h"
+namespace arduino {
+class Client : public Stream
+{
+ public:
+ virtual int connect(IPAddress ip, uint16_t port) = 0;
+ virtual int connect(const char *host, uint16_t port) = 0;
+ virtual size_t write(uint8_t) = 0;
+ virtual size_t write(const uint8_t *buf, size_t size) = 0;
virtual int available() = 0;
virtual int read() = 0;
virtual int read(uint8_t *buf, size_t size) = 0;
@@ -37,7 +37,10 @@ class Client : public Stream {
virtual void stop() = 0;
virtual uint8_t connected() = 0;
virtual operator bool() = 0;
-protected:
- uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
+
+ protected:
+ uint8_t *rawIPAddress(IPAddress &addr) { return addr.raw_address(); };
};
+}
+using arduino::Client;
diff --git a/megaavr/cores/coreX-corefiles/api/Common.cpp b/megaavr/cores/coreX-corefiles/api/Common.cpp
index d1f822c..bd7a5e2 100644
--- a/megaavr/cores/coreX-corefiles/api/Common.cpp
+++ b/megaavr/cores/coreX-corefiles/api/Common.cpp
@@ -7,4 +7,4 @@ long map(long x, long in_min, long in_max, long out_min, long out_max)
}
uint16_t makeWord(uint16_t w) { return w; }
-uint16_t makeWord(uint8_t h, uint8_t l) { return (h << 8) | l; }
\ No newline at end of file
+uint16_t makeWord(uint8_t h, uint8_t l) { return (h << 8) | l; }
diff --git a/megaavr/cores/coreX-corefiles/api/Common.h b/megaavr/cores/coreX-corefiles/api/Common.h
index 302be4c..2864970 100644
--- a/megaavr/cores/coreX-corefiles/api/Common.h
+++ b/megaavr/cores/coreX-corefiles/api/Common.h
@@ -6,65 +6,30 @@ extern "C"{
void yield(void);
-typedef enum {
- LOW = 0,
- HIGH = 1,
- CHANGE = 2,
- FALLING = 3,
- RISING = 4,
-} PinStatus;
-
-typedef enum {
- INPUT = 0x0,
- OUTPUT = 0x1,
- INPUT_PULLUP = 0x2,
- INPUT_PULLDOWN = 0x3,
-} PinMode;
-
-typedef enum {
- LSBFIRST = 0,
- MSBFIRST = 1,
-} BitOrder;
-
-#define PI 3.1415926535897932384626433832795
-#define HALF_PI 1.5707963267948966192313216916398
-#define TWO_PI 6.283185307179586476925286766559
-#define DEG_TO_RAD 0.017453292519943295769236907684886
-#define RAD_TO_DEG 57.295779513082320876798154814105
-#define EULER 2.718281828459045235360287471352
-
-#define SERIAL 0x0
-#define DISPLAY 0x1
+#define LOW 0
+#define HIGH 1
-#ifndef min
-#define min(a,b) \
- ({ __typeof__ (a) _a = (a); \
- __typeof__ (b) _b = (b); \
- _a < _b ? _a : _b; })
-#endif
+#define FALLING 2
+#define RISING 3
+#define CHANGE 4
-#ifndef max
-#define max(a,b) \
- ({ __typeof__ (a) _a = (a); \
- __typeof__ (b) _b = (b); \
- _a > _b ? _a : _b; })
-#endif
+#define INPUT 0
+#define OUTPUT 1
+#define INPUT_PULLUP 2
+//#define INPUT_PULLDOWN 3
-#ifndef constrain
-#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
-#endif
-
-#ifndef radians
-#define radians(deg) ((deg)*DEG_TO_RAD)
-#endif
+#define LSBFIRST 0
+#define MSBFIRST 1
-#ifndef degrees
-#define degrees(rad) ((rad)*RAD_TO_DEG)
-#endif
+#define PI 3.1415926535897932384626433832795
+#define HALF_PI 1.5707963267948966192313216916398
+#define TWO_PI 6.283185307179586476925286766559
+#define DEG_TO_RAD 0.017453292519943295769236907684886
+#define RAD_TO_DEG 57.295779513082320876798154814105
+#define EULER 2.718281828459045235360287471352
-#ifndef sq
-#define sq(x) ((x)*(x))
-#endif
+#define SERIAL 0
+#define DISPLAY 1
typedef void (*voidFuncPtr)(void);
@@ -100,12 +65,16 @@ typedef uint32_t pin_size_t;
typedef uint8_t pin_size_t;
#endif
-void pinMode(pin_size_t pinNumber, PinMode pinMode);
-void digitalWrite(pin_size_t pinNumber, PinStatus status);
-PinStatus digitalRead(pin_size_t pinNumber);
+void pinMode(pin_size_t pinNumber, uint8_t pinMode);
+void digitalWrite(pin_size_t pinNumber, uint8_t status);
+void digitalWriteFast(pin_size_t pinNumber, uint8_t status);
+uint8_t digitalRead(pin_size_t pinNumber);
+uint8_t digitalReadFast(pin_size_t pinNumber);
int analogRead(pin_size_t pinNumber);
+uint8_t analogReadResolution(uint8_t res);
void analogReference(uint8_t mode);
void analogWrite(pin_size_t pinNumber, int value);
+void analogWriteFrequency(uint8_t kHz);
unsigned long millis(void);
unsigned long micros(void);
@@ -114,19 +83,101 @@ void delayMicroseconds(unsigned int us);
unsigned long pulseIn(pin_size_t pin, uint8_t state, unsigned long timeout);
unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout);
-void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val);
-pin_size_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder);
+void shiftOut(pin_size_t dataPin, pin_size_t clockPin, uint8_t bitOrder, uint8_t val);
+pin_size_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, uint8_t bitOrder);
-void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode);
+void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, uint8_t mode);
void detachInterrupt(pin_size_t interruptNumber);
void setup(void);
void loop(void);
+// Constant checks error handler
+void badArg(const char*) __attribute__((error("")));
+inline __attribute__((always_inline)) void check_constant_pin(pin_size_t pin)
+{
+ if(!__builtin_constant_p(pin))
+ badArg("Digital pin must be a constant");
+}
+
#ifdef __cplusplus
} // extern "C"
#endif
+#ifdef __cplusplus
+#ifndef min
+ template
+ auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) {
+ return (b < a) ? b : a;
+ }
+#endif
+
+#ifndef max
+ template
+ auto max(const T& a, const L& b) -> decltype((a < b) ? b : a) {
+ return (a < b) ? b : a;
+ }
+#endif
+
+#ifndef round
+ template
+ long round(const T& x) {
+ return (long)(x >= 0 ? (x + 0.5) : (x - 0.5));
+ }
+#endif
+
+#ifndef max
+ template
+ auto sq(const T& x) -> decltype(x * x) {
+ return x * x;
+ }
+#endif
+
+#ifndef radians
+ template
+ auto radians(const T& deg) -> decltype(deg * DEG_TO_RAD) {
+ return deg * DEG_TO_RAD;
+ }
+#endif
+
+#ifndef degrees
+ template
+ auto degrees(const T& rad) -> decltype(rad * RAD_TO_DEG) {
+ return rad * RAD_TO_DEG;
+ }
+#endif
+#ifndef constrain
+ template
+ auto constrain(const T& x, const L& l, const H& h) -> decltype((x < l) ? l : (x > h) ? h : x) {
+ return (x < l) ? l : (x > h) ? h : x;
+ }
+#endif
+
+#else
+ #ifndef min
+ #define min(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a < _b ? _a : _b; })
+ #endif
+ #ifndef max
+ #define max(a,b) ({ typeof (a) _a = (a); typeof (b) _b = (b); _a > _b ? _a : _b; })
+ #endif
+ #ifndef sq
+ #define sq(x) ({ typeof (x) _x = (x); _x * _x; })
+ #endif
+ #ifndef radians
+ #define radians(deg) ((deg) * DEG_TO_RAD)
+ #endif
+ #ifndef degrees
+ #define degrees(rad) ((rad) * RAD_TO_DEG)
+ #endif
+ #ifndef constrain
+ #define constrain(x,low,high) ({ \
+ typeof (x) _x = (x); \
+ typeof (low) _l = (low); \
+ typeof (high) _h = (high); \
+ _x < _l ? _l : _x > _h ? _h : _x; })
+ #endif
+#endif // __cplusplus
+
#ifdef __cplusplus
/* C++ prototypes */
@@ -147,4 +198,4 @@ long random(long, long);
void randomSeed(unsigned long);
long map(long, long, long, long, long);
-#endif // __cplusplus
\ No newline at end of file
+#endif // __cplusplus
diff --git a/megaavr/cores/coreX-corefiles/api/HardwareI2C.h b/megaavr/cores/coreX-corefiles/api/HardwareI2C.h
index 25bf40e..5e37368 100644
--- a/megaavr/cores/coreX-corefiles/api/HardwareI2C.h
+++ b/megaavr/cores/coreX-corefiles/api/HardwareI2C.h
@@ -19,25 +19,25 @@
#pragma once
#include
+
#include "Stream.h"
class HardwareI2C : public Stream
{
- public:
- virtual void begin() = 0;
- virtual void begin(uint8_t address) = 0;
- virtual void end() = 0;
-
- virtual void setClock(uint32_t freq) = 0;
-
- virtual void beginTransmission(uint8_t address) = 0;
- virtual uint8_t endTransmission(bool stopBit) = 0;
- virtual uint8_t endTransmission(void) = 0;
-
- virtual uint8_t requestFrom(uint8_t address, size_t len, bool stopBit) = 0;
- virtual uint8_t requestFrom(uint8_t address, size_t len) = 0;
-
- virtual void onReceive(void(*)(int)) = 0;
- virtual void onRequest(void(*)(void)) = 0;
-};
+ public:
+ virtual void begin() = 0;
+ virtual void begin(uint8_t address) = 0;
+ virtual void end() = 0;
+
+ virtual void setClock(uint32_t freq) = 0;
+ virtual void beginTransmission(uint8_t address) = 0;
+ virtual uint8_t endTransmission(bool stopBit) = 0;
+ virtual uint8_t endTransmission(void) = 0;
+
+ virtual uint8_t requestFrom(uint8_t address, size_t len, bool stopBit) = 0;
+ virtual uint8_t requestFrom(uint8_t address, size_t len) = 0;
+
+ virtual void onReceive(void (*)(int)) = 0;
+ virtual void onRequest(void (*)(void)) = 0;
+};
diff --git a/megaavr/cores/coreX-corefiles/api/HardwareSerial.h b/megaavr/cores/coreX-corefiles/api/HardwareSerial.h
index e3b0b27..94207ea 100644
--- a/megaavr/cores/coreX-corefiles/api/HardwareSerial.h
+++ b/megaavr/cores/coreX-corefiles/api/HardwareSerial.h
@@ -19,84 +19,86 @@
#pragma once
#include
+
#include "Stream.h"
// XXX: Those constants should be defined as const int / enums?
// XXX: shall we use namespaces too?
-#define SERIAL_PARITY_EVEN (0x1ul)
-#define SERIAL_PARITY_ODD (0x2ul)
-#define SERIAL_PARITY_NONE (0x3ul)
-#define SERIAL_PARITY_MARK (0x4ul)
-#define SERIAL_PARITY_SPACE (0x5ul)
-#define SERIAL_PARITY_MASK (0xFul)
+#define SERIAL_PARITY_EVEN (0x1ul)
+#define SERIAL_PARITY_ODD (0x2ul)
+#define SERIAL_PARITY_NONE (0x3ul)
+#define SERIAL_PARITY_MARK (0x4ul)
+#define SERIAL_PARITY_SPACE (0x5ul)
+#define SERIAL_PARITY_MASK (0xFul)
-#define SERIAL_STOP_BIT_1 (0x10ul)
-#define SERIAL_STOP_BIT_1_5 (0x20ul)
-#define SERIAL_STOP_BIT_2 (0x30ul)
+#define SERIAL_STOP_BIT_1 (0x10ul)
+#define SERIAL_STOP_BIT_1_5 (0x20ul)
+#define SERIAL_STOP_BIT_2 (0x30ul)
#define SERIAL_STOP_BIT_MASK (0xF0ul)
-#define SERIAL_DATA_5 (0x100ul)
-#define SERIAL_DATA_6 (0x200ul)
-#define SERIAL_DATA_7 (0x300ul)
-#define SERIAL_DATA_8 (0x400ul)
-#define SERIAL_DATA_MASK (0xF00ul)
+#define SERIAL_DATA_5 (0x100ul)
+#define SERIAL_DATA_6 (0x200ul)
+#define SERIAL_DATA_7 (0x300ul)
+#define SERIAL_DATA_8 (0x400ul)
+#define SERIAL_DATA_MASK (0xF00ul)
-#define SERIAL_5N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_5)
-#define SERIAL_6N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_6)
-#define SERIAL_7N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_7)
-#define SERIAL_8N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_8)
-#define SERIAL_5N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_5)
-#define SERIAL_6N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_6)
-#define SERIAL_7N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_7)
-#define SERIAL_8N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_8)
-#define SERIAL_5E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_5)
-#define SERIAL_6E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_6)
-#define SERIAL_7E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_7)
-#define SERIAL_8E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_8)
-#define SERIAL_5E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_5)
-#define SERIAL_6E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_6)
-#define SERIAL_7E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_7)
-#define SERIAL_8E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_8)
-#define SERIAL_5O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_5)
-#define SERIAL_6O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_6)
-#define SERIAL_7O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_7)
-#define SERIAL_8O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_8)
-#define SERIAL_5O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_5)
-#define SERIAL_6O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_6)
-#define SERIAL_7O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_7)
-#define SERIAL_8O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_8)
-#define SERIAL_5M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_5)
-#define SERIAL_6M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_6)
-#define SERIAL_7M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_7)
-#define SERIAL_8M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_8)
-#define SERIAL_5M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_5)
-#define SERIAL_6M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_6)
-#define SERIAL_7M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_7)
-#define SERIAL_8M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_8)
-#define SERIAL_5S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_5)
-#define SERIAL_6S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_6)
-#define SERIAL_7S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_7)
-#define SERIAL_8S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_8)
-#define SERIAL_5S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_5)
-#define SERIAL_6S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_6)
-#define SERIAL_7S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_7)
-#define SERIAL_8S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_8)
+#define SERIAL_5N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_5)
+#define SERIAL_6N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_6)
+#define SERIAL_7N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_7)
+#define SERIAL_8N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_8)
+#define SERIAL_5N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_5)
+#define SERIAL_6N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_6)
+#define SERIAL_7N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_7)
+#define SERIAL_8N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_8)
+#define SERIAL_5E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_5)
+#define SERIAL_6E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_6)
+#define SERIAL_7E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_7)
+#define SERIAL_8E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_8)
+#define SERIAL_5E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_5)
+#define SERIAL_6E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_6)
+#define SERIAL_7E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_7)
+#define SERIAL_8E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_8)
+#define SERIAL_5O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_5)
+#define SERIAL_6O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_6)
+#define SERIAL_7O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_7)
+#define SERIAL_8O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_8)
+#define SERIAL_5O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_5)
+#define SERIAL_6O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_6)
+#define SERIAL_7O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_7)
+#define SERIAL_8O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_8)
+#define SERIAL_5M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_5)
+#define SERIAL_6M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_6)
+#define SERIAL_7M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_7)
+#define SERIAL_8M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_8)
+#define SERIAL_5M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_5)
+#define SERIAL_6M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_6)
+#define SERIAL_7M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_7)
+#define SERIAL_8M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_8)
+#define SERIAL_5S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_5)
+#define SERIAL_6S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_6)
+#define SERIAL_7S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_7)
+#define SERIAL_8S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_8)
+#define SERIAL_5S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_5)
+#define SERIAL_6S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_6)
+#define SERIAL_7S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_7)
+#define SERIAL_8S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_8)
class HardwareSerial : public Stream
{
- public:
- virtual void begin(unsigned long) = 0;
- virtual void begin(unsigned long baudrate, uint16_t config) = 0;
- virtual void end() = 0;
- virtual int available(void) = 0;
- virtual int peek(void) = 0;
- virtual int read(void) = 0;
- virtual void flush(void) = 0;
- virtual size_t write(uint8_t) = 0;
- using Print::write; // pull in write(str) and write(buf, size) from Print
- virtual operator bool() = 0;
+ public:
+ virtual bool pins(uint8_t tx, uint8_t rx) = 0;
+ virtual bool swap(uint8_t state) = 0;
+ virtual void begin(unsigned long) = 0;
+ virtual void begin(unsigned long baudrate, uint16_t config) = 0;
+ virtual void end() = 0;
+ virtual int available(void) = 0;
+ virtual int peek(void) = 0;
+ virtual int read(void) = 0;
+ virtual void flush(void) = 0;
+ virtual size_t write(uint8_t) = 0;
+ using Print::write; // pull in write(str) and write(buf, size) from Print
+ virtual operator bool() = 0;
};
// XXX: Are we keeping the serialEvent API?
extern void serialEventRun(void) __attribute__((weak));
-
diff --git a/megaavr/cores/coreX-corefiles/api/IPAddress.cpp b/megaavr/cores/coreX-corefiles/api/IPAddress.cpp
index 62244d6..8f70061 100644
--- a/megaavr/cores/coreX-corefiles/api/IPAddress.cpp
+++ b/megaavr/cores/coreX-corefiles/api/IPAddress.cpp
@@ -18,100 +18,104 @@
*/
#include "IPAddress.h"
+
#include "Print.h"
IPAddress::IPAddress()
{
- _address.dword = 0;
+ _address.dword = 0;
}
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
{
- _address.bytes[0] = first_octet;
- _address.bytes[1] = second_octet;
- _address.bytes[2] = third_octet;
- _address.bytes[3] = fourth_octet;
+ _address.bytes[0] = first_octet;
+ _address.bytes[1] = second_octet;
+ _address.bytes[2] = third_octet;
+ _address.bytes[3] = fourth_octet;
}
IPAddress::IPAddress(uint32_t address)
{
- _address.dword = address;
+ _address.dword = address;
}
-IPAddress::IPAddress(const uint8_t *address)
+IPAddress::IPAddress(const uint8_t* address)
{
- memcpy(_address.bytes, address, sizeof(_address.bytes));
+ memcpy(_address.bytes, address, sizeof(_address.bytes));
}
-bool IPAddress::fromString(const char *address)
+bool IPAddress::fromString(const char* address)
{
- // TODO: add support for "a", "a.b", "a.b.c" formats
+ // TODO: add support for "a", "a.b", "a.b.c" formats
- uint16_t acc = 0; // Accumulator
- uint8_t dots = 0;
+ uint16_t acc = 0; // Accumulator
+ uint8_t dots = 0;
- while (*address)
+ while (*address)
+ {
+ char c = *address++;
+ if (c >= '0' && c <= '9')
{
- char c = *address++;
- if (c >= '0' && c <= '9')
- {
- acc = acc * 10 + (c - '0');
- if (acc > 255) {
- // Value out of [0..255] range
- return false;
- }
- }
- else if (c == '.')
- {
- if (dots == 3) {
- // Too much dots (there must be 3 dots)
- return false;
- }
- _address.bytes[dots++] = acc;
- acc = 0;
- }
- else
- {
- // Invalid char
- return false;
- }
+ acc = acc * 10 + (c - '0');
+ if (acc > 255)
+ {
+ // Value out of [0..255] range
+ return false;
+ }
}
-
- if (dots != 3) {
- // Too few dots (there must be 3 dots)
+ else if (c == '.')
+ {
+ if (dots == 3)
+ {
+ // Too much dots (there must be 3 dots)
return false;
+ }
+ _address.bytes[dots++] = acc;
+ acc = 0;
}
- _address.bytes[3] = acc;
- return true;
+ else
+ {
+ // Invalid char
+ return false;
+ }
+ }
+
+ if (dots != 3)
+ {
+ // Too few dots (there must be 3 dots)
+ return false;
+ }
+ _address.bytes[3] = acc;
+ return true;
}
-IPAddress& IPAddress::operator=(const uint8_t *address)
+IPAddress& IPAddress::operator=(const uint8_t* address)
{
- memcpy(_address.bytes, address, sizeof(_address.bytes));
- return *this;
+ memcpy(_address.bytes, address, sizeof(_address.bytes));
+ return *this;
}
IPAddress& IPAddress::operator=(uint32_t address)
{
- _address.dword = address;
- return *this;
+ _address.dword = address;
+ return *this;
}
bool IPAddress::operator==(const uint8_t* addr) const
{
- return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
+ return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
}
size_t IPAddress::printTo(Print& p) const
{
- size_t n = 0;
- for (int i =0; i < 3; i++)
- {
- n += p.print(_address.bytes[i], DEC);
- n += p.print('.');
- }
- n += p.print(_address.bytes[3], DEC);
- return n;
+ size_t n = 0;
+ for (int i = 0; i < 3; i++)
+ {
+ n += p.print(_address.bytes[i], DEC);
+ n += p.print('.');
+ }
+ n += p.print(_address.bytes[3], DEC);
+ return n;
}
-const IPAddress INADDR_NONE(0,0,0,0);
+const IPAddress INADDR_NONE(0, 0, 0, 0);
diff --git a/megaavr/cores/coreX-corefiles/api/IPAddress.h b/megaavr/cores/coreX-corefiles/api/IPAddress.h
index af33cf8..cb3bf27 100644
--- a/megaavr/cores/coreX-corefiles/api/IPAddress.h
+++ b/megaavr/cores/coreX-corefiles/api/IPAddress.h
@@ -20,57 +20,67 @@
#pragma once
#include
+
#include "Printable.h"
#include "String.h"
+class EthernetClass;
+class DhcpClass;
+class DNSClient;
+
+namespace arduino {
// A class to make it easier to handle and pass around IP addresses
-class IPAddress : public Printable {
-private:
- union {
- uint8_t bytes[4]; // IPv4 address
- uint32_t dword;
- } _address;
-
- // Access the raw byte array containing the address. Because this returns a pointer
- // to the internal structure rather than a copy of the address this function should only
- // be used when you know that the usage of the returned uint8_t* will be transient and not
- // stored.
- uint8_t* raw_address() { return _address.bytes; };
-
-public:
- // Constructors
- IPAddress();
- IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
- IPAddress(uint32_t address);
- IPAddress(const uint8_t *address);
-
- bool fromString(const char *address);
- bool fromString(const String &address) { return fromString(address.c_str()); }
-
- // Overloaded cast operator to allow IPAddress objects to be used where a pointer
- // to a four-byte uint8_t array is expected
- operator uint32_t() const { return _address.dword; };
- bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; };
- bool operator==(const uint8_t* addr) const;
-
- // Overloaded index operator to allow getting and setting individual octets of the address
- uint8_t operator[](int index) const { return _address.bytes[index]; };
- uint8_t& operator[](int index) { return _address.bytes[index]; };
-
- // Overloaded copy operators to allow initialisation of IPAddress objects from other types
- IPAddress& operator=(const uint8_t *address);
- IPAddress& operator=(uint32_t address);
-
- virtual size_t printTo(Print& p) const;
-
- friend class EthernetClass;
- friend class UDP;
- friend class Client;
- friend class Server;
- friend class DhcpClass;
- friend class DNSClient;
+class IPAddress : public Printable
+{
+ private:
+ union {
+ uint8_t bytes[4]; // IPv4 address
+ uint32_t dword;
+ } _address;
+
+ // Access the raw byte array containing the address. Because this returns a pointer
+ // to the internal structure rather than a copy of the address this function should only
+ // be used when you know that the usage of the returned uint8_t* will be transient and not
+ // stored.
+ uint8_t* raw_address() { return _address.bytes; };
+
+ public:
+ // Constructors
+ IPAddress();
+ IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
+ IPAddress(uint32_t address);
+ IPAddress(const uint8_t* address);
+
+ bool fromString(const char* address);
+ bool fromString(const String& address) { return fromString(address.c_str()); }
+
+ // Overloaded cast operator to allow IPAddress objects to be used where a pointer
+ // to a four-byte uint8_t array is expected
+ operator uint32_t() const { return _address.dword; };
+ bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; };
+ bool operator==(const uint8_t* addr) const;
+
+ // Overloaded index operator to allow getting and setting individual octets of the address
+ uint8_t operator[](int index) const { return _address.bytes[index]; };
+ uint8_t& operator[](int index) { return _address.bytes[index]; };
+
+ // Overloaded copy operators to allow initialisation of IPAddress objects from other types
+ IPAddress& operator=(const uint8_t* address);
+ IPAddress& operator=(uint32_t address);
+
+ virtual size_t printTo(Print& p) const;
+
+ friend class UDP;
+ friend class Client;
+ friend class Server;
+
+ friend ::EthernetClass;
+ friend ::DhcpClass;
+ friend ::DNSClient;
};
-extern const IPAddress INADDR_NONE;
+}
+using arduino::IPAddress;
+extern const IPAddress INADDR_NONE;
diff --git a/megaavr/cores/coreX-corefiles/api/PluggableUSB.cpp b/megaavr/cores/coreX-corefiles/api/PluggableUSB.cpp
index f0c45f0..0ef7364 100644
--- a/megaavr/cores/coreX-corefiles/api/PluggableUSB.cpp
+++ b/megaavr/cores/coreX-corefiles/api/PluggableUSB.cpp
@@ -17,83 +17,95 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "USBAPI.h"
#include "PluggableUSB.h"
+#include "USBAPI.h"
+
int PluggableUSB_::getInterface(uint8_t* interfaceCount)
{
- int sent = 0;
- PluggableUSBModule* node;
- for (node = rootNode; node; node = node->next) {
- int res = node->getInterface(interfaceCount);
- if (res < 0)
- return -1;
- sent += res;
- }
- return sent;
+ int sent = 0;
+ PluggableUSBModule* node;
+ for (node = rootNode; node; node = node->next)
+ {
+ int res = node->getInterface(interfaceCount);
+ if (res < 0)
+ return -1;
+ sent += res;
+ }
+ return sent;
}
int PluggableUSB_::getDescriptor(USBSetup& setup)
{
- PluggableUSBModule* node;
- for (node = rootNode; node; node = node->next) {
- int ret = node->getDescriptor(setup);
- // ret!=0 -> request has been processed
- if (ret)
- return ret;
- }
- return 0;
+ PluggableUSBModule* node;
+ for (node = rootNode; node; node = node->next)
+ {
+ int ret = node->getDescriptor(setup);
+ // ret!=0 -> request has been processed
+ if (ret)
+ return ret;
+ }
+ return 0;
}
-void PluggableUSB_::getShortName(char *iSerialNum)
+void PluggableUSB_::getShortName(char* iSerialNum)
{
- PluggableUSBModule* node;
- for (node = rootNode; node; node = node->next) {
- iSerialNum += node->getShortName(iSerialNum);
- }
- *iSerialNum = 0;
+ PluggableUSBModule* node;
+ for (node = rootNode; node; node = node->next)
+ {
+ iSerialNum += node->getShortName(iSerialNum);
+ }
+ *iSerialNum = 0;
}
bool PluggableUSB_::setup(USBSetup& setup)
{
- PluggableUSBModule* node;
- for (node = rootNode; node; node = node->next) {
- if (node->setup(setup)) {
- return true;
- }
- }
- return false;
+ PluggableUSBModule* node;
+ for (node = rootNode; node; node = node->next)
+ {
+ if (node->setup(setup))
+ {
+ return true;
+ }
+ }
+ return false;
}
-bool PluggableUSB_::plug(PluggableUSBModule *node)
+bool PluggableUSB_::plug(PluggableUSBModule* node)
{
- if ((lastEp + node->numEndpoints) > totalEP) {
- return false;
- }
+ if ((lastEp + node->numEndpoints) > totalEP)
+ {
+ return false;
+ }
- if (!rootNode) {
- rootNode = node;
- } else {
- PluggableUSBModule *current = rootNode;
- while (current->next) {
- current = current->next;
- }
- current->next = node;
- }
+ if (!rootNode)
+ {
+ rootNode = node;
+ }
+ else
+ {
+ PluggableUSBModule* current = rootNode;
+ while (current->next)
+ {
+ current = current->next;
+ }
+ current->next = node;
+ }
- node->pluggedInterface = lastIf;
- node->pluggedEndpoint = lastEp;
- lastIf += node->numInterfaces;
- for (uint8_t i = 0; i < node->numEndpoints; i++) {
- *(unsigned int*)(epBuffer(lastEp)) = node->endpointType[i];
- lastEp++;
- }
- return true;
- // restart USB layer???
+ node->pluggedInterface = lastIf;
+ node->pluggedEndpoint = lastEp;
+ lastIf += node->numInterfaces;
+ for (uint8_t i = 0; i < node->numEndpoints; i++)
+ {
+ *(unsigned int*)(epBuffer(lastEp)) = node->endpointType[i];
+ lastEp++;
+ }
+ return true;
+ // restart USB layer???
}
PluggableUSB_& PluggableUSB()
{
- static PluggableUSB_ obj;
- return obj;
-}
\ No newline at end of file
+ static PluggableUSB_ obj;
+ return obj;
+}
diff --git a/megaavr/cores/coreX-corefiles/api/PluggableUSB.h b/megaavr/cores/coreX-corefiles/api/PluggableUSB.h
index 09b5fed..1d8b760 100644
--- a/megaavr/cores/coreX-corefiles/api/PluggableUSB.h
+++ b/megaavr/cores/coreX-corefiles/api/PluggableUSB.h
@@ -20,47 +20,54 @@
#ifndef PUSB_h
#define PUSB_h
-#include "USBAPI.h"
-#include
#include
+#include
+
+#include "USBAPI.h"
// core need to define
void* epBuffer(unsigned int n); // -> returns a poointer to the Nth element of the EP buffer structure
-class PluggableUSBModule {
-public:
- PluggableUSBModule(uint8_t numEps, uint8_t numIfs, unsigned int *epType) :
- numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
- { }
+class PluggableUSBModule
+{
+ public:
+ PluggableUSBModule(uint8_t numEps, uint8_t numIfs, unsigned int* epType) : numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
+ {
+ }
-protected:
+ protected:
virtual bool setup(USBSetup& setup) = 0;
virtual int getInterface(uint8_t* interfaceCount) = 0;
virtual int getDescriptor(USBSetup& setup) = 0;
- virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; }
+ virtual uint8_t getShortName(char* name)
+ {
+ name[0] = 'A' + pluggedInterface;
+ return 1;
+ }
uint8_t pluggedInterface;
uint8_t pluggedEndpoint;
const uint8_t numEndpoints;
const uint8_t numInterfaces;
- const unsigned int *endpointType;
+ const unsigned int* endpointType;
- PluggableUSBModule *next = NULL;
+ PluggableUSBModule* next = NULL;
friend class PluggableUSB_;
};
-class PluggableUSB_ {
-public:
+class PluggableUSB_
+{
+ public:
PluggableUSB_();
- bool plug(PluggableUSBModule *node);
+ bool plug(PluggableUSBModule* node);
int getInterface(uint8_t* interfaceCount);
int getDescriptor(USBSetup& setup);
bool setup(USBSetup& setup);
- void getShortName(char *iSerialNum);
+ void getShortName(char* iSerialNum);
-private:
+ private:
uint8_t lastIf;
uint8_t lastEp;
PluggableUSBModule* rootNode;
@@ -72,4 +79,4 @@ class PluggableUSB_ {
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
PluggableUSB_& PluggableUSB();
-#endif
\ No newline at end of file
+#endif
diff --git a/megaavr/cores/coreX-corefiles/api/Print.cpp b/megaavr/cores/coreX-corefiles/api/Print.cpp
index f23b5f2..feec47c 100644
--- a/megaavr/cores/coreX-corefiles/api/Print.cpp
+++ b/megaavr/cores/coreX-corefiles/api/Print.cpp
@@ -16,10 +16,10 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include
+#include
#include
+#include
#include
-#include
#include "Print.h"
@@ -29,9 +29,12 @@
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
- while (size--) {
- if (write(*buffer++)) n++;
- else break;
+ while (size--)
+ {
+ if (write(*buffer++))
+ n++;
+ else
+ break;
}
return n;
}
@@ -41,11 +44,14 @@ size_t Print::print(const __FlashStringHelper *ifsh)
#if defined(__AVR__)
PGM_P p = reinterpret_cast(ifsh);
size_t n = 0;
- while (1) {
+ while (1)
+ {
unsigned char c = pgm_read_byte(p++);
if (c == 0) break;
- if (write(c)) n++;
- else break;
+ if (write(c))
+ n++;
+ else
+ break;
}
return n;
#else
@@ -70,39 +76,47 @@ size_t Print::print(char c)
size_t Print::print(unsigned char b, int base)
{
- return print((unsigned long) b, base);
+ return print((unsigned long)b, base);
}
size_t Print::print(int n, int base)
{
- return print((long) n, base);
+ return print((long)n, base);
}
size_t Print::print(unsigned int n, int base)
{
- return print((unsigned long) n, base);
+ return print((unsigned long)n, base);
}
size_t Print::print(long n, int base)
{
- if (base == 0) {
+ if (base == 0)
+ {
return write(n);
- } else if (base == 10) {
- if (n < 0) {
+ }
+ else if (base == 10)
+ {
+ if (n < 0)
+ {
int t = print('-');
n = -n;
return printNumber(n, 10) + t;
}
return printNumber(n, 10);
- } else {
+ }
+ else
+ {
return printNumber(n, base);
}
}
size_t Print::print(unsigned long n, int base)
{
- if (base == 0) return write(n);
- else return printNumber(n, base);
+ if (base == 0)
+ return write(n);
+ else
+ return printNumber(n, base);
}
size_t Print::print(double n, int digits)
@@ -117,7 +131,7 @@ size_t Print::println(const __FlashStringHelper *ifsh)
return n;
}
-size_t Print::print(const Printable& x)
+size_t Print::print(const Printable &x)
{
return x.printTo(*this);
}
@@ -190,7 +204,7 @@ size_t Print::println(double num, int digits)
return n;
}
-size_t Print::println(const Printable& x)
+size_t Print::println(const Printable &x)
{
size_t n = print(x);
n += println();
@@ -238,12 +252,13 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
// prevent crash if called with base == 1
if (base < 2) base = 10;
- do {
+ do
+ {
char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
- } while(n);
+ } while (n);
return write(str);
}
@@ -254,19 +269,19 @@ size_t Print::printFloat(double number, uint8_t digits)
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
- if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
- if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
+ if (number > 4294967040.0) return print("ovf"); // constant determined empirically
+ if (number < -4294967040.0) return print("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
- n += print('-');
- number = -number;
+ n += print('-');
+ number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
- for (uint8_t i=0; i 0) {
+ if (digits > 0)
+ {
n += print(".");
}
diff --git a/megaavr/cores/coreX-corefiles/api/Print.h b/megaavr/cores/coreX-corefiles/api/Print.h
index 9001cfb..f1498ef 100644
--- a/megaavr/cores/coreX-corefiles/api/Print.h
+++ b/megaavr/cores/coreX-corefiles/api/Print.h
@@ -53,6 +53,10 @@ class Print
return write((const uint8_t *)buffer, size);
}
+ // default to zero, meaning "a single write may block"
+ // should be overriden by subclasses with buffering
+ virtual int availableForWrite() { return 0; }
+
size_t print(const __FlashStringHelper *);
size_t print(const String &);
size_t print(const char[]);
@@ -77,8 +81,9 @@ class Print
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
-
- int16_t printf(const char *format, ...);
+
+ int16_t printf(const char *format, ...) __attribute__ ((format (printf, 2, 3)));
int16_t printf(const __FlashStringHelper *format, ...);
-};
+ virtual void flush() { /* Empty implementation for backward compatibility */ }
+};
diff --git a/megaavr/cores/coreX-corefiles/api/Printable.h b/megaavr/cores/coreX-corefiles/api/Printable.h
index de45907..63f93d4 100644
--- a/megaavr/cores/coreX-corefiles/api/Printable.h
+++ b/megaavr/cores/coreX-corefiles/api/Printable.h
@@ -33,4 +33,3 @@ class Printable
public:
virtual size_t printTo(Print& p) const = 0;
};
-
diff --git a/megaavr/cores/coreX-corefiles/api/RingBuffer.cpp b/megaavr/cores/coreX-corefiles/api/RingBuffer.cpp
index 90cfcbd..ed16b2c 100644
--- a/megaavr/cores/coreX-corefiles/api/RingBuffer.cpp
+++ b/megaavr/cores/coreX-corefiles/api/RingBuffer.cpp
@@ -17,66 +17,73 @@
*/
#include "RingBuffer.h"
-#include
+
#include
#include
+#include
RingBuffer::RingBuffer(rb_index_type size) : size(size)
{
- _aucBuffer = (uint8_t*)malloc(size);
- memset( _aucBuffer, 0, size ) ;
- clear();
+ _aucBuffer = (uint8_t*)malloc(size);
+ memset(_aucBuffer, 0, size);
+ clear();
}
-void RingBuffer::store_char( uint8_t c )
+void RingBuffer::store_char(uint8_t c)
{
- rb_index_type i = nextIndex(_iHead);
-
- // if we should be storing the received character into the location
- // just before the tail (meaning that the head would advance to the
- // current location of the tail), we're about to overflow the buffer
- // and so we don't write the character or advance the head.
- if ( i != _iTail )
+ rb_index_type i = nextIndex(_iHead);
+
+ // if we should be storing the received character into the location
+ // just before the tail (meaning that the head would advance to the
+ // current location of the tail), we're about to overflow the buffer
+ // and so we don't write the character or advance the head.
+ if (i != _iTail)
+ {
+ if (_iHead < size)
{
- if (_iHead < size) {
- _aucBuffer[_iHead] = c ;
- } else {
- additionalBuffer[_iHead - size] = c;
- }
- _iHead = i ;
+ _aucBuffer[_iHead] = c;
}
+ else
+ {
+ additionalBuffer[_iHead - size] = c;
+ }
+ _iHead = i;
+ }
}
void RingBuffer::clear()
{
- _iHead = 0;
- _iTail = 0;
+ _iHead = 0;
+ _iTail = 0;
}
int RingBuffer::read_char()
{
- if(_iTail == _iHead)
- return -1;
-
- uint8_t value;
- if (_iTail < size) {
- value = _aucBuffer[_iTail];
- } else {
- value = additionalBuffer[_iTail - size];
- }
- _iTail = nextIndex(_iTail);
+ if (_iTail == _iHead)
+ return -1;
+
+ uint8_t value;
+ if (_iTail < size)
+ {
+ value = _aucBuffer[_iTail];
+ }
+ else
+ {
+ value = additionalBuffer[_iTail - size];
+ }
+ _iTail = nextIndex(_iTail);
- return value;
+ return value;
}
int RingBuffer::available()
{
- int delta = _iHead - _iTail;
+ int delta = _iHead - _iTail;
- if(delta < 0)
- return size + additionalSize + delta;
- else
- return delta;
+ if (delta < 0)
+ return size + additionalSize + delta;
+ else
+ return delta;
}
int RingBuffer::availableForStore()
@@ -88,25 +95,27 @@ int RingBuffer::availableForStore()
return -delta - 1;
}
-
int RingBuffer::peek()
{
- if(_iTail == _iHead)
- return -1;
+ if (_iTail == _iHead)
+ return -1;
- if (_iTail < size) {
- return _aucBuffer[_iTail];
- } else {
- return additionalBuffer[_iTail - size];
- }
+ if (_iTail < size)
+ {
+ return _aucBuffer[_iTail];
+ }
+ else
+ {
+ return additionalBuffer[_iTail - size];
+ }
}
rb_index_type RingBuffer::nextIndex(rb_index_type index)
{
- return (rb_index_type)(index + 1) % (size + additionalSize);
+ return (rb_index_type)(index + 1) % (size + additionalSize);
}
bool RingBuffer::isFull()
{
- return (nextIndex(_iHead) == _iTail);
+ return (nextIndex(_iHead) == _iTail);
}
diff --git a/megaavr/cores/coreX-corefiles/api/RingBuffer.h b/megaavr/cores/coreX-corefiles/api/RingBuffer.h
index f7fc4a0..95c1baf 100644
--- a/megaavr/cores/coreX-corefiles/api/RingBuffer.h
+++ b/megaavr/cores/coreX-corefiles/api/RingBuffer.h
@@ -36,28 +36,29 @@ typedef unsigned int rb_index_type;
class RingBuffer
{
- public:
- RingBuffer( rb_index_type size = 64 ) ;
- void store_char( uint8_t c ) ;
- void clear();
- int read_char();
- int available();
- int availableForStore();
- int peek();
- bool isFull();
- void addStorage(uint8_t* _buffer, rb_index_type _size) {
- additionalSize = _size;
- additionalBuffer = _buffer;
- };
-
- private:
- rb_index_type nextIndex(rb_index_type index);
- uint8_t* additionalBuffer;
- int additionalSize = 0;
- rb_index_type size;
- uint8_t* _aucBuffer;
- volatile rb_index_type _iHead ;
- volatile rb_index_type _iTail ;
+ public:
+ RingBuffer(rb_index_type size = 64);
+ void store_char(uint8_t c);
+ void clear();
+ int read_char();
+ int available();
+ int availableForStore();
+ int peek();
+ bool isFull();
+ void addStorage(uint8_t* _buffer, rb_index_type _size)
+ {
+ additionalSize = _size;
+ additionalBuffer = _buffer;
+ };
+
+ private:
+ rb_index_type nextIndex(rb_index_type index);
+ uint8_t* additionalBuffer;
+ int additionalSize = 0;
+ rb_index_type size;
+ uint8_t* _aucBuffer;
+ volatile rb_index_type _iHead;
+ volatile rb_index_type _iTail;
};
#endif /* _RING_BUFFER_ */
diff --git a/megaavr/cores/coreX-corefiles/api/Server.h b/megaavr/cores/coreX-corefiles/api/Server.h
index 8675682..fa4593c 100644
--- a/megaavr/cores/coreX-corefiles/api/Server.h
+++ b/megaavr/cores/coreX-corefiles/api/Server.h
@@ -21,8 +21,8 @@
#include "Print.h"
-class Server : public Print {
- public:
- virtual void begin() = 0;
+class Server : public Print
+{
+ public:
+ virtual void begin() = 0;
};
-
diff --git a/megaavr/cores/coreX-corefiles/api/Stream.cpp b/megaavr/cores/coreX-corefiles/api/Stream.cpp
index c16d60f..287165e 100644
--- a/megaavr/cores/coreX-corefiles/api/Stream.cpp
+++ b/megaavr/cores/coreX-corefiles/api/Stream.cpp
@@ -25,18 +25,19 @@
#include "Common.h"
#include "Stream.h"
-#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
+#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
// private method to read stream with timeout
int Stream::timedRead()
{
int c;
_startMillis = millis();
- do {
+ do
+ {
c = read();
if (c >= 0) return c;
- } while(millis() - _startMillis < _timeout);
- return -1; // -1 indicates timeout
+ } while (millis() - _startMillis < _timeout);
+ return -1; // -1 indicates timeout
}
// private method to peek stream with timeout
@@ -44,11 +45,12 @@ int Stream::timedPeek()
{
int c;
_startMillis = millis();
- do {
+ do
+ {
c = peek();
if (c >= 0) return c;
- } while(millis() - _startMillis < _timeout);
- return -1; // -1 indicates timeout
+ } while (millis() - _startMillis < _timeout);
+ return -1; // -1 indicates timeout
}
// returns peek of the next digit in the stream or -1 if timeout
@@ -56,41 +58,47 @@ int Stream::timedPeek()
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
{
int c;
- while (1) {
+ while (1)
+ {
c = timedPeek();
- if( c < 0 ||
+ if (c < 0 ||
c == '-' ||
(c >= '0' && c <= '9') ||
(detectDecimal && c == '.')) return c;
- switch( lookahead ){
- case SKIP_NONE: return -1; // Fail code.
- case SKIP_WHITESPACE:
- switch( c ){
- case ' ':
- case '\t':
- case '\r':
- case '\n': break;
- default: return -1; // Fail code.
- }
- case SKIP_ALL:
+ switch (lookahead)
+ {
+ case SKIP_NONE:
+ return -1; // Fail code.
+ case SKIP_WHITESPACE:
+ switch (c)
+ {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
break;
+ default:
+ return -1; // Fail code.
+ }
+ case SKIP_ALL:
+ break;
}
- read(); // discard non-numeric
+ read(); // discard non-numeric
}
}
// Public Methods
//////////////////////////////////////////////////////////////
-void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
+void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{
_timeout = timeout;
}
- // find returns true if the target string is found
-bool Stream::find(char *target)
+// find returns true if the target string is found
+bool Stream::find(char *target)
{
return findUntil(target, strlen(target), NULL, 0);
}
@@ -103,7 +111,7 @@ bool Stream::find(char *target, size_t length)
}
// as find but search ends if the terminator string is found
-bool Stream::findUntil(char *target, char *terminator)
+bool Stream::findUntil(char *target, char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}
@@ -113,10 +121,13 @@ bool Stream::findUntil(char *target, char *terminator)
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
{
- if (terminator == NULL) {
+ if (terminator == NULL)
+ {
MultiTarget t[1] = {{target, targetLen, 0}};
return findMulti(t, 1) == 0 ? true : false;
- } else {
+ }
+ else
+ {
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
return findMulti(t, 2) == 0 ? true : false;
}
@@ -135,22 +146,22 @@ long Stream::parseInt(LookaheadMode lookahead, char ignore)
c = peekNextDigit(lookahead, false);
// ignore non numeric leading characters
- if(c < 0)
+ if (c < 0)
return 0; // zero returned if timeout
- do{
- if(c == ignore)
+ do
+ {
+ if (c == ignore)
; // ignore this character
- else if(c == '-')
+ else if (c == '-')
isNegative = true;
- else if(c >= '0' && c <= '9') // is c a digit?
+ else if (c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
- read(); // consume the character we got with peek
+ read(); // consume the character we got with peek
c = timedPeek();
- }
- while( (c >= '0' && c <= '9') || c == ignore );
+ } while ((c >= '0' && c <= '9') || c == ignore);
- if(isNegative)
+ if (isNegative)
value = -value;
return value;
}
@@ -165,30 +176,31 @@ float Stream::parseFloat(LookaheadMode lookahead, char ignore)
float fraction = 1.0;
c = peekNextDigit(lookahead, true);
- // ignore non numeric leading characters
- if(c < 0)
+ // ignore non numeric leading characters
+ if (c < 0)
return 0; // zero returned if timeout
- do{
- if(c == ignore)
+ do
+ {
+ if (c == ignore)
; // ignore
- else if(c == '-')
+ else if (c == '-')
isNegative = true;
else if (c == '.')
isFraction = true;
- else if(c >= '0' && c <= '9') { // is c a digit?
+ else if (c >= '0' && c <= '9')
+ { // is c a digit?
value = value * 10 + c - '0';
- if(isFraction)
- fraction *= 0.1;
+ if (isFraction)
+ fraction *= 0.1;
}
- read(); // consume the character we got with peek
+ read(); // consume the character we got with peek
c = timedPeek();
- }
- while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore );
+ } while ((c >= '0' && c <= '9') || (c == '.' && !isFraction) || c == ignore);
- if(isNegative)
+ if (isNegative)
value = -value;
- if(isFraction)
+ if (isFraction)
return value * fraction;
else
return value;
@@ -202,7 +214,8 @@ float Stream::parseFloat(LookaheadMode lookahead, char ignore)
size_t Stream::readBytes(char *buffer, size_t length)
{
size_t count = 0;
- while (count < length) {
+ while (count < length)
+ {
int c = timedRead();
if (c < 0) break;
*buffer++ = (char)c;
@@ -211,7 +224,6 @@ size_t Stream::readBytes(char *buffer, size_t length)
return count;
}
-
// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
@@ -220,7 +232,8 @@ size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{
if (length < 1) return 0;
size_t index = 0;
- while (index < length) {
+ while (index < length)
+ {
int c = timedRead();
if (c < 0 || c == terminator) break;
*buffer++ = (char)c;
@@ -253,22 +266,27 @@ String Stream::readStringUntil(char terminator)
return ret;
}
-int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
+int Stream::findMulti(struct Stream::MultiTarget *targets, int tCount)
+{
// any zero length target string automatically matches and would make
// a mess of the rest of the algorithm.
- for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
+ for (struct MultiTarget *t = targets; t < targets + tCount; ++t)
+ {
if (t->len <= 0)
return t - targets;
}
- while (1) {
+ while (1)
+ {
int c = timedRead();
if (c < 0)
return -1;
- for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
+ for (struct MultiTarget *t = targets; t < targets + tCount; ++t)
+ {
// the simple case is if we match, deal with that first.
- if (c == t->str[t->index]) {
+ if (c == t->str[t->index])
+ {
if (++t->index == t->len)
return t - targets;
else
@@ -283,14 +301,16 @@ int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
continue;
int origIndex = t->index;
- do {
+ do
+ {
--t->index;
// first check if current char works against the new current index
if (c != t->str[t->index])
continue;
// if it's the only char then we're good, nothing more to check
- if (t->index == 0) {
+ if (t->index == 0)
+ {
t->index++;
break;
}
@@ -298,14 +318,16 @@ int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
// otherwise we need to check the rest of the found string
int diff = origIndex - t->index;
size_t i;
- for (i = 0; i < t->index; ++i) {
+ for (i = 0; i < t->index; ++i)
+ {
if (t->str[i] != t->str[i + diff])
break;
}
// if we successfully got through the previous loop then our current
// index is good.
- if (i == t->index) {
+ if (i == t->index)
+ {
t->index++;
break;
}
diff --git a/megaavr/cores/coreX-corefiles/api/Stream.h b/megaavr/cores/coreX-corefiles/api/Stream.h
index 7dbe2fd..dd0645e 100644
--- a/megaavr/cores/coreX-corefiles/api/Stream.h
+++ b/megaavr/cores/coreX-corefiles/api/Stream.h
@@ -22,6 +22,7 @@
#pragma once
#include
+
#include "Print.h"
// compatability macros for testing
@@ -37,51 +38,51 @@ readBytesBetween( pre_string, terminator, buffer, length)
// This enumeration provides the lookahead options for parseInt(), parseFloat()
// The rules set out here are used until either the first valid character is found
// or a time out occurs due to lack of input.
-enum LookaheadMode{
- SKIP_ALL, // All invalid characters are ignored.
- SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
- SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
+enum LookaheadMode
+{
+ SKIP_ALL, // All invalid characters are ignored.
+ SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
+ SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
};
-#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
+#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
class Stream : public Print
{
- protected:
- unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
- unsigned long _startMillis; // used for timeout measurement
- int timedRead(); // private method to read stream with timeout
- int timedPeek(); // private method to peek stream with timeout
- int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
+ protected:
+ unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
+ unsigned long _startMillis; // used for timeout measurement
+ int timedRead(); // private method to read stream with timeout
+ int timedPeek(); // private method to peek stream with timeout
+ int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
- public:
- virtual int available() = 0;
- virtual int read() = 0;
- virtual int peek() = 0;
- virtual void flush() = 0;
+ public:
+ virtual int available() = 0;
+ virtual int read() = 0;
+ virtual int peek() = 0;
- Stream() {_timeout=1000;}
+ Stream() { _timeout = 1000; }
-// parsing methods
+ // parsing methods
- void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
+ void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
unsigned long getTimeout(void) { return _timeout; }
-
- bool find(char *target); // reads data from the stream until the target string is found
- bool find(uint8_t *target) { return find ((char *)target); }
+
+ bool find(char *target); // reads data from the stream until the target string is found
+ bool find(uint8_t *target) { return find((char *)target); }
// returns true if target string is found, false if timed out (see setTimeout)
- bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
- bool find(uint8_t *target, size_t length) { return find ((char *)target, length); }
+ bool find(char *target, size_t length); // reads data from the stream until the target string of given length is found
+ bool find(uint8_t *target, size_t length) { return find((char *)target, length); }
// returns true if target string is found, false if timed out
- bool find(char target) { return find (&target, 1); }
+ bool find(char target) { return find(&target, 1); }
- bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
+ bool findUntil(char *target, char *terminator); // as find but search ends if the terminator string is found
bool findUntil(uint8_t *target, char *terminator) { return findUntil((char *)target, terminator); }
- bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
- bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((char *)target, targetLen, terminate, termLen); }
+ bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen); // as above but search ends if the terminate string is found
+ bool findUntil(uint8_t *target, size_t targetLen, char *terminate, size_t termLen) { return findUntil((char *)target, targetLen, terminate, termLen); }
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// returns the first valid (long) integer value from the current position.
@@ -93,13 +94,13 @@ class Stream : public Print
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// float version of parseInt
- size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
- size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
+ size_t readBytes(char *buffer, size_t length); // read chars from stream into buffer
+ size_t readBytes(uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
- size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
- size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
+ size_t readBytesUntil(char terminator, char *buffer, size_t length); // as readBytes with terminator character
+ size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
@@ -107,17 +108,18 @@ class Stream : public Print
String readString();
String readStringUntil(char terminator);
- protected:
+ protected:
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
// These overload exists for compatibility with any class that has derived
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected.
- struct MultiTarget {
- const char *str; // string you're searching for
- size_t len; // length of string you're searching for
- size_t index; // index used by the search routine.
+ struct MultiTarget
+ {
+ const char *str; // string you're searching for
+ size_t len; // length of string you're searching for
+ size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
diff --git a/megaavr/cores/coreX-corefiles/api/String.cpp b/megaavr/cores/coreX-corefiles/api/String.cpp
index 5a5d710..6efc5f0 100644
--- a/megaavr/cores/coreX-corefiles/api/String.cpp
+++ b/megaavr/cores/coreX-corefiles/api/String.cpp
@@ -29,101 +29,101 @@
String::String(const char *cstr)
{
- init();
- if (cstr) copy(cstr, strlen(cstr));
+ init();
+ if (cstr) copy(cstr, strlen(cstr));
}
String::String(const String &value)
{
- init();
- *this = value;
+ init();
+ *this = value;
}
String::String(const __FlashStringHelper *pstr)
{
- init();
- *this = pstr;
+ init();
+ *this = pstr;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String::String(String &&rval)
{
- init();
- move(rval);
+ init();
+ move(rval);
}
String::String(StringSumHelper &&rval)
{
- init();
- move(rval);
+ init();
+ move(rval);
}
#endif
String::String(char c)
{
- init();
- char buf[2];
- buf[0] = c;
- buf[1] = 0;
- *this = buf;
+ init();
+ char buf[2];
+ buf[0] = c;
+ buf[1] = 0;
+ *this = buf;
}
String::String(unsigned char value, unsigned char base)
{
- init();
- char buf[1 + 8 * sizeof(unsigned char)];
- utoa(value, buf, base);
- *this = buf;
+ init();
+ char buf[1 + 8 * sizeof(unsigned char)];
+ utoa(value, buf, base);
+ *this = buf;
}
String::String(int value, unsigned char base)
{
- init();
- char buf[2 + 8 * sizeof(int)];
- itoa(value, buf, base);
- *this = buf;
+ init();
+ char buf[2 + 8 * sizeof(int)];
+ itoa(value, buf, base);
+ *this = buf;
}
String::String(unsigned int value, unsigned char base)
{
- init();
- char buf[1 + 8 * sizeof(unsigned int)];
- utoa(value, buf, base);
- *this = buf;
+ init();
+ char buf[1 + 8 * sizeof(unsigned int)];
+ utoa(value, buf, base);
+ *this = buf;
}
String::String(long value, unsigned char base)
{
- init();
- char buf[2 + 8 * sizeof(long)];
- ltoa(value, buf, base);
- *this = buf;
+ init();
+ char buf[2 + 8 * sizeof(long)];
+ ltoa(value, buf, base);
+ *this = buf;
}
String::String(unsigned long value, unsigned char base)
{
- init();
- char buf[1 + 8 * sizeof(unsigned long)];
- ultoa(value, buf, base);
- *this = buf;
+ init();
+ char buf[1 + 8 * sizeof(unsigned long)];
+ ultoa(value, buf, base);
+ *this = buf;
}
String::String(float value, unsigned char decimalPlaces)
{
- init();
- char buf[33];
- *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
+ init();
+ char buf[33];
+ *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::String(double value, unsigned char decimalPlaces)
{
- init();
- char buf[33];
- *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
+ init();
+ char buf[33];
+ *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::~String()
{
- free(buffer);
+ free(buffer);
}
/*********************************************/
@@ -132,125 +132,139 @@ String::~String()
inline void String::init(void)
{
- buffer = NULL;
- capacity = 0;
- len = 0;
+ buffer = NULL;
+ capacity = 0;
+ len = 0;
}
void String::invalidate(void)
{
- if (buffer) free(buffer);
- buffer = NULL;
- capacity = len = 0;
+ if (buffer) free(buffer);
+ buffer = NULL;
+ capacity = len = 0;
}
unsigned char String::reserve(unsigned int size)
{
- if (buffer && capacity >= size) return 1;
- if (changeBuffer(size)) {
- if (len == 0) buffer[0] = 0;
- return 1;
- }
- return 0;
+ if (buffer && capacity >= size) return 1;
+ if (changeBuffer(size))
+ {
+ if (len == 0) buffer[0] = 0;
+ return 1;
+ }
+ return 0;
}
unsigned char String::changeBuffer(unsigned int maxStrLen)
{
- char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
- if (newbuffer) {
- buffer = newbuffer;
- capacity = maxStrLen;
- return 1;
- }
- return 0;
+ char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
+ if (newbuffer)
+ {
+ buffer = newbuffer;
+ capacity = maxStrLen;
+ return 1;
+ }
+ return 0;
}
/*********************************************/
/* Copy and Move */
/*********************************************/
-String & String::copy(const char *cstr, unsigned int length)
+String &String::copy(const char *cstr, unsigned int length)
{
- if (!reserve(length)) {
- invalidate();
- return *this;
- }
- len = length;
- strcpy(buffer, cstr);
- return *this;
+ if (!reserve(length))
+ {
+ invalidate();
+ return *this;
+ }
+ len = length;
+ strcpy(buffer, cstr);
+ return *this;
}
-String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
+String &String::copy(const __FlashStringHelper *pstr, unsigned int length)
{
- if (!reserve(length)) {
- invalidate();
- return *this;
- }
- len = length;
- strcpy_P(buffer, (PGM_P)pstr);
- return *this;
+ if (!reserve(length))
+ {
+ invalidate();
+ return *this;
+ }
+ len = length;
+ strcpy_P(buffer, (PGM_P)pstr);
+ return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void String::move(String &rhs)
{
- if (buffer) {
- if (rhs && capacity >= rhs.len) {
- strcpy(buffer, rhs.buffer);
- len = rhs.len;
- rhs.len = 0;
- return;
- } else {
- free(buffer);
- }
- }
- buffer = rhs.buffer;
- capacity = rhs.capacity;
- len = rhs.len;
- rhs.buffer = NULL;
- rhs.capacity = 0;
- rhs.len = 0;
+ if (buffer)
+ {
+ if (rhs && capacity >= rhs.len)
+ {
+ strcpy(buffer, rhs.buffer);
+ len = rhs.len;
+ rhs.len = 0;
+ return;
+ }
+ else
+ {
+ free(buffer);
+ }
+ }
+ buffer = rhs.buffer;
+ capacity = rhs.capacity;
+ len = rhs.len;
+ rhs.buffer = NULL;
+ rhs.capacity = 0;
+ rhs.len = 0;
}
#endif
-String & String::operator = (const String &rhs)
+String &String::operator=(const String &rhs)
{
- if (this == &rhs) return *this;
-
- if (rhs.buffer) copy(rhs.buffer, rhs.len);
- else invalidate();
-
- return *this;
+ if (this == &rhs) return *this;
+
+ if (rhs.buffer)
+ copy(rhs.buffer, rhs.len);
+ else
+ invalidate();
+
+ return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
-String & String::operator = (String &&rval)
+String &String::operator=(String &&rval)
{
- if (this != &rval) move(rval);
- return *this;
+ if (this != &rval) move(rval);
+ return *this;
}
-String & String::operator = (StringSumHelper &&rval)
+String &String::operator=(StringSumHelper &&rval)
{
- if (this != &rval) move(rval);
- return *this;
+ if (this != &rval) move(rval);
+ return *this;
}
#endif
-String & String::operator = (const char *cstr)
+String &String::operator=(const char *cstr)
{
- if (cstr) copy(cstr, strlen(cstr));
- else invalidate();
-
- return *this;
+ if (cstr)
+ copy(cstr, strlen(cstr));
+ else
+ invalidate();
+
+ return *this;
}
-String & String::operator = (const __FlashStringHelper *pstr)
+String &String::operator=(const __FlashStringHelper *pstr)
{
- if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
- else invalidate();
+ if (pstr)
+ copy(pstr, strlen_P((PGM_P)pstr));
+ else
+ invalidate();
- return *this;
+ return *this;
}
/*********************************************/
@@ -259,174 +273,174 @@ String & String::operator = (const __FlashStringHelper *pstr)
unsigned char String::concat(const String &s)
{
- return concat(s.buffer, s.len);
+ return concat(s.buffer, s.len);
}
unsigned char String::concat(const char *cstr, unsigned int length)
{
- unsigned int newlen = len + length;
- if (!cstr) return 0;
- if (length == 0) return 1;
- if (!reserve(newlen)) return 0;
- strcpy(buffer + len, cstr);
- len = newlen;
- return 1;
+ unsigned int newlen = len + length;
+ if (!cstr) return 0;
+ if (length == 0) return 1;
+ if (!reserve(newlen)) return 0;
+ strcpy(buffer + len, cstr);
+ len = newlen;
+ return 1;
}
unsigned char String::concat(const char *cstr)
{
- if (!cstr) return 0;
- return concat(cstr, strlen(cstr));
+ if (!cstr) return 0;
+ return concat(cstr, strlen(cstr));
}
unsigned char String::concat(char c)
{
- char buf[2];
- buf[0] = c;
- buf[1] = 0;
- return concat(buf, 1);
+ char buf[2];
+ buf[0] = c;
+ buf[1] = 0;
+ return concat(buf, 1);
}
unsigned char String::concat(unsigned char num)
{
- char buf[1 + 3 * sizeof(unsigned char)];
- itoa(num, buf, 10);
- return concat(buf, strlen(buf));
+ char buf[1 + 3 * sizeof(unsigned char)];
+ itoa(num, buf, 10);
+ return concat(buf, strlen(buf));
}
unsigned char String::concat(int num)
{
- char buf[2 + 3 * sizeof(int)];
- itoa(num, buf, 10);
- return concat(buf, strlen(buf));
+ char buf[2 + 3 * sizeof(int)];
+ itoa(num, buf, 10);
+ return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned int num)
{
- char buf[1 + 3 * sizeof(unsigned int)];
- utoa(num, buf, 10);
- return concat(buf, strlen(buf));
+ char buf[1 + 3 * sizeof(unsigned int)];
+ utoa(num, buf, 10);
+ return concat(buf, strlen(buf));
}
unsigned char String::concat(long num)
{
- char buf[2 + 3 * sizeof(long)];
- ltoa(num, buf, 10);
- return concat(buf, strlen(buf));
+ char buf[2 + 3 * sizeof(long)];
+ ltoa(num, buf, 10);
+ return concat(buf, strlen(buf));
}
unsigned char String::concat(unsigned long num)
{
- char buf[1 + 3 * sizeof(unsigned long)];
- ultoa(num, buf, 10);
- return concat(buf, strlen(buf));
+ char buf[1 + 3 * sizeof(unsigned long)];
+ ultoa(num, buf, 10);
+ return concat(buf, strlen(buf));
}
unsigned char String::concat(float num)
{
- char buf[20];
- char* string = dtostrf(num, 4, 2, buf);
- return concat(string, strlen(string));
+ char buf[20];
+ char *string = dtostrf(num, 4, 2, buf);
+ return concat(string, strlen(string));
}
unsigned char String::concat(double num)
{
- char buf[20];
- char* string = dtostrf(num, 4, 2, buf);
- return concat(string, strlen(string));
+ char buf[20];
+ char *string = dtostrf(num, 4, 2, buf);
+ return concat(string, strlen(string));
}
-unsigned char String::concat(const __FlashStringHelper * str)
+unsigned char String::concat(const __FlashStringHelper *str)
{
- if (!str) return 0;
- int length = strlen_P((const char *) str);
- if (length == 0) return 1;
- unsigned int newlen = len + length;
- if (!reserve(newlen)) return 0;
- strcpy_P(buffer + len, (const char *) str);
- len = newlen;
- return 1;
+ if (!str) return 0;
+ int length = strlen_P((const char *)str);
+ if (length == 0) return 1;
+ unsigned int newlen = len + length;
+ if (!reserve(newlen)) return 0;
+ strcpy_P(buffer + len, (const char *)str);
+ len = newlen;
+ return 1;
}
/*********************************************/
/* Concatenate */
/*********************************************/
-StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
+StringSumHelper &operator+(const StringSumHelper &lhs, const String &rhs)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
+StringSumHelper &operator+(const StringSumHelper &lhs, const char *cstr)
{
- StringSumHelper &a = const_cast(lhs);
- if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, char c)
+StringSumHelper &operator+(const StringSumHelper &lhs, char c)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(c)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(c)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
+StringSumHelper &operator+(const StringSumHelper &lhs, unsigned char num)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(num)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(num)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, int num)
+StringSumHelper &operator+(const StringSumHelper &lhs, int num)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(num)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(num)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
+StringSumHelper &operator+(const StringSumHelper &lhs, unsigned int num)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(num)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(num)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, long num)
+StringSumHelper &operator+(const StringSumHelper &lhs, long num)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(num)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(num)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
+StringSumHelper &operator+(const StringSumHelper &lhs, unsigned long num)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(num)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(num)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, float num)
+StringSumHelper &operator+(const StringSumHelper &lhs, float num)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(num)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(num)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, double num)
+StringSumHelper &operator+(const StringSumHelper &lhs, double num)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(num)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(num)) a.invalidate();
+ return a;
}
-StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
+StringSumHelper &operator+(const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
- StringSumHelper &a = const_cast(lhs);
- if (!a.concat(rhs)) a.invalidate();
- return a;
+ StringSumHelper &a = const_cast(lhs);
+ if (!a.concat(rhs)) a.invalidate();
+ return a;
}
/*********************************************/
@@ -435,75 +449,77 @@ StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHel
int String::compareTo(const String &s) const
{
- if (!buffer || !s.buffer) {
- if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
- if (buffer && len > 0) return *(unsigned char *)buffer;
- return 0;
- }
- return strcmp(buffer, s.buffer);
+ if (!buffer || !s.buffer)
+ {
+ if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
+ if (buffer && len > 0) return *(unsigned char *)buffer;
+ return 0;
+ }
+ return strcmp(buffer, s.buffer);
}
unsigned char String::equals(const String &s2) const
{
- return (len == s2.len && compareTo(s2) == 0);
+ return (len == s2.len && compareTo(s2) == 0);
}
unsigned char String::equals(const char *cstr) const
{
- if (len == 0) return (cstr == NULL || *cstr == 0);
- if (cstr == NULL) return buffer[0] == 0;
- return strcmp(buffer, cstr) == 0;
+ if (len == 0) return (cstr == NULL || *cstr == 0);
+ if (cstr == NULL) return buffer[0] == 0;
+ return strcmp(buffer, cstr) == 0;
}
unsigned char String::operator<(const String &rhs) const
{
- return compareTo(rhs) < 0;
+ return compareTo(rhs) < 0;
}
unsigned char String::operator>(const String &rhs) const
{
- return compareTo(rhs) > 0;
+ return compareTo(rhs) > 0;
}
unsigned char String::operator<=(const String &rhs) const
{
- return compareTo(rhs) <= 0;
+ return compareTo(rhs) <= 0;
}
unsigned char String::operator>=(const String &rhs) const
{
- return compareTo(rhs) >= 0;
+ return compareTo(rhs) >= 0;
}
-unsigned char String::equalsIgnoreCase( const String &s2 ) const
+unsigned char String::equalsIgnoreCase(const String &s2) const
{
- if (this == &s2) return 1;
- if (len != s2.len) return 0;
- if (len == 0) return 1;
- const char *p1 = buffer;
- const char *p2 = s2.buffer;
- while (*p1) {
- if (tolower(*p1++) != tolower(*p2++)) return 0;
- }
- return 1;
+ if (this == &s2) return 1;
+ if (len != s2.len) return 0;
+ if (len == 0) return 1;
+ const char *p1 = buffer;
+ const char *p2 = s2.buffer;
+ while (*p1)
+ {
+ if (tolower(*p1++) != tolower(*p2++)) return 0;
+ }
+ return 1;
}
-unsigned char String::startsWith( const String &s2 ) const
+unsigned char String::startsWith(const String &s2) const
{
- if (len < s2.len) return 0;
- return startsWith(s2, 0);
+ if (len < s2.len) return 0;
+ return startsWith(s2, 0);
}
-unsigned char String::startsWith( const String &s2, unsigned int offset ) const
+unsigned char String::startsWith(const String &s2, unsigned int offset) const
{
- if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
- return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
+ if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
+ return strncmp(&buffer[offset], s2.buffer, s2.len) == 0;
}
-unsigned char String::endsWith( const String &s2 ) const
+unsigned char String::endsWith(const String &s2) const
{
- if ( len < s2.len || !buffer || !s2.buffer) return 0;
- return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
+ if (len < s2.len || !buffer || !s2.buffer) return 0;
+ return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}
/*********************************************/
@@ -512,41 +528,43 @@ unsigned char String::endsWith( const String &s2 ) const
char String::charAt(unsigned int loc) const
{
- return operator[](loc);
+ return operator[](loc);
}
-void String::setCharAt(unsigned int loc, char c)
+void String::setCharAt(unsigned int loc, char c)
{
- if (loc < len) buffer[loc] = c;
+ if (loc < len) buffer[loc] = c;
}
-char & String::operator[](unsigned int index)
+char &String::operator[](unsigned int index)
{
- static char dummy_writable_char;
- if (index >= len || !buffer) {
- dummy_writable_char = 0;
- return dummy_writable_char;
- }
- return buffer[index];
+ static char dummy_writable_char;
+ if (index >= len || !buffer)
+ {
+ dummy_writable_char = 0;
+ return dummy_writable_char;
+ }
+ return buffer[index];
}
-char String::operator[]( unsigned int index ) const
+char String::operator[](unsigned int index) const
{
- if (index >= len || !buffer) return 0;
- return buffer[index];
+ if (index >= len || !buffer) return 0;
+ return buffer[index];
}
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{
- if (!bufsize || !buf) return;
- if (index >= len) {
- buf[0] = 0;
- return;
- }
- unsigned int n = bufsize - 1;
- if (n > len - index) n = len - index;
- strncpy((char *)buf, buffer + index, n);
- buf[n] = 0;
+ if (!bufsize || !buf) return;
+ if (index >= len)
+ {
+ buf[0] = 0;
+ return;
+ }
+ unsigned int n = bufsize - 1;
+ if (n > len - index) n = len - index;
+ strncpy((char *)buf, buffer + index, n);
+ buf[n] = 0;
}
/*********************************************/
@@ -555,79 +573,81 @@ void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int ind
int String::indexOf(char c) const
{
- return indexOf(c, 0);
+ return indexOf(c, 0);
}
-int String::indexOf( char ch, unsigned int fromIndex ) const
+int String::indexOf(char ch, unsigned int fromIndex) const
{
- if (fromIndex >= len) return -1;
- const char* temp = strchr(buffer + fromIndex, ch);
- if (temp == NULL) return -1;
- return temp - buffer;
+ if (fromIndex >= len) return -1;
+ const char *temp = strchr(buffer + fromIndex, ch);
+ if (temp == NULL) return -1;
+ return temp - buffer;
}
int String::indexOf(const String &s2) const
{
- return indexOf(s2, 0);
+ return indexOf(s2, 0);
}
int String::indexOf(const String &s2, unsigned int fromIndex) const
{
- if (fromIndex >= len) return -1;
- const char *found = strstr(buffer + fromIndex, s2.buffer);
- if (found == NULL) return -1;
- return found - buffer;
+ if (fromIndex >= len) return -1;
+ const char *found = strstr(buffer + fromIndex, s2.buffer);
+ if (found == NULL) return -1;
+ return found - buffer;
}
-int String::lastIndexOf( char theChar ) const
+int String::lastIndexOf(char theChar) const
{
- return lastIndexOf(theChar, len - 1);
+ return lastIndexOf(theChar, len - 1);
}
int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
- if (fromIndex >= len) return -1;
- char tempchar = buffer[fromIndex + 1];
- buffer[fromIndex + 1] = '\0';
- char* temp = strrchr( buffer, ch );
- buffer[fromIndex + 1] = tempchar;
- if (temp == NULL) return -1;
- return temp - buffer;
+ if (fromIndex >= len) return -1;
+ char tempchar = buffer[fromIndex + 1];
+ buffer[fromIndex + 1] = '\0';
+ char *temp = strrchr(buffer, ch);
+ buffer[fromIndex + 1] = tempchar;
+ if (temp == NULL) return -1;
+ return temp - buffer;
}
int String::lastIndexOf(const String &s2) const
{
- return lastIndexOf(s2, len - s2.len);
+ return lastIndexOf(s2, len - s2.len);
}
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
{
- if (s2.len == 0 || len == 0 || s2.len > len) return -1;
- if (fromIndex >= len) fromIndex = len - 1;
- int found = -1;
- for (char *p = buffer; p <= buffer + fromIndex; p++) {
- p = strstr(p, s2.buffer);
- if (!p) break;
- if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
- }
- return found;
+ if (s2.len == 0 || len == 0 || s2.len > len) return -1;
+ if (fromIndex >= len) fromIndex = len - 1;
+ int found = -1;
+ for (char *p = buffer; p <= buffer + fromIndex; p++)
+ {
+ p = strstr(p, s2.buffer);
+ if (!p) break;
+ if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
+ }
+ return found;
}
String String::substring(unsigned int left, unsigned int right) const
{
- if (left > right) {
- unsigned int temp = right;
- right = left;
- left = temp;
- }
- String out;
- if (left >= len) return out;
- if (right > len) right = len;
- char temp = buffer[right]; // save the replaced character
- buffer[right] = '\0';
- out = buffer + left; // pointer arithmetic
- buffer[right] = temp; //restore character
- return out;
+ if (left > right)
+ {
+ unsigned int temp = right;
+ right = left;
+ left = temp;
+ }
+ String out;
+ if (left >= len) return out;
+ if (right > len) right = len;
+ char temp = buffer[right]; // save the replaced character
+ buffer[right] = '\0';
+ out = buffer + left; // pointer arithmetic
+ buffer[right] = temp; //restore character
+ return out;
}
/*********************************************/
@@ -636,98 +656,121 @@ String String::substring(unsigned int left, unsigned int right) const
void String::replace(char find, char replace)
{
- if (!buffer) return;
- for (char *p = buffer; *p; p++) {
- if (*p == find) *p = replace;
- }
-}
-
-void String::replace(const String& find, const String& replace)
-{
- if (len == 0 || find.len == 0) return;
- int diff = replace.len - find.len;
- char *readFrom = buffer;
- char *foundAt;
- if (diff == 0) {
- while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
- memcpy(foundAt, replace.buffer, replace.len);
- readFrom = foundAt + replace.len;
- }
- } else if (diff < 0) {
- char *writeTo = buffer;
- while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
- unsigned int n = foundAt - readFrom;
- memcpy(writeTo, readFrom, n);
- writeTo += n;
- memcpy(writeTo, replace.buffer, replace.len);
- writeTo += replace.len;
- readFrom = foundAt + find.len;
- len += diff;
- }
- strcpy(writeTo, readFrom);
- } else {
- unsigned int size = len; // compute size needed for result
- while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
- readFrom = foundAt + find.len;
- size += diff;
- }
- if (size == len) return;
- if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
- int index = len - 1;
- while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
- readFrom = buffer + index + find.len;
- memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
- len += diff;
- buffer[len] = 0;
- memcpy(buffer + index, replace.buffer, replace.len);
- index--;
- }
- }
-}
-
-void String::remove(unsigned int index){
- // Pass the biggest integer as the count. The remove method
- // below will take care of truncating it at the end of the
- // string.
- remove(index, (unsigned int)-1);
-}
-
-void String::remove(unsigned int index, unsigned int count){
- if (index >= len) { return; }
- if (count <= 0) { return; }
- if (count > len - index) { count = len - index; }
- char *writeTo = buffer + index;
- len = len - count;
- strncpy(writeTo, buffer + index + count,len - index);
- buffer[len] = 0;
+ if (!buffer) return;
+ for (char *p = buffer; *p; p++)
+ {
+ if (*p == find) *p = replace;
+ }
+}
+
+void String::replace(const String &find, const String &replace)
+{
+ if (len == 0 || find.len == 0) return;
+ int diff = replace.len - find.len;
+ char *readFrom = buffer;
+ char *foundAt;
+ if (diff == 0)
+ {
+ while ((foundAt = strstr(readFrom, find.buffer)) != NULL)
+ {
+ memcpy(foundAt, replace.buffer, replace.len);
+ readFrom = foundAt + replace.len;
+ }
+ }
+ else if (diff < 0)
+ {
+ char *writeTo = buffer;
+ while ((foundAt = strstr(readFrom, find.buffer)) != NULL)
+ {
+ unsigned int n = foundAt - readFrom;
+ memcpy(writeTo, readFrom, n);
+ writeTo += n;
+ memcpy(writeTo, replace.buffer, replace.len);
+ writeTo += replace.len;
+ readFrom = foundAt + find.len;
+ len += diff;
+ }
+ strcpy(writeTo, readFrom);
+ }
+ else
+ {
+ unsigned int size = len; // compute size needed for result
+ while ((foundAt = strstr(readFrom, find.buffer)) != NULL)
+ {
+ readFrom = foundAt + find.len;
+ size += diff;
+ }
+ if (size == len) return;
+ if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
+ int index = len - 1;
+ while (index >= 0 && (index = lastIndexOf(find, index)) >= 0)
+ {
+ readFrom = buffer + index + find.len;
+ memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
+ len += diff;
+ buffer[len] = 0;
+ memcpy(buffer + index, replace.buffer, replace.len);
+ index--;
+ }
+ }
+}
+
+void String::remove(unsigned int index)
+{
+ // Pass the biggest integer as the count. The remove method
+ // below will take care of truncating it at the end of the
+ // string.
+ remove(index, (unsigned int)-1);
+}
+
+void String::remove(unsigned int index, unsigned int count)
+{
+ if (index >= len)
+ {
+ return;
+ }
+ if (count <= 0)
+ {
+ return;
+ }
+ if (count > len - index)
+ {
+ count = len - index;
+ }
+ char *writeTo = buffer + index;
+ len = len - count;
+ strncpy(writeTo, buffer + index + count, len - index);
+ buffer[len] = 0;
}
void String::toLowerCase(void)
{
- if (!buffer) return;
- for (char *p = buffer; *p; p++) {
- *p = tolower(*p);
- }
+ if (!buffer) return;
+ for (char *p = buffer; *p; p++)
+ {
+ *p = tolower(*p);
+ }
}
void String::toUpperCase(void)
{
- if (!buffer) return;
- for (char *p = buffer; *p; p++) {
- *p = toupper(*p);
- }
+ if (!buffer) return;
+ for (char *p = buffer; *p; p++)
+ {
+ *p = toupper(*p);
+ }
}
void String::trim(void)
{
- if (!buffer || len == 0) return;
- char *begin = buffer;
- while (isspace(*begin)) begin++;
- char *end = buffer + len - 1;
- while (isspace(*end) && end >= begin) end--;
- len = end + 1 - begin;
- if (begin > buffer) memcpy(buffer, begin, len);
- buffer[len] = 0;
+ if (!buffer || len == 0) return;
+ char *begin = buffer;
+ while (isspace(*begin)) begin++;
+ char *end = buffer + len - 1;
+ while (isspace(*end) && end >= begin) end--;
+ len = end + 1 - begin;
+ if (begin > buffer) memcpy(buffer, begin, len);
+ buffer[len] = 0;
}
/*********************************************/
@@ -736,17 +779,17 @@ void String::trim(void)
long String::toInt(void) const
{
- if (buffer) return atol(buffer);
- return 0;
+ if (buffer) return atol(buffer);
+ return 0;
}
float String::toFloat(void) const
{
- return float(toDouble());
+ return float(toDouble());
}
double String::toDouble(void) const
{
- if (buffer) return atof(buffer);
- return 0;
+ if (buffer) return atof(buffer);
+ return 0;
}
diff --git a/megaavr/cores/coreX-corefiles/api/String.h b/megaavr/cores/coreX-corefiles/api/String.h
index f2c6dd9..db5230e 100644
--- a/megaavr/cores/coreX-corefiles/api/String.h
+++ b/megaavr/cores/coreX-corefiles/api/String.h
@@ -48,185 +48,231 @@ class StringSumHelper;
// The string class
class String
{
- // use a function pointer to allow for "if (s)" without the
- // complications of an operator bool(). for more information, see:
- // http://www.artima.com/cppsource/safebool.html
- typedef void (String::*StringIfHelperType)() const;
- void StringIfHelper() const {}
-
-public:
- // constructors
- // creates a copy of the initial value.
- // if the initial value is null or invalid, or if memory allocation
- // fails, the string will be marked as invalid (i.e. "if (s)" will
- // be false).
- String(const char *cstr = "");
- String(const String &str);
- String(const __FlashStringHelper *str);
- #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
- String(String &&rval);
- String(StringSumHelper &&rval);
- #endif
- explicit String(char c);
- explicit String(unsigned char, unsigned char base=10);
- explicit String(int, unsigned char base=10);
- explicit String(unsigned int, unsigned char base=10);
- explicit String(long, unsigned char base=10);
- explicit String(unsigned long, unsigned char base=10);
- explicit String(float, unsigned char decimalPlaces=2);
- explicit String(double, unsigned char decimalPlaces=2);
- ~String(void);
-
- // memory management
- // return true on success, false on failure (in which case, the string
- // is left unchanged). reserve(0), if successful, will validate an
- // invalid string (i.e., "if (s)" will be true afterwards)
- unsigned char reserve(unsigned int size);
- inline unsigned int length(void) const {return len;}
-
- // creates a copy of the assigned value. if the value is null or
- // invalid, or if the memory allocation fails, the string will be
- // marked as invalid ("if (s)" will be false).
- String & operator = (const String &rhs);
- String & operator = (const char *cstr);
- String & operator = (const __FlashStringHelper *str);
- #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
- String & operator = (String &&rval);
- String & operator = (StringSumHelper &&rval);
- #endif
-
- // concatenate (works w/ built-in types)
-
- // returns true on success, false on failure (in which case, the string
- // is left unchanged). if the argument is null or invalid, the
- // concatenation is considered unsucessful.
- unsigned char concat(const String &str);
- unsigned char concat(const char *cstr);
- unsigned char concat(char c);
- unsigned char concat(unsigned char c);
- unsigned char concat(int num);
- unsigned char concat(unsigned int num);
- unsigned char concat(long num);
- unsigned char concat(unsigned long num);
- unsigned char concat(float num);
- unsigned char concat(double num);
- unsigned char concat(const __FlashStringHelper * str);
-
- // if there's not enough memory for the concatenated value, the string
- // will be left unchanged (but this isn't signalled in any way)
- String & operator += (const String &rhs) {concat(rhs); return (*this);}
- String & operator += (const char *cstr) {concat(cstr); return (*this);}
- String & operator += (char c) {concat(c); return (*this);}
- String & operator += (unsigned char num) {concat(num); return (*this);}
- String & operator += (int num) {concat(num); return (*this);}
- String & operator += (unsigned int num) {concat(num); return (*this);}
- String & operator += (long num) {concat(num); return (*this);}
- String & operator += (unsigned long num) {concat(num); return (*this);}
- String & operator += (float num) {concat(num); return (*this);}
- String & operator += (double num) {concat(num); return (*this);}
- String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
-
- friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
- friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
-
- // comparison (only works w/ Strings and "strings")
- operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
- int compareTo(const String &s) const;
- unsigned char equals(const String &s) const;
- unsigned char equals(const char *cstr) const;
- unsigned char operator == (const String &rhs) const {return equals(rhs);}
- unsigned char operator == (const char *cstr) const {return equals(cstr);}
- unsigned char operator != (const String &rhs) const {return !equals(rhs);}
- unsigned char operator != (const char *cstr) const {return !equals(cstr);}
- unsigned char operator < (const String &rhs) const;
- unsigned char operator > (const String &rhs) const;
- unsigned char operator <= (const String &rhs) const;
- unsigned char operator >= (const String &rhs) const;
- unsigned char equalsIgnoreCase(const String &s) const;
- unsigned char startsWith( const String &prefix) const;
- unsigned char startsWith(const String &prefix, unsigned int offset) const;
- unsigned char endsWith(const String &suffix) const;
-
- // character acccess
- char charAt(unsigned int index) const;
- void setCharAt(unsigned int index, char c);
- char operator [] (unsigned int index) const;
- char& operator [] (unsigned int index);
- void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
- void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
- { getBytes((unsigned char *)buf, bufsize, index); }
- const char* c_str() const { return buffer; }
- char* begin() { return buffer; }
- char* end() { return buffer + length(); }
- const char* begin() const { return c_str(); }
- const char* end() const { return c_str() + length(); }
-
- // search
- int indexOf( char ch ) const;
- int indexOf( char ch, unsigned int fromIndex ) const;
- int indexOf( const String &str ) const;
- int indexOf( const String &str, unsigned int fromIndex ) const;
- int lastIndexOf( char ch ) const;
- int lastIndexOf( char ch, unsigned int fromIndex ) const;
- int lastIndexOf( const String &str ) const;
- int lastIndexOf( const String &str, unsigned int fromIndex ) const;
- String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
- String substring( unsigned int beginIndex, unsigned int endIndex ) const;
-
- // modification
- void replace(char find, char replace);
- void replace(const String& find, const String& replace);
- void remove(unsigned int index);
- void remove(unsigned int index, unsigned int count);
- void toLowerCase(void);
- void toUpperCase(void);
- void trim(void);
-
- // parsing/conversion
- long toInt(void) const;
- float toFloat(void) const;
- double toDouble(void) const;
-
-protected:
- char *buffer; // the actual char array
- unsigned int capacity; // the array length minus one (for the '\0')
- unsigned int len; // the String length (not counting the '\0')
-protected:
- void init(void);
- void invalidate(void);
- unsigned char changeBuffer(unsigned int maxStrLen);
- unsigned char concat(const char *cstr, unsigned int length);
-
- // copy and move
- String & copy(const char *cstr, unsigned int length);
- String & copy(const __FlashStringHelper *pstr, unsigned int length);
- #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
- void move(String &rhs);
- #endif
+ // use a function pointer to allow for "if (s)" without the
+ // complications of an operator bool(). for more information, see:
+ // http://www.artima.com/cppsource/safebool.html
+ typedef void (String::*StringIfHelperType)() const;
+ void StringIfHelper() const {}
+
+ public:
+ // constructors
+ // creates a copy of the initial value.
+ // if the initial value is null or invalid, or if memory allocation
+ // fails, the string will be marked as invalid (i.e. "if (s)" will
+ // be false).
+ String(const char *cstr = "");
+ String(const String &str);
+ String(const __FlashStringHelper *str);
+#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+ String(String &&rval);
+ String(StringSumHelper &&rval);
+#endif
+ explicit String(char c);
+ explicit String(unsigned char, unsigned char base = 10);
+ explicit String(int, unsigned char base = 10);
+ explicit String(unsigned int, unsigned char base = 10);
+ explicit String(long, unsigned char base = 10);
+ explicit String(unsigned long, unsigned char base = 10);
+ explicit String(float, unsigned char decimalPlaces = 2);
+ explicit String(double, unsigned char decimalPlaces = 2);
+ ~String(void);
+
+ // memory management
+ // return true on success, false on failure (in which case, the string
+ // is left unchanged). reserve(0), if successful, will validate an
+ // invalid string (i.e., "if (s)" will be true afterwards)
+ unsigned char reserve(unsigned int size);
+ inline unsigned int length(void) const { return len; }
+
+ // creates a copy of the assigned value. if the value is null or
+ // invalid, or if the memory allocation fails, the string will be
+ // marked as invalid ("if (s)" will be false).
+ String &operator=(const String &rhs);
+ String &operator=(const char *cstr);
+ String &operator=(const __FlashStringHelper *str);
+#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+ String &operator=(String &&rval);
+ String &operator=(StringSumHelper &&rval);
+#endif
+
+ // concatenate (works w/ built-in types)
+
+ // returns true on success, false on failure (in which case, the string
+ // is left unchanged). if the argument is null or invalid, the
+ // concatenation is considered unsucessful.
+ unsigned char concat(const String &str);
+ unsigned char concat(const char *cstr);
+ unsigned char concat(char c);
+ unsigned char concat(unsigned char c);
+ unsigned char concat(int num);
+ unsigned char concat(unsigned int num);
+ unsigned char concat(long num);
+ unsigned char concat(unsigned long num);
+ unsigned char concat(float num);
+ unsigned char concat(double num);
+ unsigned char concat(const __FlashStringHelper *str);
+
+ // if there's not enough memory for the concatenated value, the string
+ // will be left unchanged (but this isn't signalled in any way)
+ String &operator+=(const String &rhs)
+ {
+ concat(rhs);
+ return (*this);
+ }
+ String &operator+=(const char *cstr)
+ {
+ concat(cstr);
+ return (*this);
+ }
+ String &operator+=(char c)
+ {
+ concat(c);
+ return (*this);
+ }
+ String &operator+=(unsigned char num)
+ {
+ concat(num);
+ return (*this);
+ }
+ String &operator+=(int num)
+ {
+ concat(num);
+ return (*this);
+ }
+ String &operator+=(unsigned int num)
+ {
+ concat(num);
+ return (*this);
+ }
+ String &operator+=(long num)
+ {
+ concat(num);
+ return (*this);
+ }
+ String &operator+=(unsigned long num)
+ {
+ concat(num);
+ return (*this);
+ }
+ String &operator+=(float num)
+ {
+ concat(num);
+ return (*this);
+ }
+ String &operator+=(double num)
+ {
+ concat(num);
+ return (*this);
+ }
+ String &operator+=(const __FlashStringHelper *str)
+ {
+ concat(str);
+ return (*this);
+ }
+
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, const String &rhs);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, const char *cstr);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, char c);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, unsigned char num);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, int num);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, unsigned int num);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, long num);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, unsigned long num);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, float num);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, double num);
+ friend StringSumHelper &operator+(const StringSumHelper &lhs, const __FlashStringHelper *rhs);
+
+ // comparison (only works w/ Strings and "strings")
+ operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
+ int compareTo(const String &s) const;
+ unsigned char equals(const String &s) const;
+ unsigned char equals(const char *cstr) const;
+ unsigned char operator==(const String &rhs) const { return equals(rhs); }
+ unsigned char operator==(const char *cstr) const { return equals(cstr); }
+ unsigned char operator!=(const String &rhs) const { return !equals(rhs); }
+ unsigned char operator!=(const char *cstr) const { return !equals(cstr); }
+ unsigned char operator<(const String &rhs) const;
+ unsigned char operator>(const String &rhs) const;
+ unsigned char operator<=(const String &rhs) const;
+ unsigned char operator>=(const String &rhs) const;
+ unsigned char equalsIgnoreCase(const String &s) const;
+ unsigned char startsWith(const String &prefix) const;
+ unsigned char startsWith(const String &prefix, unsigned int offset) const;
+ unsigned char endsWith(const String &suffix) const;
+
+ // character acccess
+ char charAt(unsigned int index) const;
+ void setCharAt(unsigned int index, char c);
+ char operator[](unsigned int index) const;
+ char &operator[](unsigned int index);
+ void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index = 0) const;
+ void toCharArray(char *buf, unsigned int bufsize, unsigned int index = 0) const
+ {
+ getBytes((unsigned char *)buf, bufsize, index);
+ }
+ const char *c_str() const { return buffer; }
+ char *begin() { return buffer; }
+ char *end() { return buffer + length(); }
+ const char *begin() const { return c_str(); }
+ const char *end() const { return c_str() + length(); }
+
+ // search
+ int indexOf(char ch) const;
+ int indexOf(char ch, unsigned int fromIndex) const;
+ int indexOf(const String &str) const;
+ int indexOf(const String &str, unsigned int fromIndex) const;
+ int lastIndexOf(char ch) const;
+ int lastIndexOf(char ch, unsigned int fromIndex) const;
+ int lastIndexOf(const String &str) const;
+ int lastIndexOf(const String &str, unsigned int fromIndex) const;
+ String substring(unsigned int beginIndex) const { return substring(beginIndex, len); };
+ String substring(unsigned int beginIndex, unsigned int endIndex) const;
+
+ // modification
+ void replace(char find, char replace);
+ void replace(const String &find, const String &replace);
+ void remove(unsigned int index);
+ void remove(unsigned int index, unsigned int count);
+ void toLowerCase(void);
+ void toUpperCase(void);
+ void trim(void);
+
+ // parsing/conversion
+ long toInt(void) const;
+ float toFloat(void) const;
+ double toDouble(void) const;
+
+ protected:
+ char *buffer; // the actual char array
+ unsigned int capacity; // the array length minus one (for the '\0')
+ unsigned int len; // the String length (not counting the '\0')
+ protected:
+ void init(void);
+ void invalidate(void);
+ unsigned char changeBuffer(unsigned int maxStrLen);
+ unsigned char concat(const char *cstr, unsigned int length);
+
+ // copy and move
+ String ©(const char *cstr, unsigned int length);
+ String ©(const __FlashStringHelper *pstr, unsigned int length);
+#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
+ void move(String &rhs);
+#endif
};
class StringSumHelper : public String
{
-public:
- StringSumHelper(const String &s) : String(s) {}
- StringSumHelper(const char *p) : String(p) {}
- StringSumHelper(char c) : String(c) {}
- StringSumHelper(unsigned char num) : String(num) {}
- StringSumHelper(int num) : String(num) {}
- StringSumHelper(unsigned int num) : String(num) {}
- StringSumHelper(long num) : String(num) {}
- StringSumHelper(unsigned long num) : String(num) {}
- StringSumHelper(float num) : String(num) {}
- StringSumHelper(double num) : String(num) {}
+ public:
+ StringSumHelper(const String &s) : String(s) {}
+ StringSumHelper(const char *p) : String(p) {}
+ StringSumHelper(char c) : String(c) {}
+ StringSumHelper(unsigned char num) : String(num) {}
+ StringSumHelper(int num) : String(num) {}
+ StringSumHelper(unsigned int num) : String(num) {}
+ StringSumHelper(long num) : String(num) {}
+ StringSumHelper(unsigned long num) : String(num) {}
+ StringSumHelper(float num) : String(num) {}
+ StringSumHelper(double num) : String(num) {}
};
-#endif // __cplusplus
+#endif // __cplusplus
diff --git a/megaavr/cores/coreX-corefiles/api/USBAPI.h b/megaavr/cores/coreX-corefiles/api/USBAPI.h
index 8743ab4..3283106 100644
--- a/megaavr/cores/coreX-corefiles/api/USBAPI.h
+++ b/megaavr/cores/coreX-corefiles/api/USBAPI.h
@@ -30,17 +30,18 @@ typedef struct __attribute__((packed))
{
union {
uint8_t bmRequestType;
- struct {
+ struct
+ {
uint8_t direction : 5;
uint8_t type : 2;
uint8_t transferDirection : 1;
};
};
- uint8_t bRequest;
- uint8_t wValueL;
- uint8_t wValueH;
- uint16_t wIndex;
- uint16_t wLength;
+ uint8_t bRequest;
+ uint8_t wValueL;
+ uint8_t wValueH;
+ uint16_t wIndex;
+ uint16_t wLength;
} USBSetup;
//================================================================================
@@ -50,11 +51,11 @@ int USB_SendControl(uint8_t flags, const void* d, int len);
int USB_RecvControl(void* d, int len);
int USB_RecvControlLong(void* d, int len);
-uint8_t USB_Available(uint8_t ep);
+uint8_t USB_Available(uint8_t ep);
uint8_t USB_SendSpace(uint8_t ep);
-int USB_Send(uint8_t ep, const void* data, int len); // blocking
-int USB_Recv(uint8_t ep, void* data, int len); // non-blocking
-int USB_Recv(uint8_t ep); // non-blocking
+int USB_Send(uint8_t ep, const void* data, int len); // blocking
+int USB_Recv(uint8_t ep, void* data, int len); // non-blocking
+int USB_Recv(uint8_t ep); // non-blocking
void USB_Flush(uint8_t ep);
#endif
\ No newline at end of file
diff --git a/megaavr/cores/coreX-corefiles/api/Udp.h b/megaavr/cores/coreX-corefiles/api/Udp.h
index 9058165..252f7a4 100644
--- a/megaavr/cores/coreX-corefiles/api/Udp.h
+++ b/megaavr/cores/coreX-corefiles/api/Udp.h
@@ -36,51 +36,54 @@
#include "Stream.h"
#include "IPAddress.h"
-
-class UDP : public Stream {
-
-public:
- virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
- virtual void stop() =0; // Finish with the UDP socket
+namespace arduino {
+class UDP : public Stream
+{
+ public:
+ virtual uint8_t begin(uint16_t) = 0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
+ virtual void stop() = 0; // Finish with the UDP socket
// Sending UDP packets
-
+
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
- virtual int beginPacket(IPAddress ip, uint16_t port) =0;
+ virtual int beginPacket(IPAddress ip, uint16_t port) = 0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
- virtual int beginPacket(const char *host, uint16_t port) =0;
+ virtual int beginPacket(const char* host, uint16_t port) = 0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
- virtual int endPacket() =0;
+ virtual int endPacket() = 0;
// Write a single byte into the packet
- virtual size_t write(uint8_t) =0;
+ virtual size_t write(uint8_t) = 0;
// Write size bytes from buffer into the packet
- virtual size_t write(const uint8_t *buffer, size_t size) =0;
+ virtual size_t write(const uint8_t* buffer, size_t size) = 0;
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
- virtual int parsePacket() =0;
+ virtual int parsePacket() = 0;
// Number of bytes remaining in the current packet
- virtual int available() =0;
+ virtual int available() = 0;
// Read a single byte from the current packet
- virtual int read() =0;
+ virtual int read() = 0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
- virtual int read(unsigned char* buffer, size_t len) =0;
+ virtual int read(unsigned char* buffer, size_t len) = 0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
- virtual int read(char* buffer, size_t len) =0;
+ virtual int read(char* buffer, size_t len) = 0;
// Return the next byte from the current packet without moving on to the next byte
- virtual int peek() =0;
- virtual void flush() =0; // Finish reading the current packet
+ virtual int peek() = 0;
+ virtual void flush() = 0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
- virtual IPAddress remoteIP() =0;
+ virtual IPAddress remoteIP() = 0;
// Return the port of the host who sent the current incoming packet
- virtual uint16_t remotePort() =0;
-protected:
+ virtual uint16_t remotePort() = 0;
+
+ protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};
+}
+using arduino::UDP;
diff --git a/megaavr/cores/coreX-corefiles/api/Udp.h.orig b/megaavr/cores/coreX-corefiles/api/Udp.h.orig
index b695002..56c5f1d 100644
--- a/megaavr/cores/coreX-corefiles/api/Udp.h.orig
+++ b/megaavr/cores/coreX-corefiles/api/Udp.h.orig
@@ -42,7 +42,7 @@ namespace arduino {
class UDP : public Stream {
public:
- virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
+ virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop() =0; // Finish with the UDP socket
// Sending UDP packets
@@ -76,7 +76,7 @@ public:
virtual int read(char* buffer, size_t len) =0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() =0;
- virtual void flush() =0; // Finish reading the current packet
+ virtual void flush() =0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() =0;
@@ -86,4 +86,4 @@ protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};
-}
\ No newline at end of file
+}
diff --git a/megaavr/cores/coreX-corefiles/api/WCharacter.h b/megaavr/cores/coreX-corefiles/api/WCharacter.h
index 4ce89ee..5db7d9b 100644
--- a/megaavr/cores/coreX-corefiles/api/WCharacter.h
+++ b/megaavr/cores/coreX-corefiles/api/WCharacter.h
@@ -38,131 +38,115 @@ inline bool isUpperCase(int c) __attribute__((always_inline));
inline bool isHexadecimalDigit(int c) __attribute__((always_inline));
inline int toAscii(int c) __attribute__((always_inline));
inline int toLowerCase(int c) __attribute__((always_inline));
-inline int toUpperCase(int c)__attribute__((always_inline));
+inline int toUpperCase(int c) __attribute__((always_inline));
-
-// Checks for an alphanumeric character.
+// Checks for an alphanumeric character.
// It is equivalent to (isalpha(c) || isdigit(c)).
-inline bool isAlphaNumeric(int c)
+inline bool isAlphaNumeric(int c)
{
- return ( isalnum(c) == 0 ? false : true);
+ return (isalnum(c) == 0 ? false : true);
}
-
-// Checks for an alphabetic character.
+// Checks for an alphabetic character.
// It is equivalent to (isupper(c) || islower(c)).
inline bool isAlpha(int c)
{
- return ( isalpha(c) == 0 ? false : true);
+ return (isalpha(c) == 0 ? false : true);
}
-
-// Checks whether c is a 7-bit unsigned char value
+// Checks whether c is a 7-bit unsigned char value
// that fits into the ASCII character set.
inline bool isAscii(int c)
{
- return ( isascii (c) == 0 ? false : true);
+ return (isascii(c) == 0 ? false : true);
}
-
// Checks for a blank character, that is, a space or a tab.
inline bool isWhitespace(int c)
{
- return ( isblank (c) == 0 ? false : true);
+ return (isblank(c) == 0 ? false : true);
}
-
// Checks for a control character.
inline bool isControl(int c)
{
- return ( iscntrl (c) == 0 ? false : true);
+ return (iscntrl(c) == 0 ? false : true);
}
-
// Checks for a digit (0 through 9).
inline bool isDigit(int c)
{
- return ( isdigit (c) == 0 ? false : true);
+ return (isdigit(c) == 0 ? false : true);
}
-
// Checks for any printable character except space.
inline bool isGraph(int c)
{
- return ( isgraph (c) == 0 ? false : true);
+ return (isgraph(c) == 0 ? false : true);
}
-
// Checks for a lower-case character.
inline bool isLowerCase(int c)
{
- return (islower (c) == 0 ? false : true);
+ return (islower(c) == 0 ? false : true);
}
-
// Checks for any printable character including space.
inline bool isPrintable(int c)
{
- return ( isprint (c) == 0 ? false : true);
+ return (isprint(c) == 0 ? false : true);
}
-
-// Checks for any printable character which is not a space
+// Checks for any printable character which is not a space
// or an alphanumeric character.
inline bool isPunct(int c)
{
- return ( ispunct (c) == 0 ? false : true);
+ return (ispunct(c) == 0 ? false : true);
}
-
-// Checks for white-space characters. For the avr-libc library,
-// these are: space, formfeed ('\f'), newline ('\n'), carriage
+// Checks for white-space characters. For the avr-libc library,
+// these are: space, formfeed ('\f'), newline ('\n'), carriage
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
inline bool isSpace(int c)
{
- return ( isspace (c) == 0 ? false : true);
+ return (isspace(c) == 0 ? false : true);
}
-
// Checks for an uppercase letter.
inline bool isUpperCase(int c)
{
- return ( isupper (c) == 0 ? false : true);
+ return (isupper(c) == 0 ? false : true);
}
-
-// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
+// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
// 8 9 a b c d e f A B C D E F.
inline bool isHexadecimalDigit(int c)
{
- return ( isxdigit (c) == 0 ? false : true);
+ return (isxdigit(c) == 0 ? false : true);
}
-
-// Converts c to a 7-bit unsigned char value that fits into the
+// Converts c to a 7-bit unsigned char value that fits into the
// ASCII character set, by clearing the high-order bits.
inline int toAscii(int c)
{
- return toascii (c);
+ return toascii(c);
}
-
// Warning:
-// Many people will be unhappy if you use this function.
-// This function will convert accented letters into random
+// Many people will be unhappy if you use this function.
+// This function will convert accented letters into random
// characters.
// Converts the letter c to lower case, if possible.
inline int toLowerCase(int c)
{
- return tolower (c);
+ return tolower(c);
}
-
// Converts the letter c to upper case, if possible.
inline int toUpperCase(int c)
{
- return toupper (c);
+ return toupper(c);
}
#endif
\ No newline at end of file
diff --git a/megaavr/cores/coreX-corefiles/api/itoa.h b/megaavr/cores/coreX-corefiles/api/itoa.h
index 55b2849..c94f733 100644
--- a/megaavr/cores/coreX-corefiles/api/itoa.h
+++ b/megaavr/cores/coreX-corefiles/api/itoa.h
@@ -23,15 +23,15 @@
// core should supply an implementation of them.
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
-extern char* itoa(int value, char *string, int radix);
-extern char* ltoa(long value, char *string, int radix);
-extern char* utoa(unsigned value, char *string, int radix);
-extern char* ultoa(unsigned long value, char *string, int radix);
+ extern char* itoa(int value, char* string, int radix);
+ extern char* ltoa(long value, char* string, int radix);
+ extern char* utoa(unsigned value, char* string, int radix);
+ extern char* ultoa(unsigned long value, char* string, int radix);
#ifdef __cplusplus
} // extern "C"
#endif
-
diff --git a/megaavr/cores/coreX-corefiles/hooks.c b/megaavr/cores/coreX-corefiles/hooks.c
index 641eabc..a61b5ef 100644
--- a/megaavr/cores/coreX-corefiles/hooks.c
+++ b/megaavr/cores/coreX-corefiles/hooks.c
@@ -26,6 +26,6 @@
* real cooperative scheduler.
*/
static void __empty() {
- // Empty
+ // Empty
}
void yield(void) __attribute__ ((weak, alias("__empty")));
diff --git a/megaavr/cores/coreX-corefiles/main.cpp b/megaavr/cores/coreX-corefiles/main.cpp
index 17aa21d..d79a464 100644
--- a/megaavr/cores/coreX-corefiles/main.cpp
+++ b/megaavr/cores/coreX-corefiles/main.cpp
@@ -20,33 +20,28 @@
#include
// Declared weak in Arduino.h to allow user redefinitions.
-int atexit(void (* /*func*/ )()) { return 0; }
-
-// Weak empty variant initialization function.
-// May be redefined by variant files.
-void initVariant() __attribute__((weak));
-void initVariant() { }
+int atexit(void (* /*func*/)()) { return 0; }
void setupUSB() __attribute__((weak));
-void setupUSB() { }
+void setupUSB() {}
int main(void)
{
- init();
+ init();
- initVariant();
+ initVariant();
#if defined(USBCON)
- USBDevice.attach();
+ USBDevice.attach();
#endif
- setup();
+ setup();
- for (;;) {
- loop();
- if (serialEventRun) serialEventRun();
- }
+ for (;;)
+ {
+ loop();
+ if (serialEventRun) serialEventRun();
+ }
- return 0;
+ return 0;
}
-
diff --git a/megaavr/cores/coreX-corefiles/new.cpp b/megaavr/cores/coreX-corefiles/new.cpp
index cf6f89c..26403f1 100644
--- a/megaavr/cores/coreX-corefiles/new.cpp
+++ b/megaavr/cores/coreX-corefiles/new.cpp
@@ -18,19 +18,37 @@
#include
-void *operator new(size_t size) {
+void *operator new(size_t size)
+{
return malloc(size);
}
-void *operator new[](size_t size) {
+void *operator new[](size_t size)
+{
return malloc(size);
}
-void operator delete(void * ptr) {
+void operator delete(void *ptr)
+{
free(ptr);
}
-void operator delete[](void * ptr) {
+void operator delete[](void *ptr)
+{
free(ptr);
}
+// C++14 introduces additional delete operators
+#if __cplusplus >= 201402L
+
+void operator delete(void * ptr, size_t)
+{
+ ::operator delete(ptr);
+}
+
+void operator delete[](void * ptr, size_t)
+{
+ ::operator delete(ptr);
+}
+
+#endif // End language is C++14 or greater
diff --git a/megaavr/cores/coreX-corefiles/new.h b/megaavr/cores/coreX-corefiles/new.h
index 6e1b68f..66b9619 100644
--- a/megaavr/cores/coreX-corefiles/new.h
+++ b/megaavr/cores/coreX-corefiles/new.h
@@ -23,8 +23,13 @@
void * operator new(size_t size);
void * operator new[](size_t size);
-void operator delete(void * ptr);
-void operator delete[](void * ptr);
+void operator delete(void* ptr);
+void operator delete[](void* ptr);
-#endif
+// C++14 introduces additional delete operators
+#if __cplusplus >= 201402L
+void operator delete(void * ptr, size_t);
+void operator delete[](void * ptr, size_t);
+#endif // end language is C++14 or greater
+#endif
diff --git a/megaavr/cores/coreX-corefiles/pwm_write.cpp b/megaavr/cores/coreX-corefiles/pwm_write.cpp
new file mode 100644
index 0000000..d89739f
--- /dev/null
+++ b/megaavr/cores/coreX-corefiles/pwm_write.cpp
@@ -0,0 +1,158 @@
+#include "Arduino.h"
+#include "pins_arduino.h"
+#include "wiring_private.h"
+
+void pwmWrite(pwm_timers_t pwmTimer, uint16_t val, timers_route_t timerRoute) {
+ // Set PORTMUX to route PWM to the correct pin
+ if (timerRoute != ROUTE_UNTOUCHED) {
+ if(timerRoute & 0x40)
+ PORTMUX.TCAROUTEA = timerRoute & 0x07;
+ else {
+ uint8_t tcb_index = (timerRoute >> 4) & 0x03;
+ uint8_t route_bit = timerRoute & 0x01;
+ uint8_t mask = (1 << tcb_index);
+ if(route_bit)
+ PORTMUX.TCBROUTEA |= mask;
+ else
+ PORTMUX.TCBROUTEA &= ~mask;
+ }
+ }
+
+ // Find corresponding IO pin based on pwmTimer
+ uint8_t route = 0;
+ uint8_t pin_bp = 0;
+ uint8_t d_max = 0;
+ VPORT_t *vport;
+ if(pwmTimer <= TCA0_5) {
+ route = PORTMUX.TCAROUTEA;
+ pin_bp = pwmTimer;
+ vport = &VPORTA + route;
+ d_max = TCA0.SPLIT.LPER;
+ } else if(pwmTimer == TCB_0) {
+ route = PORTMUX.TCBROUTEA & 0x01;
+ pin_bp = route? PIN4_bp: PIN2_bp;
+ vport = route? &VPORTF: &VPORTA;
+ d_max = TCB0.CCMPL;
+ } else if(pwmTimer == TCB_1) {
+ route = PORTMUX.TCBROUTEA & 0x02;
+ pin_bp = route? PIN5_bp: PIN3_bp;
+ vport = route? &VPORTF: &VPORTA;
+ d_max = TCB1.CCMPL;
+ } else if(pwmTimer == TCB_2) {
+ route = PORTMUX.TCBROUTEA & 0x04;
+ pin_bp = route? PIN4_bp: PIN0_bp;
+ vport = route? &VPORTB: &VPORTC;
+ d_max = TCB2.CCMPL;
+ }
+ #if defined(TCB3)
+ else if(pwmTimer == TCB_3) {
+ route = PORTMUX.TCBROUTEA & 0x08;
+ pin_bp = route? PIN1_bp: PIN5_bp;
+ vport = route? &VPORTC: &VPORTB;
+ d_max = TCB3.CCMPL;
+ }
+ #endif
+ else {
+ return;
+ }
+
+ // Set IO pin as output
+ vport->DIR |= (1< d_max) {
+ // Turn off PWM
+ uint8_t bitpos = pin_bp;
+ switch (pwmTimer) {
+ case TCA0_0...TCA0_5:
+ if (bitpos >= 3) ++bitpos; // Upper 3 bits are shifted by 1
+ TCA0.SPLIT.CTRLB &= ~(1 << (TCA_SPLIT_LCMP0EN_bp + bitpos));
+ break;
+
+ case TCB_0:
+ case TCB_1:
+ case TCB_2:
+ #if defined(TCB3)
+ case TCB_3:
+ #endif
+ timer_B = &TCB0 + (pwmTimer-TCB_0);
+ timer_B->CTRLB &= ~(TCB_CCMPEN_bm);
+ break;
+
+ default:
+ break;
+ }
+ // Set pin high or low
+ if(val <= 0)
+ vport->OUT &= ~(1<OUT |= (1<= 3) {
+ timer_cmp_out = ((uint8_t *)(&TCA0.SPLIT.HCMP0)) + 2*(pin_bp-3);
+ ++pin_bp;
+ } else {
+ timer_cmp_out = ((uint8_t *)(&TCA0.SPLIT.LCMP0)) + 2*pin_bp;
+ }
+ cli();
+ *timer_cmp_out = val;
+ SREG = savedSREG;
+ TCA0.SPLIT.CTRLB |= (1 << (TCA_SPLIT_LCMP0EN_bp + pin_bp));
+ break;
+
+ case TCB_0:
+ case TCB_1:
+ case TCB_2:
+ #if defined(TCB3)
+ case TCB_3:
+ #endif
+ timer_B = &TCB0 + (pwmTimer-TCB_0);
+ savedSREG = SREG;
+ cli();
+ timer_B->CCMPL = timer_B->CCMPL;
+ timer_B->CCMPH = val;
+ SREG = savedSREG;
+ timer_B->CTRLB |= (TCB_CCMPEN_bm);
+ break;
+ }
+ }
+}
+
+void pwmPrescaler(pwm_timers_t pwmTimer, timers_prescaler_t prescaler) {
+ if(pwmTimer <= TCA0_5)
+ TCA0.SPLIT.CTRLA = prescaler | TCA_SPLIT_ENABLE_bm;
+ else {
+ TCB_t *timer_B = &TCB0 + (pwmTimer-TCB_0);
+ uint8_t p = (prescaler >> 4) & TCB_CLKSEL_gm;
+ timer_B->CTRLA = ((timer_B->CTRLA & ~TCB_CLKSEL_gm) | p);
+ }
+}
+
+void pwmSetResolution(pwm_timers_t pwmTimer, uint8_t maxValue) {
+ // The max value will disable PWM and set pin high
+ uint8_t top = maxValue? maxValue-1: 1;
+
+ if(pwmTimer <= TCA0_5) {
+ TCA0.SPLIT.LPER =
+ TCA0.SPLIT.HPER = top;
+ TCA0.SPLIT.LCMP0 =
+ TCA0.SPLIT.LCMP1 =
+ TCA0.SPLIT.LCMP2 =
+ TCA0.SPLIT.HCMP0 =
+ TCA0.SPLIT.HCMP1 =
+ TCA0.SPLIT.HCMP2 = top >> 1;
+ } else {
+ TCB_t *timer_B = &TCB0 + (pwmTimer-TCB_0);
+ timer_B->CCMPL = top;
+ timer_B->CCMPH = top >> 1;
+ }
+
+}
\ No newline at end of file
diff --git a/megaavr/cores/coreX-corefiles/timers.h b/megaavr/cores/coreX-corefiles/timers.h
new file mode 100644
index 0000000..d468fbb
--- /dev/null
+++ b/megaavr/cores/coreX-corefiles/timers.h
@@ -0,0 +1,11 @@
+#ifndef __TIMERS_H__
+#define __TIMERS_H__
+
+// The assumption is that we have a 16 bit timer fully available for timing purposes.
+#define TIME_TRACKING_TIMER_DIVIDER 1 // Timer F_CPU Clock divider (can be 1 or 2)
+#define TIME_TRACKING_TIMER_COUNT (F_CPU / (1000 * TIME_TRACKING_TIMER_DIVIDER)) // Should correspond to exactly 1 ms, i.e. millis()
+
+#define PWM_TIMER_PERIOD 0xFE // For frequency
+#define PWM_TIMER_COMPARE 0x80 // For duty cycle
+
+#endif
diff --git a/megaavr/cores/coreX-corefiles/wiring.c b/megaavr/cores/coreX-corefiles/wiring.c
index ef0d24d..a04037f 100644
--- a/megaavr/cores/coreX-corefiles/wiring.c
+++ b/megaavr/cores/coreX-corefiles/wiring.c
@@ -1,5 +1,5 @@
/*
- wiring.c - Partial implementation of the Wiring API for the ATmega8.
+ wiring.c
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
@@ -18,391 +18,536 @@
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
-*/
-
-#include "wiring_private.h"
-
-// the prescaler is set so that timer ticks every 64 clock cycles, and the
-// the overflow handler is called every 256 ticks.
-volatile uint16_t microseconds_per_timer_overflow;
-volatile uint16_t microseconds_per_timer_tick;
-
-uint32_t F_CPU_CORRECTED = F_CPU;
-// the whole number of milliseconds per timer overflow
-uint16_t millis_inc;
+ Substantially rewritten by Egil Kvaleberg, 23 Sep 2019, to
+ use a dedicated 16 bit TSB timer for all timing purposes. This
+ cleans up a lot of things, and makes the code much simpler and
+ faster. The TCB timers have limitations making it impossible to
+ use the same timer for both PWM and timing, so this is no loss.
-// the fractional number of milliseconds per timer overflow
-uint16_t fract_inc;
-#define FRACT_MAX (1000)
+*/
-// whole number of microseconds per timer tick
+#include "wiring_private.h"
-volatile uint32_t timer_overflow_count = 0;
volatile uint32_t timer_millis = 0;
-static uint16_t timer_fract = 0;
-inline uint16_t clockCyclesPerMicrosecondComp(uint32_t clk){
- return ( (clk) / 1000000L );
+inline uint16_t clockCyclesPerMicrosecondComp(uint32_t clk)
+{
+ return ((clk) / 1000000L);
}
-inline uint16_t clockCyclesPerMicrosecond(){
- return clockCyclesPerMicrosecondComp(F_CPU_CORRECTED);
+inline uint16_t clockCyclesPerMicrosecond()
+{
+ return clockCyclesPerMicrosecondComp(F_CPU);
}
-inline unsigned long clockCyclesToMicroseconds(unsigned long cycles){
- return ( cycles / clockCyclesPerMicrosecond() );
+inline unsigned long clockCyclesToMicroseconds(unsigned long cycles)
+{
+ return (cycles / clockCyclesPerMicrosecond());
}
-inline unsigned long microsecondsToClockCycles(unsigned long microseconds){
- return ( microseconds * clockCyclesPerMicrosecond() );
+inline unsigned long microsecondsToClockCycles(unsigned long microseconds)
+{
+ return (microseconds * clockCyclesPerMicrosecond());
}
-static volatile TCB_t* _timer =
+static volatile TCB_t *_timer =
#if defined(MILLIS_USE_TIMERB0)
- &TCB0;
+ &TCB0;
#elif defined(MILLIS_USE_TIMERB1)
- &TCB1;
+ &TCB1;
#elif defined(MILLIS_USE_TIMERB2)
- &TCB2;
-#elif defined(MILLIS_USE_TIMERB3)
- &TCB3;
-#else
- &TCB0; //TCB0 fallback
+ &TCB2;
+#else // fallback or defined(MILLIS_USE_TIMERB3)
+ &TCB3; //TCB3 fallback
#endif
#if defined(MILLIS_USE_TIMERB0)
- ISR(TCB0_INT_vect)
+ISR(TCB0_INT_vect)
#elif defined(MILLIS_USE_TIMERB1)
- ISR(TCB1_INT_vect)
+ISR(TCB1_INT_vect)
#elif defined(MILLIS_USE_TIMERB2)
- ISR(TCB2_INT_vect)
-#elif defined(MILLIS_USE_TIMERB3)
- ISR(TCB3_INT_vect)
-#else //TCB0 fallback
- ISR(TCB0_INT_vect)
+ISR(TCB2_INT_vect)
+#else // fallback or defined(MILLIS_USE_TIMERB3)
+ISR(TCB3_INT_vect)
#endif
{
- // copy these to local variables so they can be stored in registers
- // (volatile variables must be read from memory on every access)
- uint32_t m = timer_millis;
- uint16_t f = timer_fract;
-
- m += millis_inc;
- f += fract_inc;
- if (f >= FRACT_MAX) {
+ timer_millis++;
- f -= FRACT_MAX;
- m += 1;
- }
-
- timer_fract = f;
- timer_millis = m;
- timer_overflow_count++;
-
- /* Clear flag */
- _timer->INTFLAGS = TCB_CAPT_bm;
+ /* Clear flag */
+ _timer->INTFLAGS = TCB_CAPT_bm;
}
unsigned long millis()
{
- unsigned long m;
-
- // disable interrupts while we read timer0_millis or we might get an
- // inconsistent value (e.g. in the middle of a write to timer0_millis)
- uint8_t status = SREG;
- cli();
- m = timer_millis;
-
- SREG = status;
+ unsigned long m;
- return m;
-}
-
-unsigned long micros() {
- unsigned long overflows, microseconds;
- uint8_t ticks;
-
- /* Save current state and disable interrupts */
- uint8_t status = SREG;
- cli();
+ // disable interrupts while we read timer0_millis or we might get an
+ // inconsistent value (e.g. in the middle of a write to timer_millis)
+ uint8_t status = SREG;
+ cli();
- /* Get current number of overflows and timer count */
- overflows = timer_overflow_count;
- ticks = _timer->CNTL;
+ m = timer_millis;
- /* If the timer overflow flag is raised, we just missed it,
- increment to account for it, & read new ticks */
- if(_timer->INTFLAGS & TCB_CAPT_bm){
- overflows++;
- ticks = _timer->CNTL;
- }
+ SREG = status;
- /* Restore state */
- SREG = status;
+ return m;
+}
- /* Return microseconds of up time (resets every ~70mins) */
- microseconds = ((overflows * microseconds_per_timer_overflow)
- + (ticks * microseconds_per_timer_tick));
- return microseconds;
+unsigned long micros()
+{
+ uint32_t m;
+ uint16_t t;
+
+ /* Save current state and disable interrupts */
+ uint8_t status = SREG;
+ cli();
+
+ /* Get current number of millis (i.e. overflows) and timer count */
+ m = timer_millis;
+ t = _timer->CNT;
+
+ /* If the timer overflow flag is raised, we just missed it,
+ increment to account for it, & read new ticks */
+ if (_timer->INTFLAGS & TCB_CAPT_bm)
+ {
+ m++;
+ t = _timer->CNT;
+ }
+
+ // Restore SREG
+ SREG = status;
+
+#if (F_CPU == 20000000L)
+ t = t >> 4;
+ return m * 1000 + (t - (t >> 2) + (t >> 4) - (t >> 6));
+#elif (F_CPU == 16000000L)
+ return m * 1000 + (t >> 4);
+#elif (F_CPU == 10000000L)
+ t = t >> 3;
+ return m * 1000 + (t - (t >> 2) + (t >> 4) - (t >> 6));
+#elif (F_CPU == 8000000L)
+ return m * 1000 + (t >> 3);
+#elif (F_CPU == 5000000L)
+ t = t >> 2;
+ return m * 1000 + (t - (t >> 2) + (t >> 4) - (t >> 6));
+#elif (F_CPU == 4000000L)
+ return m * 1000 + (t >> 2);
+#elif (F_CPU == 2000000L)
+ return m * 1000 + (t >> 1);
+#elif (F_CPU == 1000000L)
+ return m * 1000 + t;
+#else
+ return 0;
+#endif
}
void delay(unsigned long ms)
{
- uint32_t start_time = micros(), delay_time = 1000*ms;
-
- /* Calculate future time to return */
- uint32_t return_time = start_time + delay_time;
-
- /* If return time overflows */
- if(return_time < delay_time){
- /* Wait until micros overflows */
- while(micros() > return_time);
- }
-
- /* Wait until return time */
- while(micros() < return_time);
+ uint32_t start_time = micros(), delay_time = 1000 * ms;
+
+ /* Calculate future time to return */
+ uint32_t return_time = start_time + delay_time;
+
+ /* If return time overflows */
+ if (return_time < delay_time)
+ {
+ /* Wait until micros overflows */
+ while (micros() > return_time)
+ ;
+ }
+
+ /* Wait until return time */
+ while (micros() < return_time)
+ ;
}
/* Delay for the given number of microseconds. Assumes a 1, 8, 12, 16, 20 or 24 MHz clock. */
+// BUG: should really be implemented using _timer instead!!!!!!!!!!
void delayMicroseconds(unsigned int us)
{
- // call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
+ // call = 4 cycles + 2 to 4 cycles to init us(2 for constant delay, 4 for variable)
- // calling avrlib's delay_us() function with low values (e.g. 1 or
- // 2 microseconds) gives delays longer than desired.
- //delay_us(us);
+ // calling avrlib's delay_us() function with low values (e.g. 1 or
+ // 2 microseconds) gives delays longer than desired.
+ //delay_us(us);
#if F_CPU >= 24000000L
- // for the 24 MHz clock for the aventurous ones, trying to overclock
+ // for the 24 MHz clock for the aventurous ones, trying to overclock
- // zero delay fix
- if (!us) return; // = 3 cycles, (4 when true)
+ // zero delay fix
+ if (!us) return; // = 3 cycles, (4 when true)
- // the following loop takes a 1/6 of a microsecond (4 cycles)
- // per iteration, so execute it six times for each microsecond of
- // delay requested.
- us *= 6; // x6 us, = 7 cycles
+ // the following loop takes a 1/6 of a microsecond (4 cycles)
+ // per iteration, so execute it six times for each microsecond of
+ // delay requested.
+ us *= 6; // x6 us, = 7 cycles
- // account for the time taken in the preceeding commands.
- // we just burned 22 (24) cycles above, remove 5, (5*4=20)
- // us is at least 6 so we can substract 5
- us -= 5; //=2 cycles
+ // account for the time taken in the preceeding commands.
+ // we just burned 22 (24) cycles above, remove 5, (5*4=20)
+ // us is at least 6 so we can substract 5
+ us -= 5; //=2 cycles
#elif F_CPU >= 20000000L
- // for the 20 MHz clock on rare Arduino boards
-
- // for a one-microsecond delay, simply return. the overhead
- // of the function call takes 18 (20) cycles, which is 1us
- __asm__ __volatile__ (
- "nop" "\n\t"
- "nop" "\n\t"
- "nop" "\n\t"
- "nop"); //just waiting 4 cycles
- if (us <= 1) return; // = 3 cycles, (4 when true)
-
- // the following loop takes a 1/5 of a microsecond (4 cycles)
- // per iteration, so execute it five times for each microsecond of
- // delay requested.
- us = (us << 2) + us; // x5 us, = 7 cycles
-
- // account for the time taken in the preceeding commands.
- // we just burned 26 (28) cycles above, remove 7, (7*4=28)
- // us is at least 10 so we can substract 7
- us -= 7; // 2 cycles
+
+ // for a one-microsecond delay, simply return. the overhead
+ // of the function call takes 18 (20) cycles, which is 1us
+ __asm__ __volatile__(
+ "nop"
+ "\n\t"
+ "nop"
+ "\n\t"
+ "nop"
+ "\n\t"
+ "nop"); //just waiting 4 cycles
+ if (us <= 1) return; // = 3 cycles, (4 when true)
+
+ // the following loop takes a 1/5 of a microsecond (4 cycles)
+ // per iteration, so execute it five times for each microsecond of
+ // delay requested.
+ us = (us << 2) + us; // x5 us, = 7 cycles
+
+ // account for the time taken in the preceeding commands.
+ // we just burned 26 (28) cycles above, remove 7, (7*4=28)
+ // us is at least 10 so we can substract 7
+ us -= 7; // 2 cycles
#elif F_CPU >= 16000000L
- // for the 16 MHz clock on most Arduino boards
- // for a one-microsecond delay, simply return. the overhead
- // of the function call takes 14 (16) cycles, which is 1us
- if (us <= 1) return; // = 3 cycles, (4 when true)
+ // for a one-microsecond delay, simply return. the overhead
+ // of the function call takes 14 (16) cycles, which is 1us
+ if (us <= 1) return; // = 3 cycles, (4 when true)
- // the following loop takes 1/4 of a microsecond (4 cycles)
- // per iteration, so execute it four times for each microsecond of
- // delay requested.
- us <<= 2; // x4 us, = 4 cycles
+ // the following loop takes 1/4 of a microsecond (4 cycles)
+ // per iteration, so execute it four times for each microsecond of
+ // delay requested.
+ us <<= 2; // x4 us, = 4 cycles
- // account for the time taken in the preceeding commands.
- // we just burned 19 (21) cycles above, remove 5, (5*4=20)
- // us is at least 8 so we can substract 5
- us -= 5; // = 2 cycles,
+ // account for the time taken in the preceeding commands.
+ // we just burned 19 (21) cycles above, remove 5, (5*4=20)
+ // us is at least 8 so we can substract 5
+ us -= 5; // = 2 cycles,
#elif F_CPU >= 12000000L
- // for the 12 MHz clock if somebody is working with USB
- // for a 1 microsecond delay, simply return. the overhead
- // of the function call takes 14 (16) cycles, which is 1.5us
- if (us <= 1) return; // = 3 cycles, (4 when true)
+ // for a 1 microsecond delay, simply return. the overhead
+ // of the function call takes 14 (16) cycles, which is 1.5us
+ if (us <= 1) return; // = 3 cycles, (4 when true)
+
+ // the following loop takes 1/3 of a microsecond (4 cycles)
+ // per iteration, so execute it three times for each microsecond of
+ // delay requested.
+ us = (us << 1) + us; // x3 us, = 5 cycles
+
+ // account for the time taken in the preceeding commands.
+ // we just burned 20 (22) cycles above, remove 5, (5*4=20)
+ // us is at least 6 so we can substract 5
+ us -= 5; //2 cycles
- // the following loop takes 1/3 of a microsecond (4 cycles)
- // per iteration, so execute it three times for each microsecond of
- // delay requested.
- us = (us << 1) + us; // x3 us, = 5 cycles
+#elif F_CPU >= 10000000L
- // account for the time taken in the preceeding commands.
- // we just burned 20 (22) cycles above, remove 5, (5*4=20)
- // us is at least 6 so we can substract 5
- us -= 5; //2 cycles
+ // for a 1 microsecond delay, simply return. the overhead
+ // of the function call takes 14 (16) cycles, which is 1.5us
+ if (us <= 1) return; // = 3 cycles, (4 when true)
+
+ // the following loop takes 2/5 of a microsecond (4 cycles)
+ // per iteration, so execute it 2.5 times for each microsecond of
+ // delay requested.
+ us = (us << 1) + (us >> 1); // x2.5 us, = 5 cycles
+
+ // account for the time taken in the preceding commands.
+ // we just burned 20 (22) cycles above, remove 5, (5*4=20)
+ // us is at least 6 so we can subtract 5
+ us -= 5; //2 cycles
#elif F_CPU >= 8000000L
- // for the 8 MHz internal clock
- // for a 1 and 2 microsecond delay, simply return. the overhead
- // of the function call takes 14 (16) cycles, which is 2us
- if (us <= 2) return; // = 3 cycles, (4 when true)
+ // for a 1 and 2 microsecond delay, simply return. the overhead
+ // of the function call takes 14 (16) cycles, which is 2us
+ if (us <= 2) return; // = 3 cycles, (4 when true)
- // the following loop takes 1/2 of a microsecond (4 cycles)
- // per iteration, so execute it twice for each microsecond of
- // delay requested.
- us <<= 1; //x2 us, = 2 cycles
+ // the following loop takes 1/2 of a microsecond (4 cycles)
+ // per iteration, so execute it twice for each microsecond of
+ // delay requested.
+ us <<= 1; //x2 us, = 2 cycles
- // account for the time taken in the preceeding commands.
- // we just burned 17 (19) cycles above, remove 4, (4*4=16)
- // us is at least 6 so we can substract 4
- us -= 4; // = 2 cycles
+ // account for the time taken in the preceeding commands.
+ // we just burned 17 (19) cycles above, remove 4, (4*4=16)
+ // us is at least 6 so we can substract 4
+ us -= 4; // = 2 cycles
-#else
- // for the 1 MHz internal clock (default settings for common Atmega microcontrollers)
+#elif F_CPU >= 5000000L
+
+ // For a 1 ~ 3 microsecond delay, simply return. The overhead
+ // of the function call takes 14 (16) cycles, which is 3us
+ if (us <= 3) return; // = 3 cycles, (4 when true)
- // the overhead of the function calls is 14 (16) cycles
- if (us <= 16) return; //= 3 cycles, (4 when true)
- if (us <= 25) return; //= 3 cycles, (4 when true), (must be at least 25 if we want to substract 22)
+ // The following loop takes 4/5th microsecond (4 cycles)
+ // per iteration, so we want to add it to 1/4th of itself
+ us += (us >> 2);
- // compensate for the time taken by the preceeding and next commands (about 22 cycles)
- us -= 22; // = 2 cycles
- // the following loop takes 4 microseconds (4 cycles)
- // per iteration, so execute it us/4 times
- // us is at least 4, divided by 4 gives us 1 (no zero delay bug)
- us >>= 2; // us div 4, = 4 cycles
+ us -= 2; // = 2 cycles
+#elif F_CPU >= 4000000L
+ // The overhead of the function call is 14 (16) cycles which is 4 us
+ if (us <= 2) return;
+
+ // Subtract microseconds that were wasted in this function
+ us -= 2;
+
+ // We don't need to multiply here because one request microsecond is exactly one loop cycle
+
+#elif F_CPU >= 2000000L
+ // The overhead of the function call is 14 (16) cycles which is 8.68 us
+ // Plus the if-statement that takes 3 cycles (4 when true): ~11us
+ if (us <= 13) return;
+
+ // Subtract microseconds that were wasted in this function
+ us -= 11; // 2 cycles
+
+ us = (us >> 1); // 3 cycles
+
+#else
+
+ // the overhead of the function calls is 14 (16) cycles
+ if (us <= 16) return; //= 3 cycles, (4 when true)
+ if (us <= 25) return; //= 3 cycles, (4 when true), (must be at least 25 if we want to substract 22)
+
+ // compensate for the time taken by the preceeding and next commands (about 22 cycles)
+ us -= 22; // = 2 cycles
+ // the following loop takes 4 microseconds (4 cycles)
+ // per iteration, so execute it us/4 times
+ // us is at least 4, divided by 4 gives us 1 (no zero delay bug)
+ us >>= 2; // us div 4, = 4 cycles
#endif
- // busy wait
- __asm__ __volatile__ (
- "1: sbiw %0,1" "\n\t" // 2 cycles
- "brne 1b" : "=w" (us) : "0" (us) // 2 cycles
- );
- // return = 4 cycles
+ // busy wait
+ __asm__ __volatile__(
+ "1: sbiw %0,1"
+ "\n\t" // 2 cycles
+ "brne 1b"
+ : "=w"(us)
+ : "0"(us) // 2 cycles
+ );
+ // return = 4 cycles
}
void init()
{
- // this needs to be called before setup() or some functions won't
- // work there
-
-/******************************** CLOCK STUFF *********************************/
-
- /* We assume 5V operating frequency and FUSE.OSCCFG -> 16MHz */
-
- int64_t cpu_freq;
-
- #if (F_CPU == 20000000)
- cpu_freq = 20000000;
-
- /* No division on clock */
- _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00);
-
- #elif (F_CPU == 16000000)
- cpu_freq = 16000000;
-
- /* No division on clock */
- _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00);
-
- #elif (F_CPU == 8000000)
- cpu_freq = 8000000;
-
- /* Clock DIV2 */
- _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_2X_gc));
-
- #elif (F_CPU == 4000000)
- cpu_freq = 4000000;
-
- /* Clock DIV4 */
- _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_4X_gc));
-
- #elif (F_CPU == 2000000)
- cpu_freq = 2000000;
-
- /* Clock DIV8 */
- _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_8X_gc));
- #else
-
- #ifndef F_CPU
- # warning "F_CPU not defined"
- #define F_CPU 16000000
- #endif
-
- # warning "F_CPU defined as an invalid value - may cause undefined behavior"
-
- /* Default value is 16MHz */
- cpu_freq = 16000000;
-
- /* No division on clock */
- _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00);
- #endif
-
- /* Apply calculated value to F_CPU_CORRECTED */
- F_CPU_CORRECTED = (uint32_t)cpu_freq;
-
-
-/********************************* ADC ****************************************/
+ // this needs to be called before setup() or some functions won't
+ // work there
+
+ /******************************** CLOCK STUFF *********************************/
+
+// Use external oscillator if already defined (in boards.txt, platformio.ini)
+#if defined(USE_EXTERNAL_OSCILLATOR)
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLA, CLKCTRL_CLKSEL_EXTCLK_gc);
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00); // Fallback to 16 MHz internal if no EXTCLK
+
+// Use internal oscillator if not defined. No need to manipulate the MCLKCTRLA register here
+// because it's already done in the SYSCFG0 fuse byte
+#else
+#if (F_CPU == 20000000L)
+ /* No division on clock */
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00);
+#elif (F_CPU == 16000000L)
+ /* No division on clock */
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0x00);
+#elif (F_CPU == 10000000L)
+ /* Clock DIV2 */
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_2X_gc));
+#elif (F_CPU == 8000000L)
+ /* Clock DIV2 */
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_2X_gc));
+#elif (F_CPU == 5000000L)
+ /* Clock DIV4 */
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_4X_gc));
+#elif (F_CPU == 4000000L)
+ /* Clock DIV4 */
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_4X_gc));
+#elif (F_CPU == 2000000L)
+ /* Clock DIV8 */
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_8X_gc));
+#elif (F_CPU == 1000000L)
+ /* Clock DIV16 */
+ _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, (CLKCTRL_PEN_bm | CLKCTRL_PDIV_16X_gc));
+#else
+#assert "This internal CPU clock is not supported"
+#endif
+#endif
+
+ /********************************* ADC ****************************************/
#if defined(ADC0)
- /* ADC clock between 50-200 kHz */
-
- #if F_CPU >= 20000000 // 20 MHz / 128 = 156.250 kHz
- ADC0.CTRLC |= ADC_PRESC_DIV128_gc;
- #elif F_CPU >= 16000000 // 16 MHz / 128 = 125 kHz
- ADC0.CTRLC |= ADC_PRESC_DIV128_gc;
- #elif F_CPU >= 8000000 // 8 MHz / 64 = 125 kHz
- ADC0.CTRLC |= ADC_PRESC_DIV64_gc;
- #elif F_CPU >= 4000000 // 4 MHz / 32 = 125 kHz
- ADC0.CTRLC |= ADC_PRESC_DIV32_gc;
- #elif F_CPU >= 2000000 // 2 MHz / 16 = 125 kHz
- ADC0.CTRLC |= ADC_PRESC_DIV16_gc;
- #elif F_CPU >= 1000000 // 1 MHz / 8 = 125 kHz
- ADC0.CTRLC |= ADC_PRESC_DIV8_gc;
- #else // 128 kHz / 2 = 64 kHz -> This is the closest you can get, the prescaler is 2
- ADC0.CTRLC |= ADC_PRESC_DIV2_gc;
- #endif
-
- /* Enable ADC */
- ADC0.CTRLA |= ADC_ENABLE_bm;
- analogReference(VDD);
+ /* ADC clock between 50-200 kHz */
+
+#if (F_CPU >= 20000000L) // 20 MHz / 128 = 156.250 kHz
+ ADC0.CTRLC |= ADC_PRESC_DIV128_gc;
+#elif (F_CPU >= 16000000L) // 16 MHz / 128 = 125 kHz
+ ADC0.CTRLC |= ADC_PRESC_DIV128_gc;
+#elif (F_CPU >= 8000000L) // 8 MHz / 64 = 125 kHz
+ ADC0.CTRLC |= ADC_PRESC_DIV64_gc;
+#elif (F_CPU >= 4000000L) // 4 MHz / 32 = 125 kHz
+ ADC0.CTRLC |= ADC_PRESC_DIV32_gc;
+#elif (F_CPU >= 2000000L) // 2 MHz / 16 = 125 kHz
+ ADC0.CTRLC |= ADC_PRESC_DIV16_gc;
+#elif (F_CPU >= 1000000L) // 1 MHz / 8 = 125 kHz
+ ADC0.CTRLC |= ADC_PRESC_DIV8_gc;
+#else // 128 kHz / 2 = 64 kHz -> This is the closest you can get, the prescaler is 2
+ ADC0.CTRLC |= ADC_PRESC_DIV2_gc;
+#endif
+
+ /* Enable ADC */
+ ADC0.CTRLA |= ADC_ENABLE_bm;
+ analogReference(VDD);
#endif
- PORTMUX.USARTROUTEA = 0;
+ PORTMUX.USARTROUTEA = 0;
- setup_timers();
+ setup_timers();
- /********************* TCB for system time tracking **************************/
+ /********************* TCB for system time tracking **************************/
- /* Calculate relevant time tracking values */
- microseconds_per_timer_overflow = clockCyclesToMicroseconds(TIME_TRACKING_CYCLES_PER_OVF);
- microseconds_per_timer_tick = microseconds_per_timer_overflow/TIME_TRACKING_TIMER_PERIOD;
+ // BUG: we can compensate for F_CPU by fine tuning value of TIME_TRACKING_TIMER_COUNT
- millis_inc = microseconds_per_timer_overflow / 1000;
- fract_inc = ((microseconds_per_timer_overflow % 1000));
+ /* Select vanilla 16 bit periodic interrupt mode */
+ _timer->CTRLB = TCB_CNTMODE_INT_gc;
- /* Default Periodic Interrupt Mode */
- /* TOP value for overflow every 1024 clock cycles */
- _timer->CCMP = TIME_TRACKING_TIMER_PERIOD;
+ /* TOP value for overflow every N clock cycles */
+ _timer->CCMP = TIME_TRACKING_TIMER_COUNT - 1;
- /* Enable TCB interrupt */
- _timer->INTCTRL |= TCB_CAPT_bm;
+ /* Enable TCB interrupt */
+ _timer->INTCTRL |= TCB_CAPT_bm;
- /* Clock selection -> same as TCA (F_CPU/64 -- 250kHz) */
- _timer->CTRLA = TCB_CLKSEL_CLKTCA_gc;
+ /* Clock selection is F_CPU/N -- which is independent of TCA */
+#if TIME_TRACKING_TIMER_DIVIDER == 1
+ _timer->CTRLA = TCB_CLKSEL_CLKDIV1_gc; /* F_CPU */
+#elif TIME_TRACKING_TIMER_DIVIDER == 2
+ _timer->CTRLA = TCB_CLKSEL_CLKDIV2_gc; /* F_CPU/2 */
+#else
+#assert "TIME_TRACKING_TIMER_DIVIDER not supported"
+#endif
- /* Enable & start */
- _timer->CTRLA |= TCB_ENABLE_bm; /* Keep this last before enabling interrupts to ensure tracking as accurate as possible */
+ /* Enable & start */
+ _timer->CTRLA |= TCB_ENABLE_bm; /* Keep this last before enabling interrupts to ensure tracking as accurate as possible */
-/*************************** ENABLE GLOBAL INTERRUPTS *************************/
+ /*************************** ENABLE GLOBAL INTERRUPTS *************************/
- sei();
+ sei();
}
-void setup_timers(void) __attribute__((weak));
\ No newline at end of file
+void setup_timers()
+{
+ // TYPE A TIMER
+
+ // PORTMUX setting for TCA (defined in pins_arduino.h)
+ PORTMUX.TCAROUTEA = TCA0_PINS;
+
+ // Enable split mode before anything else
+ TCA0.SPLIT.CTRLD = TCA_SINGLE_SPLITM_bm;
+
+ // Period setting, two 8 bit registers
+ TCA0.SPLIT.LPER =
+ TCA0.SPLIT.HPER = PWM_TIMER_PERIOD;
+
+ // Default duty 50%, will re-assign in analogWrite()
+ TCA0.SPLIT.LCMP0 =
+ TCA0.SPLIT.LCMP1 =
+ TCA0.SPLIT.LCMP2 =
+ TCA0.SPLIT.HCMP0 =
+ TCA0.SPLIT.HCMP1 =
+ TCA0.SPLIT.HCMP2 = PWM_TIMER_COMPARE;
+
+#if F_CPU <= 1000000L
+ // Use DIV4 prescaler (giving 250kHz clock on 1MHz), enable TCA timer
+ TCA0.SPLIT.CTRLA = (TCA_SPLIT_CLKSEL_DIV4_gc) | (TCA_SPLIT_ENABLE_bm);
+#elif F_CPU <= 2000000L
+ // Use DIV8 prescaler (giving 250kHz clock on 2MHz), enable TCA timer
+ TCA0.SPLIT.CTRLA = (TCA_SPLIT_CLKSEL_DIV8_gc) | (TCA_SPLIT_ENABLE_bm);
+#elif F_CPU <= 8000000L
+ // Use DIV16 prescaler (giving 250kHz clocke on 4MHz, 500kHz clock on 8MHz), enable TCA timer
+ TCA0.SPLIT.CTRLA = (TCA_SPLIT_CLKSEL_DIV16_gc) | (TCA_SPLIT_ENABLE_bm);
+#else
+ // Use DIV64 prescaler (giving 250kHz clock on 16MHz), enable TCA timer
+ TCA0.SPLIT.CTRLA = (TCA_SPLIT_CLKSEL_DIV64_gc) | (TCA_SPLIT_ENABLE_bm);
+#endif
+
+ // TYPE B TIMERS
+
+ // Set up routing (defined in pins_arduino.h)
+ PORTMUX.TCBROUTEA = 0
+#if defined(TCB0)
+ | TCB0_PINS
+#endif
+#if defined(TCB1)
+ | TCB1_PINS
+#endif
+#if defined(TCB2)
+ | TCB2_PINS
+#endif
+#if defined(TCB3)
+ | TCB3_PINS
+#endif
+ ;
+
+ // Start with TCB0
+ TCB_t *timer_B = (TCB_t *)&TCB0;
+
+// Find end timer
+#if defined(TCB3)
+ TCB_t *timer_B_end = (TCB_t *)&TCB3;
+#elif defined(TCB2)
+ TCB_t *timer_B_end = (TCB_t *)&TCB2;
+#elif defined(TCB1)
+ TCB_t *timer_B_end = (TCB_t *)&TCB1;
+#else
+ TCB_t *timer_B_end = (TCB_t *)&TCB0;
+#endif
+
+ // Timer B Setup loop for TCB[0:end]
+ do
+ {
+ // 8 bit PWM mode, but do not enable output yet, will do in analogWrite()
+ timer_B->CTRLB = (TCB_CNTMODE_PWM8_gc);
+
+ // Assign 8-bit period
+ timer_B->CCMPL = PWM_TIMER_PERIOD;
+
+ // default duty 50%, set when output enabled
+ timer_B->CCMPH = PWM_TIMER_COMPARE;
+
+ // Use TCA clock (250kHz) and enable
+ // (sync update commented out, might try to synchronize later
+ timer_B->CTRLA = (TCB_CLKSEL_CLKTCA_gc)
+ //|(TCB_SYNCUPD_bm)
+ | (TCB_ENABLE_bm);
+
+ // Increment pointer to next TCB instance
+ timer_B++;
+
+ // Stop when pointing to TCB3
+ } while (timer_B <= timer_B_end);
+
+ // Stuff for synchronizing PWM timers
+ // // Restart TCA to sync TCBs
+ // // should not be needed
+ // TCA0.SINGLE.CTRLESET = TCA_SINGLE_CMD_RESTART_gc;
+ // TCA0.SINGLE.CTRLECLR = TCA_SINGLE_CMD_RESTART_gc;
+ //
+ // timer_B = (TCB_t *)&TCB0;
+ //
+ // // TCB are sync to TCA, remove setting
+ // for (uint8_t digitial_pin_timer = (TIMERB0 - TIMERB0);
+ // digitial_pin_timer < (TIMERB3 - TIMERB0);
+ // digitial_pin_timer++)
+ // {
+ // // disable sync with tca
+ // timer_B->CTRLA &= ~ (TCB_SYNCUPD_bm);
+ //
+ // // Add offset to register
+ // timer_B++;
+ //
+ // }
+}
diff --git a/megaavr/cores/coreX-corefiles/wiring_analog.c b/megaavr/cores/coreX-corefiles/wiring_analog.c
index c5a715b..5305d72 100644
--- a/megaavr/cores/coreX-corefiles/wiring_analog.c
+++ b/megaavr/cores/coreX-corefiles/wiring_analog.c
@@ -22,95 +22,74 @@
Modified 28 September 2010 by Mark Sproul
*/
-#include "wiring_private.h"
-#include "pins_arduino.h"
#include "Arduino.h"
-
-uint8_t analog_reference = DEFAULT;
+#include "pins_arduino.h"
+#include "wiring_private.h"
void analogReference(uint8_t mode)
{
- /* Clear relevant settings */
- ADC0.CTRLC &= ~(ADC_REFSEL_gm);
- VREF.CTRLA &= ~(VREF_ADC0REFSEL_gm);
-
- /* If reference NOT using internal reference from VREF */
- if((mode == EXTERNAL) || (mode == VDD)) {
-
- /* Set reference in ADC peripheral */
- ADC0.CTRLC |= mode;
-
- /* If reference using internal reference from VREF */
- } else if (
- (mode == INTERNAL0V55)
- || (mode == INTERNAL1V1)
- || (mode == INTERNAL2V5)
- || (mode == INTERNAL4V3)
- || (mode == INTERNAL1V5)) {
-
- /* Set ADC reference to INTERNAL */
- ADC0.CTRLC |= INTERNAL;
-
- /* Configure VREF ADC0 reference */
- VREF.CTRLA |= (mode << VREF_ADC0REFSEL_gp);
-
- /* Non-standard values / default */
- } else {
-
- /* Non valid value will set default */
- /* Set ADC reference to INTERNAL */
- ADC0.CTRLC |= INTERNAL;
-
- /* Configure VREF ADC0 reference */
- VREF.CTRLA |= (INTERNAL0V55 << VREF_ADC0REFSEL_gp);
- }
+ switch (mode)
+ {
+ case EXTERNAL:
+ case VDD:
+ ADC0.CTRLC = (ADC0.CTRLC & ~(ADC_REFSEL_gm)) | mode | ADC_SAMPCAP_bm; // Per datasheet, recommended SAMPCAP=1 at ref > 1v - we don't *KNOW* the external reference will be >1v, but it's probably more likely...
+ // VREF.CTRLA does not need to be reconfigured, as the voltage references only supply their specified voltage when requested to do so by the ADC.
+ break;
+ case INTERNAL0V55:
+ VREF.CTRLA = VREF.CTRLA & ~(VREF_ADC0REFSEL_gm); // These bits are all 0 for 0.55v reference, so no need to do the mode << VREF_ADC0REFSEL_gp here;
+ ADC0.CTRLC = (ADC0.CTRLC & ~(ADC_REFSEL_gm | ADC_SAMPCAP_bm)) | INTERNAL; // Per datasheet, recommended SAMPCAP=0 at ref < 1v
+ break;
+ case INTERNAL1V1:
+ case INTERNAL2V5:
+ case INTERNAL4V34:
+ case INTERNAL1V5:
+ VREF.CTRLA = (VREF.CTRLA & ~(VREF_ADC0REFSEL_gm)) | (mode << VREF_ADC0REFSEL_gp);
+ ADC0.CTRLC = (ADC0.CTRLC & ~(ADC_REFSEL_gm)) | INTERNAL | ADC_SAMPCAP_bm; // Per datasheet, recommended SAMPCAP=1 at ref > 1v
+ break;
+ default:
+ ADC0.CTRLC = (ADC0.CTRLC & ~(ADC_REFSEL_gm)) | VDD | ADC_SAMPCAP_bm; // Per datasheet, recommended SAMPCAP=1 at ref > 1v - we don't *KNOW* the external reference will be >1v, but it's probably more likely...
+ }
}
int analogRead(uint8_t pin)
{
- pin = digitalPinToAnalogInput(pin);
- if(pin > NUM_ANALOG_INPUTS) return NOT_A_PIN;
-
- /* Check if TWI is operating on double bonded pin (Master Enable is high
- in both Master and Slave mode for bus error detection, so this can
- indicate an active state for Wire) */
- if(isDoubleBondedActive(pin)) return 0;
-
- uint8_t low, high;
-
-#if defined(analogPinToChannel)
- /* If analog pin number != adc0 channel */
-#endif
+ pin = digitalPinToAnalogInput(pin);
+ if (pin > 15)
+ return NOT_A_PIN;
#if defined(ADC0)
- /* Reference should be already set up */
- /* Select channel */
- ADC0.MUXPOS = (pin << ADC_MUXPOS_gp);
-
- /* Start conversion */
- ADC0.COMMAND = ADC_STCONV_bm;
+ /* Reference should be already set up */
+ /* Select channel */
+ ADC0.MUXPOS = (pin << ADC_MUXPOS_gp);
- /* Wait for result ready */
- while(!(ADC0.INTFLAGS & ADC_RESRDY_bm));
+ /* Start conversion */
+ ADC0.COMMAND = ADC_STCONV_bm;
- /* Save state */
- uint8_t status = SREG;
- cli();
+ /* Wait for result ready */
+ while (!(ADC0.INTFLAGS & ADC_RESRDY_bm))
+ ;
- /* Read result */
- low = ADC0.RESL;
- high = ADC0.RESH;
+ /* Combine two bytes */
+ return ADC0.RES;
- /* Restore state */
- SREG = status;
-
-#else /* No ADC, return 0 */
- low = 0;
- high = 0;
+#else /* No ADC, return 0 */
+ return 0;
#endif
+}
- /* Combine two bytes */
- return (high << 8) | low;
+// analogReadResolution() has two legal values you can pass it, 8 or 10.
+// According to the datasheet, you can clock the ADC faster if you set it to 8.
+// Like the pinswap functions, if the user passes bogus values, we set it to the default and return false.
+uint8_t analogReadResolution(uint8_t res)
+{
+ if (res==8)
+ {
+ ADC0.CTRLA |= ADC_RESSEL_bm;
+ return 1;
+ }
+ // If argument wasn't 8, we'll be putting it to default value either way
+ ADC0.CTRLA &= ~ADC_RESSEL_bm;
+ return (res == 10); // Only return true if the value passed was the valid option, 10.
}
// Right now, PWM output only works on the pins with
@@ -119,76 +98,133 @@ int analogRead(uint8_t pin)
// to digital output.
void analogWrite(uint8_t pin, int val)
{
+ uint8_t bit_pos = digitalPinToBitPosition(pin);
+ if (bit_pos == NOT_A_PIN)
+ return;
+
+ // We need to make sure the PWM output is enabled for those pins
+ // that support it, as we turn it off when digitally reading or
+ // writing with them. Also, make sure the pin is in output mode
+ // for consistently with Wiring, which doesn't require a pinMode
+ // call for the analog output pins.
+ pinMode(pin, OUTPUT);
+
+ if (val <= 0)
+ { /* if zero or negative drive digital low */
+ digitalWrite(pin, LOW);
+ }
+ else if (val >= 255)
+ { /* if max or greater drive digital high */
+ digitalWrite(pin, HIGH);
+ }
+ else
+ { /* handle pwm to generate analog value */
+
+ /* Get timer */
+ uint8_t digital_pin_timer = digitalPinToTimer(pin);
+
+ uint8_t *timer_cmp_out;
+ TCB_t *timer_B;
+
+ uint8_t savedSREG;
+
+ /* Find out Port and Pin to correctly handle port mux, and timer. */
+ switch (digital_pin_timer)
+ {
+ case TIMERA0:
+ /* Split mode, 2x3 8 bit registers. (chapter 19.7) */
+ if (bit_pos >= 3)
+ {
+ timer_cmp_out = ((uint8_t *)(&TCA0.SPLIT.HCMP0)) + 2 * (bit_pos - 3);
+ ++bit_pos; /* Upper 3 bits are shifted by 1 */
+ }
+ else
+ {
+ /* Calculate correct compare buffer register */
+ timer_cmp_out = ((uint8_t *)(&TCA0.SPLIT.LCMP0)) + 2 * bit_pos;
+ }
+
+ /* Configure duty cycle for correct compare channel */
+ savedSREG = SREG;
+ cli();
+ (*timer_cmp_out) = (val); // non-atomic 16-bit write operation
+ SREG = savedSREG;
+
+ /* Enable output on pin */
+ TCA0.SPLIT.CTRLB |= (1 << (TCA_SPLIT_LCMP0EN_bp + bit_pos));
+ break;
+
+ case TIMERB0:
+ case TIMERB1:
+ case TIMERB2:
+ case TIMERB3:
+
+ /* Get pointer to timer, TIMERB0 order definition in Arduino.h*/
+ //assert (((TIMERB0 - TIMERB3) == 2));
+ timer_B = ((TCB_t *)&TCB0 + (digital_pin_timer - TIMERB0));
+
+ // (16-bit read/write operation are non-atomic and use a temporary register)
+ savedSREG = SREG;
+ cli();
+ timer_B->CCMPL = timer_B->CCMPL; // Copy CCMPL into temporary register
+ timer_B->CCMPH = val; // Set CCMPH value + copy temporary register content into CCMPL
+ SREG = savedSREG;
+
+ /* Enable Timer Output */
+ timer_B->CTRLB |= (TCB_CCMPEN_bm);
+
+ break;
+
+ /* If non timer pin, or unknown timer definition. */
+ /* do a digital write */
+
+ case NOT_ON_TIMER:
+ default:
+ if (val < 128)
+ {
+ digitalWrite(pin, LOW);
+ }
+ else
+ {
+ digitalWrite(pin, HIGH);
+ }
+ break;
+ }
+ }
+}
- uint8_t bit_pos = digitalPinToBitPosition(pin);
- if(bit_pos == NOT_A_PIN || isDoubleBondedActive(pin)) return;
-
- // We need to make sure the PWM output is enabled for those pins
- // that support it, as we turn it off when digitally reading or
- // writing with them. Also, make sure the pin is in output mode
- // for consistently with Wiring, which doesn't require a pinMode
- // call for the analog output pins.
- pinMode(pin, OUTPUT);
-
- if(val < 1){ /* if zero or negative drive digital low */
-
- digitalWrite(pin, LOW);
-
- } else if(val > 255){ /* if max or greater drive digital high */
-
- digitalWrite(pin, HIGH);
-
- } else { /* handle pwm to generate analog value */
-
- /* Get timer */
- uint8_t digital_pin_timer = digitalPinToTimer(pin);
-
- uint16_t* timer_cmp_out;
- TCB_t *timer_B;
-
- /* Find out Port and Pin to correctly handle port mux, and timer. */
- switch (digital_pin_timer) {
-
- case TIMERA0:
- /* Calculate correct compare buffer register */
- timer_cmp_out = ((uint16_t*) (&TCA0.SINGLE.CMP0BUF)) + bit_pos;
-
- /* Configure duty cycle for correct compare channel */
- (*timer_cmp_out) = (val);
-
- /* Enable output on pin */
- TCA0.SINGLE.CTRLB |= (1 << (TCA_SINGLE_CMP0EN_bp + bit_pos));
-
- break;
-
- case TIMERB0:
- case TIMERB1:
- case TIMERB2:
- case TIMERB3:
-
- /* Get pointer to timer, TIMERB0 order definition in Arduino.h*/
- //assert (((TIMERB0 - TIMERB3) == 2));
- timer_B = ((TCB_t *)&TCB0 + (digital_pin_timer - TIMERB0));
-
- /* set duty cycle */
- timer_B->CCMPH = val;
-
- /* Enable Timer Output */
- timer_B->CTRLB |= (TCB_CCMPEN_bm);
-
- break;
-
- /* If non timer pin, or unknown timer definition. */
- /* do a digital write */
-
- case NOT_ON_TIMER:
- default:
- if (val < 128) {
- digitalWrite(pin, LOW);
- } else {
- digitalWrite(pin, HIGH);
- }
- break;
- }
- }
-}
\ No newline at end of file
+// Set PWM repeat frequency for all PWM outputs with
+// hardware support.
+// The argument is the desired frequency in kHz. A
+// best effort will be made to find something that matches.
+//
+void analogWriteFrequency(uint8_t kHz)
+{
+ static const byte index2setting[] = {
+#if F_CPU > 1000000L
+#if F_CPU > 2000000L
+#if F_CPU > 4000000L
+#if F_CPU > 8000000L
+ TCA_SPLIT_ENABLE_bm | TCA_SPLIT_CLKSEL_DIV64_gc, // ~1 kHz PWM, ~250kHz clock
+#endif
+ TCA_SPLIT_ENABLE_bm | TCA_SPLIT_CLKSEL_DIV16_gc, // ~2 kHz is not possible, use 4
+#endif
+ TCA_SPLIT_ENABLE_bm | TCA_SPLIT_CLKSEL_DIV16_gc, // ~4 kHz PWM, ~1MHz clock
+#endif
+ TCA_SPLIT_ENABLE_bm | TCA_SPLIT_CLKSEL_DIV8_gc, // ~8 kHz PWM, ~2MHz clock
+#endif
+ TCA_SPLIT_ENABLE_bm | TCA_SPLIT_CLKSEL_DIV4_gc, // ~16 kHz PWM, ~4MHz clock
+ TCA_SPLIT_ENABLE_bm | TCA_SPLIT_CLKSEL_DIV2_gc, // ~32 kHz PWM, ~8MHz clock
+ TCA_SPLIT_ENABLE_bm | TCA_SPLIT_CLKSEL_DIV1_gc // ~64 kHz PWM, ~16MHz clock
+ };
+ uint8_t index = 0;
+
+ while (kHz > 1)
+ { // find approximate match
+ kHz >>= 1;
+ if (++index >= sizeof(index2setting) - 1) break;
+ }
+ TCA0.SPLIT.CTRLA = index2setting[index];
+
+ // note that this setting also influences Tone.cpp
+}
diff --git a/megaavr/cores/coreX-corefiles/wiring_digital.c b/megaavr/cores/coreX-corefiles/wiring_digital.c
index 0d51d57..3f07a6e 100644
--- a/megaavr/cores/coreX-corefiles/wiring_digital.c
+++ b/megaavr/cores/coreX-corefiles/wiring_digital.c
@@ -26,52 +26,52 @@
#include "wiring_private.h"
#include "pins_arduino.h"
-__attribute__((weak)) bool isDoubleBondedActive(uint8_t pin __attribute__((unused))) {
- return false;
-};
-
-void pinMode(uint8_t pin, PinMode mode)
+void pinMode(uint8_t pin, uint8_t mode)
{
- uint8_t bit_mask = digitalPinToBitMask(pin);
-
- if ((bit_mask == NOT_A_PIN) || (mode > INPUT_PULLUP) || isDoubleBondedActive(pin)) return;
-
- PORT_t* port = digitalPinToPortStruct(pin);
- if(port == NULL) return;
-
- if(mode == OUTPUT){
-
- /* Configure direction as output */
- port->DIRSET = bit_mask;
-
- } else { /* mode == INPUT or INPUT_PULLUP */
-
- uint8_t bit_pos = digitalPinToBitPosition(pin);
- /* Calculate where pin control register is */
- volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
-
- /* Save state */
- uint8_t status = SREG;
- cli();
-
- /* Configure direction as input */
- port->DIRCLR = bit_mask;
-
- /* Configure pull-up resistor */
- if(mode == INPUT_PULLUP){
-
- /* Enable pull-up */
- *pin_ctrl_reg |= PORT_PULLUPEN_bm;
-
- } else { /* mode == INPUT (no pullup) */
-
- /* Disable pull-up */
- *pin_ctrl_reg &= ~(PORT_PULLUPEN_bm);
- }
-
- /* Restore state */
- SREG = status;
- }
+ uint8_t bit_mask = digitalPinToBitMask(pin);
+
+ if ((bit_mask == NOT_A_PIN) || (mode > INPUT_PULLUP))
+ return;
+
+ PORT_t *port = digitalPinToPortStruct(pin);
+ if (port == NULL)
+ return;
+
+ if (mode == OUTPUT)
+ {
+ /* Configure direction as output */
+ port->DIRSET = bit_mask;
+ }
+ else
+ { /* mode == INPUT or INPUT_PULLUP */
+
+ uint8_t bit_pos = digitalPinToBitPosition(pin);
+ /* Calculate where pin control register is */
+ volatile uint8_t *pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
+
+ /* Save state */
+ uint8_t status = SREG;
+ cli();
+
+ /* Configure direction as input */
+ port->DIRCLR = bit_mask;
+
+ /* Configure pull-up resistor */
+ if (mode == INPUT_PULLUP)
+ {
+ /* Enable pull-up */
+ *pin_ctrl_reg |= PORT_PULLUPEN_bm;
+ }
+ else
+ { /* mode == INPUT (no pullup) */
+
+ /* Disable pull-up */
+ *pin_ctrl_reg &= ~(PORT_PULLUPEN_bm);
+ }
+
+ /* Restore state */
+ SREG = status;
+ }
}
// Forcing this inline keeps the callers from having to push their own stuff
@@ -79,7 +79,8 @@ void pinMode(uint8_t pin, PinMode mode)
// user than calling. (It will take more bytes on the 168.)
//
// But shouldn't this be moved into pinMode? Seems silly to check and do on
-// each digitalread or write.
+// each digitalread or write. One issue that then needs to be fixed is that
+// current implementation on analogWrite() depends on this behaviour.
//
// Mark Sproul:
// - Removed inline. Save 170 bytes on atmega1280
@@ -90,125 +91,176 @@ void pinMode(uint8_t pin, PinMode mode)
//static inline void turnOffPWM(uint8_t timer)
static void turnOffPWM(uint8_t pin)
{
- /* Actually turn off compare channel, not the timer */
-
- /* Get pin's timer */
- uint8_t timer = digitalPinToTimer(pin);
- if(timer == NOT_ON_TIMER) return;
+ /* Actually turn off compare channel, not the timer */
- uint8_t bit_pos;
- TCB_t *timerB;
+ /* Get pin's timer */
+ uint8_t timer = digitalPinToTimer(pin);
+ if (timer == NOT_ON_TIMER)
+ return;
- switch (timer) {
+ uint8_t bit_pos;
+ TCB_t *timerB;
- /* TCA0 */
- case TIMERA0:
- /* Bit position will give output channel */
- bit_pos = digitalPinToBitPosition(pin);
+ switch (timer)
+ {
+ /* TCA0 */
+ case TIMERA0:
+ /* Bit position will give output channel */
+ bit_pos = digitalPinToBitPosition(pin);
- /* Disable corresponding channel */
- TCA0.SINGLE.CTRLB &= ~(1 << (TCA_SINGLE_CMP0EN_bp + bit_pos));
+ /* Disable corresponding channel */
+ if (bit_pos >= 3) ++bit_pos; /* Upper 3 bits are shifted by 1 */
+ TCA0.SPLIT.CTRLB &= ~(1 << (TCA_SPLIT_LCMP0EN_bp + bit_pos));
- break;
+ break;
- /* TCB - only one output */
- case TIMERB0:
- case TIMERB1:
- case TIMERB2:
- case TIMERB3:
+ /* TCB - only one output */
+ case TIMERB0:
+ case TIMERB1:
+ case TIMERB2:
+ case TIMERB3:
- timerB = (TCB_t *)&TCB0 + (timer - TIMERB0);
+ timerB = (TCB_t *)&TCB0 + (timer - TIMERB0);
- /* Disable TCB compare channel */
- timerB->CTRLB &= ~(TCB_CCMPEN_bm);
+ /* Disable TCB compare channel */
+ timerB->CTRLB &= ~(TCB_CCMPEN_bm);
- break;
- default:
- break;
- }
+ break;
+ default:
+ break;
+ }
}
-void digitalWrite(uint8_t pin, PinStatus val)
+void digitalWrite(uint8_t pin, uint8_t val)
{
- /* Get bit mask for pin */
- uint8_t bit_mask = digitalPinToBitMask(pin);
- if(bit_mask == NOT_A_PIN || isDoubleBondedActive(pin)) return;
-
- /* Turn off PWM if applicable */
-
- // If the pin that support PWM output, we need to turn it off
- // before doing a digital write.
- turnOffPWM(pin);
-
- /* Assuming the direction is already output !! */
-
- /* Get port */
- PORT_t *port = digitalPinToPortStruct(pin);
-
- /* Output direction */
- if(port->DIR & bit_mask){
-
- /* Set output to value */
- if (val == LOW) { /* If LOW */
- port->OUTCLR = bit_mask;
+ /* Get bit mask for pin */
+ uint8_t bit_mask = digitalPinToBitMask(pin);
+ if (bit_mask == NOT_A_PIN)
+ return;
+
+ /* Turn off PWM if applicable */
+
+ // If the pin that support PWM output, we need to turn it off
+ // before doing a digital write.
+ turnOffPWM(pin);
+
+ /* Assuming the direction is already output !! */
+
+ /* Get port */
+ PORT_t *port = digitalPinToPortStruct(pin);
+
+ /* Output direction */
+ if (port->DIR & bit_mask)
+ {
+ /* Set output to value */
+ if (val == LOW)
+ { /* If LOW */
+ port->OUTCLR = bit_mask;
+ }
+ else if (val == CHANGE)
+ { /* If TOGGLE */
+ port->OUTTGL = bit_mask;
+ /* If HIGH OR > TOGGLE */
+ }
+ else
+ {
+ port->OUTSET = bit_mask;
+ }
+
+ /* Input direction */
+ }
+ else
+ {
+ /* Old implementation has side effect when pin set as input -
+ pull up is enabled if this function is called.
+ Should we purposely implement this side effect?
+ */
+
+ /* Get bit position for getting pin ctrl reg */
+ uint8_t bit_pos = digitalPinToBitPosition(pin);
+
+ /* Calculate where pin control register is */
+ volatile uint8_t *pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
+
+ /* Save system status and disable interrupts */
+ uint8_t status = SREG;
+ cli();
+
+ if (val == LOW)
+ {
+ /* Disable pullup */
+ *pin_ctrl_reg &= ~PORT_PULLUPEN_bm;
+ }
+ else
+ {
+ /* Enable pull-up */
+ *pin_ctrl_reg |= PORT_PULLUPEN_bm;
+ }
+
+ /* Restore system status */
+ SREG = status;
+ }
+}
- } else if (val == CHANGE) { /* If TOGGLE */
- port->OUTTGL = bit_mask;
- /* If HIGH OR > TOGGLE */
- } else {
- port->OUTSET = bit_mask;
- }
+inline __attribute__((always_inline)) void digitalWriteFast(uint8_t pin, uint8_t val)
+{
+ // Make sure pin is constant and know at compile time
+ check_constant_pin(pin);
+
+ // Mega-0, Tiny-1 style IOPORTs
+ // Assumes VPORTs exist starting at 0 for each PORT structure
+ uint8_t mask = 1 << digital_pin_to_bit_position[pin];
+ uint8_t port = digital_pin_to_port[pin];
+ VPORT_t *vport;
+
+ // Write pin value from VPORTx.OUT register
+ vport = (VPORT_t *)(port * 4);
+
+ if (val == HIGH)
+ vport->OUT |= mask;
+ else if (val == LOW)
+ vport->OUT &= ~mask;
+ else // CHANGE
+ vport->IN = mask;
+}
- /* Input direction */
- } else {
- /* Old implementation has side effect when pin set as input -
- pull up is enabled if this function is called.
- Should we purposely implement this side effect?
- */
+uint8_t digitalRead(uint8_t pin)
+{
+ /* Get bit mask and check valid pin */
+ uint8_t bit_mask = digitalPinToBitMask(pin);
+ if (bit_mask == NOT_A_PIN)
+ return LOW;
- /* Get bit position for getting pin ctrl reg */
- uint8_t bit_pos = digitalPinToBitPosition(pin);
+ // If the pin that support PWM output, we need to turn it off
+ // before getting a digital reading.
+ turnOffPWM(pin);
- /* Calculate where pin control register is */
- volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos);
+ /* Get port and check valid port */
+ PORT_t *port = digitalPinToPortStruct(pin);
- /* Save system status and disable interrupts */
- uint8_t status = SREG;
- cli();
+ /* Read pin value from PORTx.IN register */
+ if (port->IN & bit_mask)
+ return HIGH;
+ else
+ return LOW;
- if(val == LOW){
- /* Disable pullup */
- *pin_ctrl_reg &= ~PORT_PULLUPEN_bm;
+ return LOW;
+}
- } else {
- /* Enable pull-up */
- *pin_ctrl_reg |= PORT_PULLUPEN_bm;
- }
+inline __attribute__((always_inline)) uint8_t digitalReadFast(uint8_t pin)
+{
+ // Make sure pin is constant and know at compile time
+ check_constant_pin(pin);
- /* Restore system status */
- SREG = status;
- }
+ // Mega-0, Tiny-1 style IOPORTs
+ // Assumes VPORTs exist starting at 0 for each PORT structure
+ uint8_t mask = 1 << digital_pin_to_bit_position[pin];
+ uint8_t port = digital_pin_to_port[pin];
+ VPORT_t *vport;
-}
+ // Old style port logic is a small integer 0 for PORTA, 1 for PORTB etc.
+ vport = (VPORT_t *)(port * 4);
-PinStatus digitalRead(uint8_t pin)
-{
- /* Get bit mask and check valid pin */
- uint8_t bit_mask = digitalPinToBitMask(pin);
- if(bit_mask == NOT_A_PIN || isDoubleBondedActive(pin)) return LOW;
-
- // If the pin that support PWM output, we need to turn it off
- // before getting a digital reading.
- turnOffPWM(pin);
-
- /* Get port and check valid port */
- PORT_t *port = digitalPinToPortStruct(pin);
-
- /* Read pin value from PORTx.IN register */
- if(port->IN & bit_mask){
- return HIGH;
- } else {
- return LOW;
- }
- return LOW;
+ // Read pin value from VPORTx.IN register
+ return !!(vport->IN & mask);
}
diff --git a/megaavr/cores/coreX-corefiles/wiring_private.h b/megaavr/cores/coreX-corefiles/wiring_private.h
index 9597ed8..a38e94e 100644
--- a/megaavr/cores/coreX-corefiles/wiring_private.h
+++ b/megaavr/cores/coreX-corefiles/wiring_private.h
@@ -23,20 +23,21 @@
#ifndef WiringPrivate_h
#define WiringPrivate_h
-#include
#include
-#include
+#include
#include
+#include
#include "Arduino.h"
#ifdef __cplusplus
-extern "C"{
+extern "C"
+{
#endif
-uint32_t countPulseASM(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops);
+ uint32_t countPulseASM(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops);
-typedef void (*voidFuncPtr)(void);
+ typedef void (*voidFuncPtr)(void);
#ifdef __cplusplus
} // extern "C"
diff --git a/megaavr/cores/coreX-corefiles/wiring_pulse.c b/megaavr/cores/coreX-corefiles/wiring_pulse.c
index 3d75cd8..c4fd7e4 100644
--- a/megaavr/cores/coreX-corefiles/wiring_pulse.c
+++ b/megaavr/cores/coreX-corefiles/wiring_pulse.c
@@ -20,8 +20,8 @@
Boston, MA 02111-1307 USA
*/
-#include "wiring_private.h"
#include "pins_arduino.h"
+#include "wiring_private.h"
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
@@ -32,24 +32,24 @@
*/
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
- // cache the port and bit of the pin in order to speed up the
- // pulse width measuring loop and achieve finer resolution. calling
- // digitalRead() instead yields much coarser resolution.
- uint8_t bit = digitalPinToBitMask(pin);
- uint8_t port = digitalPinToPort(pin);
- uint8_t stateMask = (state ? bit : 0);
+ // cache the port and bit of the pin in order to speed up the
+ // pulse width measuring loop and achieve finer resolution. calling
+ // digitalRead() instead yields much coarser resolution.
+ uint8_t bit = digitalPinToBitMask(pin);
+ uint8_t port = digitalPinToPort(pin);
+ uint8_t stateMask = (state ? bit : 0);
- // convert the timeout from microseconds to a number of times through
- // the initial loop; it takes approximately 16 clock cycles per iteration
- unsigned long maxloops = microsecondsToClockCycles(timeout)/12;
+ // convert the timeout from microseconds to a number of times through
+ // the initial loop; it takes approximately 16 clock cycles per iteration
+ unsigned long maxloops = microsecondsToClockCycles(timeout) / 12;
- unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);
+ unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops);
- // prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
- if (width)
- return clockCyclesToMicroseconds(width * 16 + 16);
- else
- return 0;
+ // prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
+ if (width)
+ return clockCyclesToMicroseconds(width * 16 + 16);
+ else
+ return 0;
}
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
@@ -62,32 +62,35 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
*/
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
- // cache the port and bit of the pin in order to speed up the
- // pulse width measuring loop and achieve finer resolution. calling
- // digitalRead() instead yields much coarser resolution.
- uint8_t bit = digitalPinToBitMask(pin);
- uint8_t port = digitalPinToPort(pin);
- uint8_t stateMask = (state ? bit : 0);
+ // cache the port and bit of the pin in order to speed up the
+ // pulse width measuring loop and achieve finer resolution. calling
+ // digitalRead() instead yields much coarser resolution.
+ uint8_t bit = digitalPinToBitMask(pin);
+ uint8_t port = digitalPinToPort(pin);
+ uint8_t stateMask = (state ? bit : 0);
- unsigned long startMicros = micros();
+ unsigned long startMicros = micros();
- // wait for any previous pulse to end
- while ((*portInputRegister(port) & bit) == stateMask) {
- if (micros() - startMicros > timeout)
- return 0;
- }
+ // wait for any previous pulse to end
+ while ((*portInputRegister(port) & bit) == stateMask)
+ {
+ if (micros() - startMicros > timeout)
+ return 0;
+ }
- // wait for the pulse to start
- while ((*portInputRegister(port) & bit) != stateMask) {
- if (micros() - startMicros > timeout)
- return 0;
- }
+ // wait for the pulse to start
+ while ((*portInputRegister(port) & bit) != stateMask)
+ {
+ if (micros() - startMicros > timeout)
+ return 0;
+ }
- unsigned long start = micros();
- // wait for the pulse to stop
- while ((*portInputRegister(port) & bit) == stateMask) {
- if (micros() - startMicros > timeout)
- return 0;
- }
- return micros() - start;
+ unsigned long start = micros();
+ // wait for the pulse to stop
+ while ((*portInputRegister(port) & bit) == stateMask)
+ {
+ if (micros() - startMicros > timeout)
+ return 0;
+ }
+ return micros() - start;
}
\ No newline at end of file
diff --git a/megaavr/cores/coreX-corefiles/wiring_shift.c b/megaavr/cores/coreX-corefiles/wiring_shift.c
index 0848df9..6819e7e 100644
--- a/megaavr/cores/coreX-corefiles/wiring_shift.c
+++ b/megaavr/cores/coreX-corefiles/wiring_shift.c
@@ -20,34 +20,37 @@
Boston, MA 02111-1307 USA
*/
-#include
-
-uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, BitOrder bitOrder) {
- uint8_t value = 0;
- uint8_t i;
-
- for (i = 0; i < 8; ++i) {
- digitalWrite(clockPin, HIGH);
- if (bitOrder == LSBFIRST)
- value |= digitalRead(dataPin) << i;
- else
- value |= digitalRead(dataPin) << (7 - i);
- digitalWrite(clockPin, LOW);
- }
- return value;
+#include "Arduino.h"
+
+uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
+{
+ uint8_t value = 0;
+ uint8_t i;
+
+ for (i = 0; i < 8; ++i)
+ {
+ digitalWrite(clockPin, HIGH);
+ if (bitOrder == LSBFIRST)
+ value |= digitalRead(dataPin) << i;
+ else
+ value |= digitalRead(dataPin) << (7 - i);
+ digitalWrite(clockPin, LOW);
+ }
+ return value;
}
-void shiftOut(uint8_t dataPin, uint8_t clockPin, BitOrder bitOrder, uint8_t val)
+void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
- uint8_t i;
-
- for (i = 0; i < 8; i++) {
- if (bitOrder == LSBFIRST)
- digitalWrite(dataPin, !!(val & (1 << i)));
- else
- digitalWrite(dataPin, !!(val & (1 << (7 - i))));
-
- digitalWrite(clockPin, HIGH);
- digitalWrite(clockPin, LOW);
- }
+ uint8_t i;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (bitOrder == LSBFIRST)
+ digitalWrite(dataPin, !!(val & (1 << i)));
+ else
+ digitalWrite(dataPin, !!(val & (1 << (7 - i))));
+
+ digitalWrite(clockPin, HIGH);
+ digitalWrite(clockPin, LOW);
+ }
}
diff --git a/megaavr/libraries/Comparator/README.md b/megaavr/libraries/Comparator/README.md
new file mode 100644
index 0000000..4947834
--- /dev/null
+++ b/megaavr/libraries/Comparator/README.md
@@ -0,0 +1,182 @@
+# Comparator
+A library for interfacing with the analog comparator peripheral in the megaAVR-0 series MCUs.
+Developed by [MCUdude](https://github.com/MCUdude/).
+The megaAVR-0 has one comparator where four positive and three negative pins are available for use. An alternative for the negative pin is to use an internally generated reference voltage instead.
+More useful information about the analog comparator can be found in the [Microchip Application Note TB3211](http://ww1.microchip.com/downloads/en/AppNotes/TB3211-Getting-Started-with-AC-90003211A.pdf) and in the [megaAVR-0 family data sheet](http://ww1.microchip.com/downloads/en/DeviceDoc/megaAVR0-series-Family-Data-Sheet-DS40002015B.pdf).
+
+
+## Comparator
+Class for interfacing with the built-in comparator. Use the predefined objects `Comparator` or `Comparator0`.
+
+
+### input_p
+Variable for setting what input pin the positive input of the comparator should be connected to
+Accepted values:
+``` c++
+comparator::in_p::in0; // Use positive input pin 0 (PD2) as input
+comparator::in_p::in1; // Use positive input pin 1 (PD4) as input
+comparator::in_p::in2; // Use positive input pin 2 (PD6) as input
+comparator::in_p::in3; // Use positive input pin 3 (PD1) as input
+```
+
+##### Usage
+``` c++
+Comparator.input_p = comparator::in_p::in0; // Connect positive input pin 0 to the positive pin of the comparator
+```
+
+##### Default state
+`Comparator.input_p` defaults to `comparator::in_p::in0` if not specified in the user program.
+
+
+### input_n
+Variable for setting what input pin the negative input of the comparator should be connected to
+Accepted values:
+``` c++
+comparator::in_n::in0; // Use positive input pin 0 (PD3) as input
+comparator::in_n::in1; // Use positive input pin 1 (PD5) as input
+comparator::in_n::in2; // Use positive input pin 2 (PD7) as input
+comparator::in_n::dacref; // Use DACREF as input
+```
+
+##### Usage
+``` c++
+Comparator.input_n = comparator::in_n::in0; // Connect negative input pin 0 to the negative pin of the comparator
+```
+
+##### Default state
+`Comparator.input_n` defaults to `comparator::in_n::in0` if not specified in the user program.
+
+
+### reference
+Variable for setting what reference voltage the DACREF should be derived from. This voltage is internally generated.
+Accepted values:
+``` c++
+comparator::ref::disable; // Do not use any reference
+comparator::ref::vref_0v55; // 0.55V internal voltage
+comparator::ref::vref_1v1; // 1.1V internal voltage
+comparator::ref::vref_1v5; // 1.5V internal voltage
+comparator::ref::vref_2v5; // 2.5V internal voltage
+comparator::ref::vref_4v3; // 4.3V internal voltage
+comparator::ref::vref_avcc; // Use voltage on AVCC pin
+```
+
+##### Usage
+``` c++
+Comparator.reference = comparator::ref::vref_2v5; // Use the internal 2.5V reference for the DACREF
+```
+
+##### Default state
+`Comparator.reference` defaults to `comparator::ref::disable` if not specified in the user program.
+
+
+### dacref
+Variable for setting the DACREF value. This voltage can be selected as the input for the negative side of the comparator.
+This is the formula for the DACREF output voltage:
+
+
+
+##### Usage
+``` c++
+Comparator.dacref = 127; // Divide the reference voltage by two
+```
+
+##### Default state
+`Comparator.dacref` defaults to `255` if not specified in the user program.
+
+
+### hysteresis
+Variable for setting the comparator input hysteresis. Useful for eliminating "bouncing".
+Accepted values:
+``` c++
+comparator::hyst::disable; // No hysteresis
+comparator::hyst::small; // 10mV hysteresis (±5mV)
+comparator::hyst::medium; // 25mV hysteresis (±12.5mV)
+comparator::hyst::large; // 50mV hysteresis (±25mV)
+```
+
+##### Usage
+``` c++
+Comparator.hysteresis = comparator::hyst::large; // Use 50V hysteresis
+```
+
+##### Default state
+`Comparator.hysteresis` defaults to `comparator::hyst::disable` if not specified in the user program.
+
+
+### output
+Variable for setting the comparator output, internally and/or externally.
+Accepted values:
+``` c++
+comparator::out::disable; // No output pin, signal not inverted internally
+comparator::out::disable_invert; // No output pin, signal inverted internally
+comparator::out::enable; // Enable output pin (PA7), signal not inverted internally
+comparator::out::invert; // Enable output pin (PA7), signal inverted internally
+comparator::out::enable_invert; // Identical to out::invert
+```
+
+##### Usage
+``` c++
+Comparator.output = comparator::out::enable; // Enable output pin (PA7)
+```
+
+##### Default state
+`Comparator.output` defaults to `comparator::out::disable` if not specified in the user program.
+
+
+## init()
+Method for initializing the comparator.
+
+##### Usage
+```c++
+Comparator.init(); // Initialize comparator
+```
+
+
+## start()
+Method for starting the analog comparator.
+##### Usage
+```c++
+Comparator.start(); // Start comparator
+```
+
+
+## stop()
+Method for stopping the analog comparator.
+
+##### Usage
+```c++
+Comparator.stop(); // Stop comparator
+```
+
+
+## read()
+Reads the state of the analog comparator output. Works also when the physical output pin is disabled.
+
+##### Usage
+```c++
+bool comp_state = Comparator.read(); // Read comparator
+```
+
+
+## attachInterrupt()
+Method for enabling analog comparator interrupt. The interrupt will trigger when the the comparator output changes.
+Valid arguments for the third parameters are `RISING`, `FALLING` and `CHANGE`.
+
+##### Usage
+```c++
+Comparator.attachInterrupt(blinkLED, RISING); // Run the blinkLED function when the comparator output goes high
+
+void blinkLED()
+{
+ digitalWrite(myLedPin, CHANGE);
+}
+```
+
+
+## detachInterrupt()
+Method for disabling analog comparator interrupt.
+
+##### Usage
+```c++
+Comparator.detachInterrupt(); // Disable interrupt
+```
diff --git a/megaavr/libraries/Comparator/examples/Hysteresis/Hysteresis.ino b/megaavr/libraries/Comparator/examples/Hysteresis/Hysteresis.ino
new file mode 100644
index 0000000..9fbb4d2
--- /dev/null
+++ b/megaavr/libraries/Comparator/examples/Hysteresis/Hysteresis.ino
@@ -0,0 +1,38 @@
+/***********************************************************************|
+| megaAVR analog comparator library |
+| |
+| Hysteresis.ino |
+| |
+| A library for interfacing with the megaAVR analog comparator. |
+| Developed in 2019 by MCUdude |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use the negative and positive input 0 of the |
+| comparator. The output goes high if the positive input is higher than |
+| the negative input, and low otherwise. We'll also use the built-in |
+| hysteresis functionality to prevent false spikes. |
+| |
+| See Microchip's application note TB3211 for more information. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Configure relevant comparator parameters
+ Comparator.input_p = comparator::in_p::in0; // Use positive input 0 (PD2)
+ Comparator.input_n = comparator::in_n::in0; // Use negative input 0 (PD3)
+ Comparator.hysteresis = comparator::hyst::large; // Use a 50mV hysteresis
+ Comparator.output = comparator::out::enable; // Enable output on digital pin 7 (PA7)
+
+ // Initialize comparator
+ Comparator.init();
+
+ // Start comparator
+ Comparator.start();
+}
+
+void loop()
+{
+
+}
diff --git a/megaavr/libraries/Comparator/examples/Internal_reference/Internal_reference.ino b/megaavr/libraries/Comparator/examples/Internal_reference/Internal_reference.ino
new file mode 100644
index 0000000..1ff6485
--- /dev/null
+++ b/megaavr/libraries/Comparator/examples/Internal_reference/Internal_reference.ino
@@ -0,0 +1,43 @@
+/***********************************************************************|
+| megaAVR analog comparator library |
+| |
+| Internal_reference.ino |
+| |
+| A library for interfacing with the megaAVR analog comparator. |
+| Developed in 2019 by MCUdude |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use an internal reference voltage instead of an |
+| external one on the negative pin. This eliminates the need for an |
+| external voltage divider to generate a reference. Note that the |
+| internal reference requires a stable voltage to function properly. |
+| |
+| This is the formula for the generated voltage: |
+| Vdacref = (DACREF / 256) * Vref |
+| |
+| See Microchip's application note TB3211 for more information. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Configure relevant comparator parameters
+ Comparator.input_p = comparator::in_p::in0; // Use positive input 0 (PD2)
+ Comparator.input_n = comparator::in_n::dacref; // Connect the negative pin to the DACREF voltage
+ Comparator.reference = comparator::ref::vref_2v5; // Set the DACREF voltage to 2.5V
+ Comparator.dacref = 127; // Gives us 1.24V -> (127 / 256) * 2.5V = 1.24V
+ Comparator.hysteresis = comparator::hyst::large; // Use a 50mV hysteresis
+ Comparator.output = comparator::out::enable; // Enable output on digital pin 7 (PA7)
+
+ // Initialize comparator
+ Comparator.init();
+
+ // Start comparator
+ Comparator.start();
+}
+
+void loop()
+{
+
+}
diff --git a/megaavr/libraries/Comparator/examples/Interrupt/Interrupt.ino b/megaavr/libraries/Comparator/examples/Interrupt/Interrupt.ino
new file mode 100644
index 0000000..2677f2d
--- /dev/null
+++ b/megaavr/libraries/Comparator/examples/Interrupt/Interrupt.ino
@@ -0,0 +1,57 @@
+/***********************************************************************|
+| megaAVR analog comparator library |
+| |
+| Interrupt.ino |
+| |
+| A library for interfacing with the megaAVR analog comparator. |
+| Developed in 2019 by MCUdude |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use an internal reference voltage instead of an |
+| external one on the negative pin. This eliminates the need for an |
+| external voltage divider to generate a reference. Note that the |
+| internal reference requires a stable voltage to function properly. |
+| Instead of using a physical output pin we're instead triggering an |
+| interrupt that will run a user defined function. |
+| |
+| This is the formula for the generated voltage: |
+| Vdacref = (DACREF / 256) * Vref |
+| |
+| See Microchip's application note TB3211 for more information. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Configure serial port
+ Serial2.begin(9600);
+
+ // Configure relevant comparator parameters
+ Comparator.input_p = comparator::in_p::in0; // Use positive input 0 (PD2)
+ Comparator.input_n = comparator::in_n::dacref; // Connect the negative pin to the DACREF voltage
+ Comparator.reference = comparator::ref::vref_2v5; // Set the DACREF voltage to 2.5V
+ Comparator.dacref = 255; // Gives us 2.5V -> (255 / 256) * 2.5V = 2.5V
+ Comparator.hysteresis = comparator::hyst::large; // Use a 50mV hysteresis
+ Comparator.output = comparator::out::disable; // Use interrupt trigger instead of output pin
+
+ // Initialize comparator
+ Comparator.init();
+
+ // Set interrupt (supports RISING, FALLING and CHANGE)
+ Comparator.attachInterrupt(interruptFunction, RISING);
+
+ // Start comparator
+ Comparator.start();
+}
+
+void loop()
+{
+
+}
+
+// This function runs when an interrupt occurs
+void interruptFunction()
+{
+ Serial2.println("Output of analog comparator went high!");
+}
diff --git a/megaavr/libraries/Comparator/examples/Simple_comparator/Simple_comparator.ino b/megaavr/libraries/Comparator/examples/Simple_comparator/Simple_comparator.ino
new file mode 100644
index 0000000..29278eb
--- /dev/null
+++ b/megaavr/libraries/Comparator/examples/Simple_comparator/Simple_comparator.ino
@@ -0,0 +1,36 @@
+/***********************************************************************|
+| megaAVR analog comparator library |
+| |
+| Simple_comparator.ino |
+| |
+| A library for interfacing with the megaAVR analog comparator. |
+| Developed in 2019 by MCUdude |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use the negative and positive input 0 of the |
+| comparator. The output goes high if the positive input is higher than |
+| the negative input, and low otherwise. |
+| |
+| See Microchip's application note TB3211 for more information. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Configure relevant comparator parameters
+ Comparator.input_p = comparator::in_p::in0; // Use positive input 0 (PD2)
+ Comparator.input_n = comparator::in_n::in0; // Use negative input 0 (PD3)
+ Comparator.output = comparator::out::enable; // Enable output on digital pin 7 (PA7)
+
+ // Initialize comparator
+ Comparator.init();
+
+ // Start comparator
+ Comparator.start();
+}
+
+void loop()
+{
+
+}
diff --git a/megaavr/libraries/Comparator/keywords.txt b/megaavr/libraries/Comparator/keywords.txt
new file mode 100644
index 0000000..9f324e2
--- /dev/null
+++ b/megaavr/libraries/Comparator/keywords.txt
@@ -0,0 +1,38 @@
+#######################################
+# Syntax Coloring Map For Wire
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+start KEYWORD2
+stop KEYWORD2
+init KEYWORD2
+attachInterrupt KEYWORD2
+detachInterrupt KEYWORD2
+
+#######################################
+# Instances (KEYWORD2)
+#######################################
+
+Comparator KEYWORD2
+Comparator0 KEYWORD2
+Comparator1 KEYWORD2
+Comparator2 KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
+comparator LITERAL1
+out LITERAL1
+hyst LITERAL1
+in_p LITERAL1
+in_n LITERAL1
+ref LITERAL1
diff --git a/megaavr/libraries/Comparator/library.properties b/megaavr/libraries/Comparator/library.properties
new file mode 100644
index 0000000..858879d
--- /dev/null
+++ b/megaavr/libraries/Comparator/library.properties
@@ -0,0 +1,10 @@
+name=Comparator
+version=1.1.1
+author=MCUdude
+maintainer=MCUdude
+sentence=A library for interfacing with the built-in analog comparator
+paragraph=
+category=Signal Input/Output
+url=https://github.com/MCUdude/MegaCoreX
+dot_a_linkage=true
+architectures=megaavr
diff --git a/megaavr/libraries/Comparator/src/Comparator.cpp b/megaavr/libraries/Comparator/src/Comparator.cpp
new file mode 100644
index 0000000..eb5326b
--- /dev/null
+++ b/megaavr/libraries/Comparator/src/Comparator.cpp
@@ -0,0 +1,68 @@
+#include "Comparator.h"
+
+AnalogComparator Comparator(0, AC0);
+
+AnalogComparator::AnalogComparator(const uint8_t comp_number, AC_t& ac) : comparator_number(comp_number), AC(ac)
+{
+}
+
+void AnalogComparator::init()
+{
+ // Set voltage reference
+ if(reference != comparator::ref::disable)
+ {
+ VREF.CTRLA = (VREF.CTRLA & ~VREF_AC0REFSEL_AVDD_gc) | reference;
+ VREF.CTRLB = VREF_AC0REFEN_bm;
+ }
+ else
+ VREF.CTRLB &= ~VREF_AC0REFEN_bm;
+
+ // Set DACREF
+ AC.DACREF = dacref;
+
+ // Set hysteresis and output pin state
+ AC.CTRLA = (AC.CTRLA & ~AC_HYSMODE_gm) | hysteresis | (output & AC_OUTEN_bm);
+
+ // Clear input pins
+ if(input_p == comparator::in_p::in0)
+ PORTD.PIN2CTRL = PORT_ISC_INPUT_DISABLE_gc;
+ else if(input_p == comparator::in_p::in1)
+ PORTD.PIN4CTRL = PORT_ISC_INPUT_DISABLE_gc;
+ else if(input_p == comparator::in_p::in2)
+ PORTD.PIN6CTRL = PORT_ISC_INPUT_DISABLE_gc;
+ else if(input_p == comparator::in_p::in3)
+ PORTD.PIN1CTRL = PORT_ISC_INPUT_DISABLE_gc;
+ if(input_n == comparator::in_n::in0)
+ PORTD.PIN3CTRL = PORT_ISC_INPUT_DISABLE_gc;
+ else if(input_n == comparator::in_n::in1)
+ PORTD.PIN5CTRL = PORT_ISC_INPUT_DISABLE_gc;
+ else if(input_n == comparator::in_n::in2)
+ PORTD.PIN7CTRL = PORT_ISC_INPUT_DISABLE_gc;
+
+ // Set positive and negative pins, invert output if defined by the user
+ AC.MUXCTRLA = (AC.MUXCTRLA & ~0x1B) | (input_p << 3) | input_n | (output & AC_INVERT_bm);
+
+ // Set output if enabled
+ if(output & AC_OUTEN_bm)
+ PORTA.DIRSET = PIN7_bm;
+ else
+ PORTA.DIRCLR = PIN7_bm;
+}
+
+void AnalogComparator::start(bool state)
+{
+ if(state)
+ AC.CTRLA |= AC_ENABLE_bm;
+ else
+ AC.CTRLA &= ~AC_ENABLE_bm;
+}
+
+void AnalogComparator::stop()
+{
+ start(false);
+}
+
+bool AnalogComparator::read()
+{
+ return !!(AC0.STATUS & AC_STATE_bm);
+}
diff --git a/megaavr/libraries/Comparator/src/Comparator.h b/megaavr/libraries/Comparator/src/Comparator.h
new file mode 100644
index 0000000..699eec6
--- /dev/null
+++ b/megaavr/libraries/Comparator/src/Comparator.h
@@ -0,0 +1,115 @@
+#ifndef COMPARATOR_h
+#define COMPARATOR_h
+
+#include
+
+namespace comparator
+{
+ namespace out
+ {
+ enum output_t : uint8_t
+ {
+ disable = 0x00,
+ disable_invert = 0x80,
+ enable = 0x40,
+ invert = 0xC0,
+ enable_invert = 0xC0,
+ };
+ };
+
+ namespace hyst
+ {
+ enum hysteresis_t : uint8_t
+ {
+ disable = 0x00, // No hysteresis
+ small = 0x02, // 10 mV
+ medium = 0x04, // 25 mV
+ large = 0x06, // 50 mV
+ };
+ };
+
+ namespace in_p
+ {
+ enum inputP_t : uint8_t
+ {
+ in0 = 0x00,
+ in1 = 0x01,
+ in2 = 0x02,
+ in3 = 0x03,
+ };
+ };
+
+ namespace in_n
+ {
+ enum inputN_t : uint8_t
+ {
+ in0 = 0x00,
+ in1 = 0x01,
+ in2 = 0x02,
+ dacref = 0x03,
+ };
+ };
+
+ namespace ref
+ {
+ enum reference_t : uint8_t
+ {
+ vref_0v55 = 0x00, // 0.55V
+ vref_1v1 = 0x01, // 1.1V
+ vref_1v5 = 0x04, // 1.5V
+ vref_2v5 = 0x02, // 2.5V
+ vref_4v3 = 0x03, // 4.3V
+ vref_avcc = 0x07, // Vcc
+ disable = 0x08,
+ };
+ };
+};
+
+// Legacy definitions
+namespace out { using namespace comparator::out; };
+namespace hyst { using namespace comparator::hyst; };
+namespace in_p { using namespace comparator::in_p; };
+namespace in_n { using namespace comparator::in_n; };
+namespace ref { using namespace comparator::ref; };
+
+class AnalogComparator
+{
+ public:
+ AnalogComparator(const uint8_t comparator_number, AC_t& ac);
+ void init();
+ void start(bool state = true);
+ void stop();
+ bool read();
+ void attachInterrupt(voidFuncPtr callback, uint8_t mode);
+ void detachInterrupt();
+
+ comparator::out::output_t output = comparator::out::disable;
+ comparator::hyst::hysteresis_t hysteresis = comparator::hyst::disable;
+ comparator::in_p::inputP_t input_p = comparator::in_p::in0;
+ comparator::in_n::inputN_t input_n = comparator::in_n::in0;
+ comparator::ref::reference_t reference = comparator::ref::disable;
+ uint8_t dacref = 0xff;
+
+ private:
+ const uint8_t comparator_number;
+ AC_t& AC;
+ bool enable = false;
+};
+
+// Array for storing ISR function pointers
+#if defined(AC2_AC_vect)
+static volatile voidFuncPtr intFuncAC[3];
+#elif defined(AC1_AC_vect)
+static volatile voidFuncPtr intFuncAC[2];
+#elif defined(AC0_AC_vect)
+static volatile voidFuncPtr intFuncAC[1];
+#else
+#error target does not have an analog comparator!
+#endif
+
+#if defined(AC0_AC_vect)
+extern AnalogComparator Comparator0;
+#define Comparator Comparator0
+#endif
+
+#endif
diff --git a/megaavr/libraries/Comparator/src/Comparator_ISR.cpp b/megaavr/libraries/Comparator/src/Comparator_ISR.cpp
new file mode 100644
index 0000000..21af638
--- /dev/null
+++ b/megaavr/libraries/Comparator/src/Comparator_ISR.cpp
@@ -0,0 +1,71 @@
+// This file will be optimized away if attachInterrupt or detachInterrupt isn't used in
+// user program, thanks to dot_a_linkage set in library.properties
+
+#include "Comparator.h"
+
+void AnalogComparator::attachInterrupt(void (*userFunc)(void), uint8_t mode)
+{
+ AC_INTMODE_t intmode;
+ switch (mode)
+ {
+ // Set RISING, FALLING or CHANGE interrupt trigger for the comparator output
+ case RISING:
+ intmode = AC_INTMODE_POSEDGE_gc;
+ break;
+ case FALLING:
+ intmode = AC_INTMODE_NEGEDGE_gc;
+ break;
+ case CHANGE:
+ intmode = AC_INTMODE_BOTHEDGE_gc;
+ break;
+ default:
+ // Only RISING, FALLING and CHANGE is supported
+ return;
+ }
+ AC.CTRLA = (AC.CTRLA & ~AC_INTMODE_POSEDGE_gc) | intmode;
+
+ // Store function pointer
+ intFuncAC[comparator_number] = userFunc;
+
+ // Enable interrupt
+ AC.INTCTRL |= AC_CMP_bm;
+}
+
+void AnalogComparator::detachInterrupt()
+{
+ // Disable interrupt
+ AC.INTCTRL &= ~AC_CMP_bm;
+}
+
+#ifdef AC0_AC_vect
+ISR(AC0_AC_vect)
+{
+ // Run user function
+ intFuncAC[0]();
+
+ // Clear flag
+ AC0.STATUS = AC_CMP_bm;
+}
+#endif
+
+#ifdef AC1_AC_vect
+ISR(AC1_AC_vect)
+{
+ // Run user function
+ intFuncAC[1]();
+
+ // Clear flag
+ AC1.STATUS = AC_CMP_bm;
+}
+#endif
+
+#ifdef AC2_AC_vect
+ISR(AC2_AC_vect)
+{
+ // Run user function
+ intFuncAC[2]();
+
+ // Clear flag
+ AC2.STATUS = AC_CMP_bm;
+}
+#endif
diff --git a/megaavr/libraries/EEPROM/README.md b/megaavr/libraries/EEPROM/README.md
index a624136..3e16839 100644
--- a/megaavr/libraries/EEPROM/README.md
+++ b/megaavr/libraries/EEPROM/README.md
@@ -1,13 +1,27 @@
-## **EEPROM Library V2.0** for Arduino
+## **EEPROM Library V2.1**
-**Written by:** _Christopher Andrews_.
+**Written by:** _Christopher Andrews_.
+
+**Modified by:** _Spence Konde_ for better megaAVR support.
### **What is the EEPROM library.**
-Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips.
+The EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found on megaAVR ATtiny and ATmega devices. It was adapted for these devices by Spence Konde for distribution as part of [megaTinyCore](https://github.com/SpenceKonde/megaTinyCore). The interface is fully compatible with the standard Arduino EEPROM.h library. EEPROM memory will retain it's stored data when the device is powered off. If the EESAVE bit in the SYSCFG0 fuse is set, it will retain it's values even if a UPDI programmer is used to issue a Chip Erase command, unless the part has been "locked" via the LOCKBIT fuse, in which case the EEPROM is always cleared.
+
+### **Additional features when used with the megaavr devices**
+
+Like all AVR microcontrollers, the megaAVR devices have the usual complement of EEPROM memory available (See the datasheet or megaTinyCore part-specific documentation for more details). In addition to the standard EEPROM, the megaavr devices also have an additional "page" of memory available in what Atmel/Microchip refers to as the "user row". When using this version of EEPROM.h (Included in megaTinyCore 1.1.9 and later), the same methods described below work in the same way to read and write the user row. The library will treat any address greater than 0xFF (255) as pointing to the user row, as no currently available megaavr devices provide more than 256b of EEPROM memory.
+
+The user row can be used like normal EEPROM. Unlike normal EEPROM, when the chip is locked (via the LOCKBIT fuse), it can be *written to* (but not read from) via UPDI. It is still erased when a Chip Erase instruction is used.
+
+### **Library limitations**
+
+As with most Arduino libraries, this library sacrifices performance and functionality in favor of ease of use. This is particularly true of the megaAVR parts - unlike "classic" AVR devices, these provide a readiliy accessible facility for programming flash and EEPROM memory a whole page at a time (see the datasheet for additional information) - this library writes all memory one byte at a time. Providing a high performance library that made use of that would require that the library br aware of the page boundaries; after consideration, it was decided that the flash and performance overhead of such a system would not nr justified in the resource-constrained environment of a TinyAVR device as this version of the library is intended for. For applications where space is at a particular premium, megaTinyCore provides a minimal eeprom libtary called TinyEEPROM ( https://github.com/SpenceKonde/megaTinyCore/extras/TinyEEPROM.md .)
+
+No facility for wear leveling is provided, other than the `update()` and `put()` methods checking that the contents have not changed before writing. Under typical usage scenarios, further wear leveling methods are unnecessary - these devices are rated for 100,000 erase-write cycles, and according to the datasheet, the hardware only erases and writes bytes which have been written to the page buffer - it deos not perform a read-modify-write cycle on the whole page when any byte within the page is written or erased. If you do determine thas wear leveling is required for your application, many libraries that do this are available from various authors. Be aware that there is a bug in eeprom_is_ready() macro provided by the included with most versions of avr-libc, which impacts many third party EEPROM-rel;ated libraries. The symptom of this issue is an error referring to NVM_STATUS; to fix it, search the library code for eeprom_is_ready(). Replace `eeprom_is_ready()` with `!(NVMCTRL.STATUS & NVMCTRL_EEBUSY_bm)` and the library should work, assuming they do not make use of direct register writes that would require hand-porting to other families of AVR.
### **How to use it**
-The EEPROM library is included in your IDE download. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch.
+The EEPROM library is provided as part of all board packages for hardware with this sort of memory - this particular version is supplied with megaTinyCore. It will be used whenver you are compiling for
```Arduino
#include
@@ -66,7 +80,7 @@ This function returns a reference to the `object` passed in. It does not need to
#### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino)
-This operator allows using the identifier `EEPROM` like an array.
+This operator allows using the identifier `EEPROM` like an array.
EEPROM cells can be read _and_ **_written_** directly using this method.
This operator returns a reference to the EEPROM cell.
@@ -113,7 +127,7 @@ unsigned char val = ref; //Read referenced cell.
#### **`EEPtr` class**
This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects.
-Just like a normal pointer type, this type can be dereferenced and repositioned using
+Just like a normal pointer type, this type can be dereferenced and repositioned using
increment/decrement operators.
```C++
@@ -128,12 +142,12 @@ ptr++; //Move to next EEPROM cell.
#### **`EEPROM.begin()`**
-This function returns an `EEPtr` pointing to the first cell in the EEPROM.
+This function returns an `EEPtr` pointing to the first cell in the EEPROM.
This is useful for STL objects, custom iteration and C++11 style ranged for loops.
#### **`EEPROM.end()`**
-This function returns an `EEPtr` pointing at the location after the last EEPROM cell.
+This function returns an `EEPtr` pointing at the location after the last EEPROM cell.
Used with `begin()` to provide custom iteration.
-**Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell.
+**Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell.
\ No newline at end of file
diff --git a/megaavr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino b/megaavr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino
index f8694da..ec30bbd 100644
--- a/megaavr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino
+++ b/megaavr/libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino
@@ -1,10 +1,10 @@
/***
- Written by Christopher Andrews.
- CRC algorithm generated by pycrc, MIT licence ( https://github.com/tpircher/pycrc ).
+ Written by Christopher Andrews.
+ CRC algorithm generated by pycrc, MIT licence ( https://github.com/tpircher/pycrc ).
- A CRC is a simple way of checking whether data has changed or become corrupted.
- This example calculates a CRC value directly on the EEPROM values.
- The purpose of this example is to highlight how the EEPROM object can be used just like an array.
+ A CRC is a simple way of checking whether data has changed or become corrupted.
+ This example calculates a CRC value directly on the EEPROM values.
+ The purpose of this example is to highlight how the EEPROM object can be used just like an array.
***/
#include
diff --git a/megaavr/libraries/EEPROM/library.properties b/megaavr/libraries/EEPROM/library.properties
index 2bd5552..4c639be 100644
--- a/megaavr/libraries/EEPROM/library.properties
+++ b/megaavr/libraries/EEPROM/library.properties
@@ -1,9 +1,9 @@
name=EEPROM
-version=2.0
+version=2.1
author=Arduino, Christopher Andrews
-maintainer=Arduino
-sentence=Enables reading and writing to the permanent board storage.
-paragraph=This library allows to read and write data in a memory type, the EEPROM, that keeps its content also when the board is powered off. The amount of EEPROM available depends on the microcontroller type.
+maintainer=MCUdude
+sentence=Enables reading and writing to EEPROM and USERROW on megaAVR parts.
+paragraph=This library allows a sketch to read and write data in a memory type, the EEPROM, that keeps its content also when the board is powered off. This version of the library also supports reading and writing the USERROW page on megaAVR parts.
category=Data Storage
url=http://www.arduino.cc/en/Reference/EEPROM
architectures=megaavr
diff --git a/megaavr/libraries/EEPROM/src/EEPROM.h b/megaavr/libraries/EEPROM/src/EEPROM.h
index a600835..7ac7b08 100644
--- a/megaavr/libraries/EEPROM/src/EEPROM.h
+++ b/megaavr/libraries/EEPROM/src/EEPROM.h
@@ -2,144 +2,158 @@
EEPROM.h - EEPROM library
Original Copyright (c) 2006 David A. Mellis. All right reserved.
New version by Christopher Andrews 2015.
-
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
-
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
-
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Expanded by Spence Konde for megaTinyCore, with several new additions
+ First, owing to recently discovered
*/
#ifndef EEPROM_h
#define EEPROM_h
-#include
-#include
#include
+#include
/***
EERef class.
-
This object references an EEPROM cell.
Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM.
This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell.
***/
-struct EERef{
-
- EERef( const int index )
- : index( index ) {}
-
- //Access/read members.
- uint8_t operator*() const { return eeprom_read_byte( (uint8_t*) index ); }
- operator uint8_t() const { return **this; }
-
- //Assignment/write members.
- EERef &operator=( const EERef &ref ) { return *this = *ref; }
- EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_t*) index, in ), *this; }
- EERef &operator +=( uint8_t in ) { return *this = **this + in; }
- EERef &operator -=( uint8_t in ) { return *this = **this - in; }
- EERef &operator *=( uint8_t in ) { return *this = **this * in; }
- EERef &operator /=( uint8_t in ) { return *this = **this / in; }
- EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; }
- EERef &operator %=( uint8_t in ) { return *this = **this % in; }
- EERef &operator &=( uint8_t in ) { return *this = **this & in; }
- EERef &operator |=( uint8_t in ) { return *this = **this | in; }
- EERef &operator <<=( uint8_t in ) { return *this = **this << in; }
- EERef &operator >>=( uint8_t in ) { return *this = **this >> in; }
-
- EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; }
-
- /** Prefix increment/decrement **/
- EERef& operator++() { return *this += 1; }
- EERef& operator--() { return *this -= 1; }
-
- /** Postfix increment/decrement **/
- uint8_t operator++ (int){
- uint8_t ret = **this;
- return ++(*this), ret;
- }
-
- uint8_t operator-- (int){
- uint8_t ret = **this;
- return --(*this), ret;
- }
-
- int index; //Index of current EEPROM cell.
+#define nvm_read_byte(idx) *(uint8_t *)((idx & 0xFF) | ((idx & 0x100) ? USER_SIGNATURES_START : EEPROM_START))
+
+static void nvm_write_byte(uint16_t idx, uint8_t dat)
+{
+ *(uint8_t *)((idx & 0xFF) | ((idx & 0x100) ? USER_SIGNATURES_START : EEPROM_START)) = dat;
+ uint8_t oldSREG = SREG;
+ cli();
+ _PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);
+ SREG = oldSREG;
+ while (NVMCTRL.STATUS & NVMCTRL_EEBUSY_bm)
+ ;
+}
+
+struct EERef
+{
+ EERef(const int index)
+ : index(index) {}
+
+ //Access/read members.
+ uint8_t operator*() const { return nvm_read_byte(index); }
+ operator uint8_t() const { return **this; }
+
+ //Assignment/write members.
+ EERef &operator=(const EERef &ref) { return *this = *ref; }
+ EERef &operator=(uint8_t in) { return nvm_write_byte(index, in), *this; }
+ EERef &operator+=(uint8_t in) { return *this = **this + in; }
+ EERef &operator-=(uint8_t in) { return *this = **this - in; }
+ EERef &operator*=(uint8_t in) { return *this = **this * in; }
+ EERef &operator/=(uint8_t in) { return *this = **this / in; }
+ EERef &operator^=(uint8_t in) { return *this = **this ^ in; }
+ EERef &operator%=(uint8_t in) { return *this = **this % in; }
+ EERef &operator&=(uint8_t in) { return *this = **this & in; }
+ EERef &operator|=(uint8_t in) { return *this = **this | in; }
+ EERef &operator<<=(uint8_t in) { return *this = **this << in; }
+ EERef &operator>>=(uint8_t in) { return *this = **this >> in; }
+
+ EERef &update(uint8_t in) { return in != *this ? *this = in : *this; }
+
+ /** Prefix increment/decrement **/
+ EERef &operator++() { return *this += 1; }
+ EERef &operator--() { return *this -= 1; }
+
+ /** Postfix increment/decrement **/
+ uint8_t operator++(int)
+ {
+ uint8_t ret = **this;
+ return ++(*this), ret;
+ }
+
+ uint8_t operator--(int)
+ {
+ uint8_t ret = **this;
+ return --(*this), ret;
+ }
+
+ int index; //Index of current EEPROM cell.
};
/***
EEPtr class.
-
This object is a bidirectional pointer to EEPROM cells represented by EERef objects.
- Just like a normal pointer type, this can be dereferenced and repositioned using
+ Just like a normal pointer type, this can be dereferenced and repositioned using
increment/decrement operators.
***/
-struct EEPtr{
-
- EEPtr( const int index )
- : index( index ) {}
-
- operator int() const { return index; }
- EEPtr &operator=( int in ) { return index = in, *this; }
-
- //Iterator functionality.
- bool operator!=( const EEPtr &ptr ) { return index != ptr.index; }
- EERef operator*() { return index; }
-
- /** Prefix & Postfix increment/decrement **/
- EEPtr& operator++() { return ++index, *this; }
- EEPtr& operator--() { return --index, *this; }
- EEPtr operator++ (int) { return index++; }
- EEPtr operator-- (int) { return index--; }
-
- int index; //Index of current EEPROM cell.
+struct EEPtr
+{
+ EEPtr(const int index)
+ : index(index) {}
+
+ operator int() const { return index; }
+ EEPtr &operator=(int in) { return index = in, *this; }
+
+ //Iterator functionality.
+ bool operator!=(const EEPtr &ptr) { return index != ptr.index; }
+ EERef operator*() { return index; }
+
+ /** Prefix & Postfix increment/decrement **/
+ EEPtr &operator++() { return ++index, *this; }
+ EEPtr &operator--() { return --index, *this; }
+ EEPtr operator++(int) { return index++; }
+ EEPtr operator--(int) { return index--; }
+
+ int index; //Index of current EEPROM cell.
};
/***
EEPROMClass class.
-
This object represents the entire EEPROM space.
It wraps the functionality of EEPtr and EERef into a basic interface.
This class is also 100% backwards compatible with earlier Arduino core releases.
***/
-struct EEPROMClass{
-
- //Basic user access methods.
- EERef operator[]( const int idx ) { return idx; }
- uint8_t read( int idx ) { return EERef( idx ); }
- void write( int idx, uint8_t val ) { (EERef( idx )) = val; }
- void update( int idx, uint8_t val ) { EERef( idx ).update( val ); }
-
- //STL and C++11 iteration capability.
- EEPtr begin() { return 0x00; }
- EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
- uint16_t length() { return EEPROM_SIZE; }
-
- //Functionality to 'get' and 'put' objects to and from EEPROM.
- template< typename T > T &get( int idx, T &t ){
- EEPtr e = idx;
- uint8_t *ptr = (uint8_t*) &t;
- for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e;
- return t;
- }
-
- template< typename T > const T &put( int idx, const T &t ){
- EEPtr e = idx;
- const uint8_t *ptr = (const uint8_t*) &t;
- for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ );
- return t;
- }
+struct EEPROMClass
+{
+ //Basic user access methods.
+ EERef operator[](const int idx) { return idx; }
+ uint8_t read(int idx) { return EERef(idx); }
+ void write(int idx, uint8_t val) { (EERef(idx)) = val; }
+ void update(int idx, uint8_t val) { EERef(idx).update(val); }
+
+ //STL and C++11 iteration capability.
+ EEPtr begin() { return 0x00; }
+ EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid.
+ uint16_t length() { return EEPROM_SIZE; }
+
+ //Functionality to 'get' and 'put' objects to and from EEPROM.
+ template
+ T &get(int idx, T &t)
+ {
+ EEPtr e = idx;
+ uint8_t *ptr = (uint8_t *)&t;
+ for (int count = sizeof(T); count; --count, ++e) *ptr++ = *e;
+ return t;
+ }
+
+ template
+ const T &put(int idx, const T &t)
+ {
+ EEPtr e = idx;
+ const uint8_t *ptr = (const uint8_t *)&t;
+ for (int count = sizeof(T); count; --count, ++e) (*e).update(*ptr++);
+ return t;
+ }
};
static EEPROMClass EEPROM;
diff --git a/megaavr/libraries/Event/README.md b/megaavr/libraries/Event/README.md
new file mode 100644
index 0000000..a5a490f
--- /dev/null
+++ b/megaavr/libraries/Event/README.md
@@ -0,0 +1,449 @@
+# Event
+A library for interfacing with the built-in Event system on the megaAVR-0 series MCUs.
+Developed by [MCUdude](https://github.com/MCUdude/).
+
+**From the datasheet:**
+> The Event System (EVSYS) enables direct peripheral-to-peripheral signaling. It allows a change in one peripheral (the event generator) to trigger actions in other peripherals (the event users) through event channels, without using the CPU. It is designed to provide short and predictable response times between peripherals, allowing for autonomous peripheral control and interaction, and also for synchronized timing of actions in several peripheral modules. It is thus a powerful tool for reducing the complexity, size, and execution time of the software.
+
+
+## Overview
+The event system allows routing of signals from event "generators" (outputs on various peripherals) through an event "channel", which one or more "event users" can be connected. When an event signal coming from the generator is is "active" or "high", the users connected to the same channel as the generator will perform certain specified actions depending on the peripheral. Generators are often the sorts of things that generate an interrupt if that is enabled - but some things can generate constant level events (such as following the state of a pin).
+The event users can do a wide variety of things. The ADC can kick off a staged measurement. Type A and B timers can count them, and type B timers can measure their duration or time between them with input capture. USARTs can even use them as their RX input! This is nice and all - but what really makes the Event system reach it's potential is CCL (configurable custom logic) which can use events as inputs, in addiion to having access to several more internal sourcesof "event-like" signals - and being event generators in their own right.
+
+More information about the Event system and how it works can be found in the [Microchip Application Note AN2451](http://ww1.microchip.com/downloads/en/AppNotes/DS00002451B.pdf) and in the [megaAVR-0 family data sheet](http://ww1.microchip.com/downloads/en/DeviceDoc/megaAVR0-series-Family-Data-Sheet-DS40002015B.pdf).
+
+
+### Level vs. Pulse events
+There are two types of events - a "pulse" interrupt, which lasts for the duration of a single clock cycle (either `CLK_PER` or a relevant (slower) clock - for example, the USART XCK generator provides a pulse event which lasts one XCK period, whuich is far slower than CLK_PER), or a "level" interrupt which lasts for the duration of some condition.
+Often for a given even generator or user only one or the other makes sense. Less often, for some reason or another, you may need a level event, but all you have is a pulse event - or the other way around. A [CCL module (Logic.h)](../Logic/README.md) event between the two at the cost of the logic module and one event channel. In the case of timer WO (PWM) channels, the CCL already has level inputs.
+
+
+### Synchronization
+>Events can be either synchronous or asynchronous to the peripheral clock. Each Event System channel has two subchannels: one asynchronous and one synchronous.
+>The asynchronous subchannel is identical to the event output from the generator. If the event generator generates a signal asynchronous to the peripheral clock, the signal on the asynchronous subchannel will be asynchronous. If the event generator generates a signal synchronous to the peripheral clock, the signal on the asynchronous subchannel
+>will also be synchronous.
+>The synchronous subchannel is identical to the event output from the generator, if the event generator generates a signal synchronous to the peripheral clock. If the event generator generates a signal asynchronous to the peripheral clock, this signal is first synchronized before being routed onto the synchronous subchannel. Depending on when the event occurs, synchronization will delay the it by two to three clock cycles. The Event System automatically perform this synchronization if an asynchronous generator is selected for an event channel.
+
+The event system, under the hood, is asynchronous - it can react faster than the system clock (often a lot faster).
+The fact that it is asynchronous usually doesn't matter, but it is one of the things one should keep in mind when using these features, because every so often it does.
+
+
+## Event
+Class for interfacing with the Event system (EVSYS). Each event channel has its own object.
+Use the predefined objects `Event0`, `Event1`, `Event2`, `Event3`, `Event4`, `Event5`, `Event6` or `Event7`. Refer to static functions by using `Event::`. Additionally, there is an `Event_empty` that is returned whenever you call a method that returns an Event reference, but it can't fulfil your request.
+Note that different channels have different functionality, so make sure you use the right channel for the task.
+
+
+In short terms:
+* `event::genN::rtc_div8192`, `event::genN::rtc_div4096`, `event::genN::rtc_div2048` and `event::genN::rtc_div1024` are only available on odd numbered channels
+* `event::genN::rtc_div512`, `event::genN::rtc_div256`, `event::genN::rtc_div128` and `event::genN::rtc_div64` are only available on even numbered channels
+* PIN PA0..7 and PB0..5 can only be used as event generators on channel 0 and 1
+* PIN PC0..7 and PD0..7 can only be used as event generators on channel 2 and 3
+* PIN PE0..3 and PF0..6 can only be used as event generators on channel 4 and 5
+
+
+## get_channel_number()
+Function to get the current channel number. Useful if the channel object has been passed to a function as reference. The `Event_empty` object has channel number 255.
+
+### Declaration
+``` c++
+uint8_t get_channel_number();
+```
+
+### Usage
+``` c++
+uint8_t this_channel = Event0.get_channel_number(); // In this case, get_channel_number will return 0
+```
+
+
+## get_channel()
+Static function that returns the event object of that number. Useful if you need to get the correct Event object based on an integer number.
+
+### Declaration
+``` c++
+static Event& get_channel(uint8_t channel_number);
+```
+
+### Usage
+```c++
+// Create a reference to the object get_channel() returns, which in this case will be the Event2 object
+// myEvent can be futher used as a regular object
+Event& myEvent = Event::get_channel(2);
+
+// Simple check to compare two objects
+if(&myEvent == &Event2)
+{
+ // myEvent and Event2 is the same thing!
+}
+```
+
+
+## get_generator_channel()
+Static function that returns the object used for a particular event generator. Useful to figure out which channel or object a generator is connected to.
+Returns a reference to the `Event_empty` object if the generator is not connected to any channel.
+
+### Declaration
+``` c++
+static Event& get_generator_channel(event::gen::generator_t generator); // For all other generators (event::gen, event::gen0...gen7)
+static Event& get_generator_channel(uint8_t generator); // For Arduino pins
+```
+
+### Usage
+```c++
+// Set ccl0_out as event generator for channel 2
+Event2.set_generator(event::gen::ccl0_out);
+
+// Now we want to get the channel/object connected to the ccl0_out generator
+// Create a reference to the object get_generator_channel() returns.
+Event& myEvent = Event::get_generator_channel(event::gen::ccl0_out);
+
+// myEvent is now a reference to Event2!
+```
+
+
+## get_generator()
+Function to get the generator used for a particular channel.
+
+### Declaration
+``` c++
+uint8_t get_generator();
+```
+
+### Usage
+```c++
+uint8_t generator_used = Event0.get_generator();
+if(generator_used == event::gen::ccl0_out) {
+ Serial.println("We're using event::gen::ccl0_out as generator");
+}
+```
+
+
+## set_generator(event::gen::generator_t)
+Function to connect an event generator to a channel. Note that we use the prefix event::genN:: (where N is the channel number) when referring to generators unique to this particular channel. we use event::gen:: when referring to generators available on all generators.
+
+### Declaration
+``` c++
+void set_generator(event::gen::generator_t generator);
+void set_generator(event::gen0::generator_t generator);
+//...
+void set_generator(event::gen7::generator_t generator);
+```
+
+### Usage
+```c++
+Event0.set_generator(event::gen::ccl0_out); // Use the output of logic block 0 (CCL0) as an event generator for Event0
+Event2.set_generator(event::gen2::pin_pc0); // Use pin PC0 as an event generator for Event2
+```
+
+### Generator table
+Below is a table with all possible generators for each channel.
+
+| All event channels | Event0 | Event1 | Event2 | Event3 | Event4 | Event5 | Event6 | Event7 |
+|-----------------------------|------------------------------------------------------------|------------------------------------------------------------|------------------------------------------------------------|------------------------------------------------------------|-------------------------------------------------------------|-------------------------------------------------------------|----------------------------|---------------------------|
+| `event::gen::disable` | `event::gen0::disable` | `event::gen1::disable` | `event::gen2::disable` | `event::gen3::disable` | `event::gen4::disable` | `event::gen5::disable` | `event::gen6::disable` | `event::gen7::disable` |
+| `event::gen::updi_synch` | `event::gen0::rtc_div8192` | `event::gen1::rtc_div512` | `event::gen2::rtc_div8192` | `event::gen3::rtc_div512` | `event::gen4::rtc_div8192` | `event::gen5::rtc_div512` | `event::gen6::rtc_div8192` | `event::gen7::rtc_div512` |
+| `event::gen::rtc_ovf` | `event::gen0::rtc_div4096` | `event::gen1::rtc_div256` | `event::gen2::rtc_div4096` | `event::gen3::rtc_div256` | `event::gen4::rtc_div4096` | `event::gen5::rtc_div256` | `event::gen6::rtc_div4096` | `event::gen7::rtc_div256` |
+| `event::gen::rtc_cmp` | `event::gen0::rtc_div2048` | `event::gen1::rtc_div128` | `event::gen2::rtc_div2048` | `event::gen3::rtc_div128` | `event::gen4::rtc_div2048` | `event::gen5::rtc_div128` | `event::gen6::rtc_div2048` | `event::gen7::rtc_div128` |
+| `event::gen::ccl0_out` | `event::gen0::rtc_div1024` | `event::gen1::rtc_div64` | `event::gen2::rtc_div1024` | `event::gen3::rtc_div64` | `event::gen4::rtc_div1024` | `event::gen5::rtc_div64` | `event::gen6::rtc_div1024` | `event::gen7::rtc_div64` |
+| `event::gen::ccl1_out` | `event::gen0::pin_pa0` | `event::gen1::pin_pa0` | `event::gen2::pin_pc0` | `event::gen3::pin_pc0` | `event::gen4::pin_pe0`
(Only available on ATmegaX809) | `event::gen5::pin_pe0`
(Only available on ATmegaX809) | | |
+| `event::gen::ccl2_out` | `event::gen0::pin_pa1` | `event::gen1::pin_pa1` | `event::gen2::pin_pc1` | `event::gen3::pin_pc1` | `event::gen4::pin_pe1`
(Only available on ATmegaX809) | `event::gen5::pin_pe1`
(Only available on ATmegaX809) | | |
+| `event::gen::ccl3_out` | `event::gen0::pin_pa2` | `event::gen1::pin_pa2` | `event::gen2::pin_pc2` | `event::gen3::pin_pc2` | `event::gen4::pin_pe2`
(Only available on ATmegaX809) | `event::gen5::pin_pe2`
(Only available on ATmegaX809) | | |
+| `event::gen::ac0_out` | `event::gen0::pin_pa3` | `event::gen1::pin_pa3` | `event::gen2::pin_pc3` | `event::gen3::pin_pc3` | `event::gen4::pin_pe3`
(Only available on ATmegaX809) | `event::gen5::pin_pe3`
(Only available on ATmegaX809) | | |
+| `event::gen::adc0_ready` | `event::gen0::pin_pa4` | `event::gen1::pin_pa4` | `event::gen2::pin_pc4`
(Only available on ATmegaX809) | `event::gen3::pin_pc4`
(Only available on ATmegaX809) | | | | |
+| `event::gen::usart0_xck` | `event::gen0::pin_pa5` | `event::gen1::pin_pa5` | `event::gen2::pin_pc5`
(Only available on ATmegaX809) | `event::gen3::pin_pc5`
(Only available on ATmegaX809) | | | | |
+| `event::gen::usart1_xck` | `event::gen0::pin_pa6` | `event::gen1::pin_pa6` | `event::gen2::pin_pc6`
(Only available on ATmegaX809) | `event::gen3::pin_pc6`
(Only available on ATmegaX809) | | | | |
+| `event::gen::usart2_xck` | `event::gen0::pin_pa7` | `event::gen1::pin_pa7` | `event::gen2::pin_pc7`
(Only available on ATmegaX809) | `event::gen3::pin_pc7`
(Only available on ATmegaX809) | | | | |
+| `event::gen::usart3_xck` | `event::gen0::pin_pb0`
(Only available on ATmegaX809) | `event::gen1::pin_pb0`
(Only available on ATmegaX809) | `event::gen2::pin_pd0` | `event::gen3::pin_pd0` | `event::gen4::pin_pf0` | `event::gen5::pin_pf0` | | |
+| `event::gen::spi0_sck` | `event::gen0::pin_pb1`
(Only available on ATmegaX809) | `event::gen1::pin_pb1`
(Only available on ATmegaX809) | `event::gen2::pin_pd1` | `event::gen3::pin_pd1` | `event::gen4::pin_pf1` | `event::gen5::pin_pf1` | | |
+| `event::gen::tca0_ovf_lunf` | `event::gen0::pin_pb2`
(Only available on ATmegaX809) | `event::gen1::pin_pb2`
(Only available on ATmegaX809) | `event::gen2::pin_pd2` | `event::gen3::pin_pd2` | `event::gen4::pin_pf2`
(Not available on 28-pin parts) | `event::gen5::pin_pf2`
(Not available on 28-pin parts) | | |
+| `event::gen::tca0_hunf` | `event::gen0::pin_pb3`
(Only available on ATmegaX809) | `event::gen1::pin_pb3`
(Only available on ATmegaX809) | `event::gen2::pin_pd3` | `event::gen3::pin_pd3` | `event::gen4::pin_pf3`
(Not available on 28-pin parts) | `event::gen5::pin_pf3`
(Not available on 28-pin parts) | | |
+| `event::gen::tca0_cmp0` | `event::gen0::pin_pb4`
(Only available on ATmegaX809) | `event::gen1::pin_pb4`
(Only available on ATmegaX809) | `event::gen2::pin_pd4` | `event::gen3::pin_pd4` | `event::gen4::pin_pf4`
(Not available on 28-pin parts) | `event::gen5::pin_pf4`
(Not available on 28-pin parts) | | |
+| `event::gen::tca0_cmp1` | `event::gen0::pin_pb5`
(Only available on ATmegaX809) | `event::gen1::pin_pb5`
(Only available on ATmegaX809) | `event::gen2::pin_pd5` | `event::gen3::pin_pd5` | `event::gen4::pin_pf5`
(Not available on 28-pin parts) | `event::gen5::pin_pf5`
(Not available on 28-pin parts) | | |
+| `event::gen::tca0_cmp2` | | | `event::gen2::pin_pd6` | `event::gen3::pin_pd6` | `event::gen4::pin_pf6` | `event::gen5::pin_pf6` | | |
+| `event::gen::tcb0_capt` | | | `event::gen2::pin_pd7` | `event::gen3::pin_pd7` | | | | |
+| `event::gen::tcb1_capt` | | | | | | | | |
+| `event::gen::tcb2_capt` | | | | | | | | |
+| `event::gen::tcb3_capt` | | | | | | | | |
+| `event::gen::tcb3_capt` | | | | | | | | |
+
+
+### assign_generator(event::gen::generator_t)
+Static function that connects an event generator to a channel. What's different compared to `set_generator()` is that this function returns a reference to the channel object the generator has been assigned to. In other words, you don't need to keep track of the exact channel number, it just assigns an available channel.
+Note that this function only accepts generators that are present on all channels (event::gen::). It will return a reference to the `Event_empty` object if no channel is available.
+
+### Declaration
+``` c++
+static Event& assign_generator(event::gen::generator_t event_generator);
+```
+
+### Usage
+```c++
+Event& myEvent = Event::assign_generator(event::gen::ac0_out); // Assign the AC0 out generator to a channel
+myEvent.start();
+```
+
+
+## set_generator(uint8_t pin_number)
+Function that sets an Arduino pin as the event generator. Note that you will have to make sure a particular pin can be used as an event generator for the selected channel/object. **If this sounds like a hassle, use [assign_generator_pin()](#assign_generator_pin) instead.**
+
+### Declaration
+``` c++
+void set_generator(uint8_t pin_number);
+```
+
+### Usage
+```c++
+Event0.set_generator(PIN_PA0); // Will work. PA0 can be used as an event generator for channel 0
+Event1.set_generator(PIN_PC3); // WILL NOT WORK! PORTC cannot be used as an event generator for channel 1
+```
+
+
+## assign_generator_pin()
+Static function that sets an Arduino pin as the event generator. Unlike set_generator(uint8_t pin_number), this function will return the object the generator has been assigned to. It will always try to use the lowest possible channel number as possible, and will return a reference to the object `Event_empty` (generator number 255) if the pin can't be assigned to a channel.
+
+### Declaration
+``` c++
+static Event& assign_generator_pin(uint8_t pin_number);
+```
+
+### Usage
+```c++
+// We're using PIN_PE2 as event generator, and the library finds a suited object
+Event& myEvent = Event::assign_generator_pin(PIN_PE2);
+
+// The myEvent object can be used directly
+myEvent.start();
+```
+
+
+## get_user_channel_number()
+Static function to get what event channel a user is connected to. Returns -1 if not connected to any channel.
+Note that we use `event::user::` as prefix when we refer to event users. Since this is a static function you don't have to specify an object to determine what channel the user is connected to. An event channel, and hence an event generator, can have as many event users are you want - but an event user can only have one event generator.
+You cannot get a list or count of all users connected to a generator except by iterating over the list.
+
+### Declaration
+``` c++
+static int8_t get_user_channel_number(event::user::user_t event_user);
+```
+
+### Usage
+```c++
+int8_t connected_to = Event::get_user_channel_number(event::user::ccl0_event_a); // Returns the channel number ccl0_event_a is connected to
+```
+
+
+## get_user_channel()
+Static function that returns the Event channel object a particular user is connected to. unlike get_user_channel_number()`, this returns a reference to an Event object, and returns a referece to the `Event_empty` object if not connected to any event channel.
+
+### Declaration
+``` c++
+static Event& get_user_channel(event::user::user_t event_user);
+```
+
+### Usage
+```c++
+Event& myEvent = Event::get_user_channel(event::user::ccl0_event_a);
+```
+
+
+## set_user()
+Function to connect an event user to an event generator. Note that a generator can have multiple users.
+
+### Declaration
+``` c++
+void set_user(event::user::user_t event_user);
+```
+
+### Usage
+```c++
+Event0.set_generator(event::gen0::pin_pa0); // Set pin PA0` as event generator for Event0
+Event0.set_user(event::user::evoutc); // Set EVOUTC (pin PC2) as event user
+Event0.set_user(event::user::evoutd); // Set evoutD (pin PD2) as event user
+```
+
+### User table
+Below is a table with all possible event users.
+Note that `evoutN_pin_pN7` is the same as `evoutN_pin_pN2` but where the pin is swapped from 2 to 7. This means that for instance, `evouta_pin_pa2` can't be used in combination with `evouta_pin_pa7.`
+
+| Event users | Notes |
+|-------------------------------------------------|-----------------------------------------------------------------------|
+| `event::user::ccl0_event_a` | |
+| `event::user::ccl0_event_b` | |
+| `event::user::ccl1_event_a` | |
+| `event::user::ccl1_event_b` | |
+| `event::user::ccl2_event_a` | |
+| `event::user::ccl2_event_b` | |
+| `event::user::ccl3_event_a` | |
+| `event::user::ccl3_event_b` | |
+| `event::user::adc0_start` | |
+| `event::user::evouta_pin_pa2` | |
+| `event::user::evouta_pin_pa7` | Pin swapped variant of `evouta_pin_pa2` |
+| `event::user::evoutb_pin_pb2` | Only available on ATmegaX809 |
+| `event::user::evoutc_pin_pc2` | |
+| `event::user::evoutc_pin_pc7` | Pin swapped variant of `evoutc_pin_pc2`. Only available on ATmegaX809 |
+| `event::user::evoutd_pin_pd2` | |
+| `event::user::evoutd_pin_pd7` | Pin swapped variant of `evoutd_pin_pd2` |
+| `event::user::evoute_pin_pe2` | Only available on ATmegaX809 |
+| `event::user::evoutf_pin_pf2` | Not available on 28-pin parts |
+| `event::user::usart0_irda` | |
+| `event::user::usart1_irda` | |
+| `event::user::usart2_irda` | |
+| `event::user::usart3_irda` | |
+| `event::user::tca0` or `event::user::tca0_capt` | |
+| `event::user::tcb0` or `event::user::tcb0_capt` | |
+| `event::user::tcb1` or `event::user::tcb1_capt` | |
+| `event::user::tcb2` or `event::user::tcb2_capt` | |
+| `event::user::tcb3` or `event::user::tcb3_capt` | |
+
+
+## set_user_pin(uint8_t pin_number)
+Function to set an Arduino pin as an event user. Note that only some pins can be used for this. See table below for more details
+
+### Declaration
+``` c++
+int8_t set_user_pin(uint8_t pin_number);
+```
+
+### Usage
+```c++
+Event0.set_user_pin(PIN_PA2);
+```
+
+### Arduino pin table
+| Event pin users | Notes |
+|-----------------|----------------------------------------------------------------------------------------------------------|
+| PIN_PA2 | |
+| PIN_PA7 | Pin swapped variant of PIN_PA2. Cannot be used in combination with PIN_PA2 |
+| PIN_PB2 | Only available on ATmegaX809 |
+| PIN_PC2 | |
+| PIN_PC7 | Pin swapped variant of PIN_PC2. Cannot be used in combination with PIN_PC2. Only available on ATmegaX809 |
+| PIN_PD2 | |
+| PIN_PD7 | Pin swapped variant of PIN_PD2. Cannot be used in combination with PIN_PD2 |
+| PIN_PE2 | Only available on ATmegaX809 |
+| PIN_PF2 | Not available on 28-pin parts |
+
+
+## clear_user()
+Function to detach a user from a channel. Note that you don't need to know what channel to detach from, simply use `Event::clear_user()`.
+
+### Declaration
+``` c++
+static void clear_user(event::user::user_t event_user);
+```
+
+### Usage
+```c++
+Event::clear_user(event::user::evouta); // Remove the event::user::evouta from whatever event channel it is connected to
+```
+
+
+## soft_event()
+Creates a single software event - users connected to that channel will react to it in the same way as they would to one caused by the generator the channel is connected to.
+Great if you have to force trigger something. Note that a software event only lasts a single system clock cycle, so it's rather fast!
+The software events will invert the channel, and so will trigger something regardless of whether it needs a the event channel to go high or low.
+
+### Declaration
+``` c++
+void soft_event();
+```
+
+### Usage
+```c++
+Event0.soft_event(); // Create a single software event on Event0
+```
+
+
+### long_soft_event()
+`soft_event()` is only one system clock long, and might be difficult to catch in a real-life application. This function does the same thing as `soft_event()` but has a programmable interval for how long the soft event will last.
+
+The event lengths that are available are 2, 4, 6, 10 and 16 system clocks. (Any number less than 4 will give 2 clock-long pulse, only 4 will give a 4 clock long one. Anything between 4 and 10 will give 6, exactly 10 will give 10, and anything larger will give 16).
+
+#### Usage
+```c++
+Event0.long_soft_event(4); // Will invert the state of the event channel for 4 system clock cycles (200ns at 20 MHz)
+Event0.long_soft_event(10); // Will invert the state of the event channel for 10 system clock cycles (500ns at 20 MHz)
+
+```
+Don't forget that this is an invert, not a "high" or "low". It should be entirely possible for the event that normally drives it to occur resulting in the state changing during that pulse, depending on it's configuration. Note also that the overhead of long_soft_event is typically several times the length of the pulse due to calculating the bitmask to write; it's longer with higher numbered channels.
+
+
+## start()
+Starts an event generator channel by writing the generator selected by the `set_generator()` function.
+
+### Declaration
+``` c++
+void start(bool state = true);
+```
+
+### Usage
+```c++
+Event0.start(); // Starts the Event0 generator channel
+```
+
+
+## stop()
+Stops an event generator channel. The `Eventn` object retains memory of what generator it was previously set to.
+
+### Declaration
+``` c++
+void stop();
+```
+
+### Usage
+```c++
+Event0.stop(); // Stops the Event0 generator channel
+```
+
+
+## gen_from_peripheral() and user_from_peripheral()
+These two static functions allow you to pass a reference to a peripheral module, and get back the generator or user associated with it. In this context the "Peripheral Modules" are the structs containing the registers, defined in the io headers; for example `TCB0` or `USART1` or `CCL`.
+
+This is most useful if you are writing portable (library) code that uses the Event library to interact with the event system. Say you made a library that lets users make one-shot pulses with timerB. You use the Event library to handle that part. You would of course need to know which timer to use - the natural way would be to ask the user to pass a reference or pointer.
+But then what? The fact that you've got the pointer to something which, as it happens, is TCB0 (which itself is annoying to determine from an unknown pointer)... though even KNOWING THAT, you're not able to use it with the event library, since it needs event::user::tcb0 (or event::user::tcb0_capt). As the function names imply, one gives generators, the other gives users. They take 2 arguments, the first being a pointer to a peripheral struct.
+The second, defaulting to 0, is the "type" of generator or user. Some peripherals have more than one event input or output. These are ordered in the same order as they are in the tables here and in the datasheet listings.
+
+### Usage
+```c
+// Here we see a typical use case - you get the generator, and immediately ask Event to assign a channel to it and give that to you. After getting it, you test to make sure it's not Event_empty, which indicates that either gen_from_peripheral failed, or assign_generator was out of event channels. Either way that's probably the user's fault, so you decide to return an error code.
+uint8_t init(TCB_t* some_timer, /*and more arguments, most likely */)
+{
+ &Event_TCBnCapt = Event::assign_generator(Event::gen_from_peripheral(some_timer, 0));
+ if (_TCBnCapt.get_channel_number() == 255)
+ return MY_ERROR_INVALID_TIMER_OR_NO_FREE_EVENT;
+ doMoreCoolStuff();
+}
+```
+
+Shown below, generators/user per instance (second argument should be less than this; zero-indexed), and the number of instances (for reference)
+
+| Peripheral | mega0 |
+|------------|----------|
+| TCAn | 5 / 1 x1 |
+| TCBn | 1/1 x3-4 |
+| CCL * | 4 / 8 |
+| ACn | 1 / 0 x1 |
+| USARTn | !/1 x3-4 |
+
+`*` - There is only one CCL peripheral, with multiple logic blocks. Each logic block has 1 event generator and 2 event users. If using the logic library, get the Logic instance number. The output generator is that number. The input is twice that number, and twice that number + 1.
+`!` - These parts do have an option, but we didn't bother to implement it because it isn't particularly useful. But the Event RX mode combined with the TX input to the CCL permit arbitrary remapping of RX and very flexible remapping of TX.
+
+And what they are:
+
+| Peripheral | TCAn | TCBn | CCL* | ACn | USARTn |
+|------------|----------|------|---------|-----|---------|
+| gen 0 | OVF/LUNF | CAPT | LUT0OUT | OUT | ! |
+| gen 1 | HUNF | | LUT1OUT | | |
+| gen 2 | CMP0 | | LUT2OUT | | |
+| gen 3 | CMP1 | | LUT3OUT | | |
+| gen 4 | CMP2 | | ETC. | | |
+| user 0 | EVACTA | CAPT | LUT0EVA | - | EVENTRX |
+| user 1 | | | LUT0EVB | | |
+| user 2 | | | LUT1EVA | | |
+| user 3 | | | LUT1EVB | | |
+| user 4 | | | ETC. | | |
+
+`*` - Since there's only one CCL, the pointer (or rather, its type) is just used to select which implementation is used. But this does mean that the CCL can have an insane number of options. But that's fine, because there are plenty of numbers between 0 and 255.
+`!` - These parts do have an option, but we didn't bother to implement it because it isn't particularly useful. But the Event RX mode combined with the TX input to the CCL permit arbitrary remapping of RX and very flexible remapping of TX!
+
+
+Asking for a generator that doesn't exist will return 0 (disabled); be sure to check for this in some way. Asking for a user that doesn't exist will return 255, which the library is smart enough not to accept.
diff --git a/megaavr/libraries/Event/examples/Read_event_settings/Read_event_settings.ino b/megaavr/libraries/Event/examples/Read_event_settings/Read_event_settings.ino
new file mode 100644
index 0000000..1acd561
--- /dev/null
+++ b/megaavr/libraries/Event/examples/Read_event_settings/Read_event_settings.ino
@@ -0,0 +1,68 @@
+/***********************************************************************|
+| megaAVR event system library |
+| |
+| Read_event_settings.ino |
+| |
+| A library for interfacing with the megaAVR event system. |
+| Developed in 2021 by MCUdude |
+| https://github.com/MCUdude/ |
+| |
+| In this example, we demonstrate the possibilities of reading out |
+| which event channel we're working with, which generator is used, and |
+| which channel an event user has been connected to. |
+| |
+| See Microchip's application note AN2451 for more information. |
+|***********************************************************************/
+
+#include
+
+// Function to print information about the passed event
+void print_event_info(Event& my_event)
+{
+ Serial2.printf("This is event channel no. %d\n", my_event.get_channel_number());
+ Serial2.printf("This channel uses generator no. 0x%02x, which you can find in Event.h\n", my_event.get_generator());
+}
+
+// Function to print information about the passed event user
+void print_user_info(event::user::user_t my_user)
+{
+ // Event::get_user_channel() returns -1 if the user isn't connected to any event generator
+ Serial2.printf("User 0x%02x is connected to event channel no. %d\n\n", my_user, Event::get_user_channel_number(my_user));
+}
+
+void setup()
+{
+ Serial2.begin(9600); // Initialize hardware serial port
+
+ Event1.set_generator(event::gen0::pin_pa3); // Set pin PA3 as event generator for event channel 1
+ Event2.set_generator(event::gen2::pin_pc3); // Set pin PC3 as event generator for event channel 2
+ Event& myEvent = Event::assign_generator_pin(PIN_PA2); // Set pin PA2 as event generator for an available channel
+
+ // For more information about EVOUT, see the PORTMUX section in the datasheet
+ Event1.set_user(event::user::evoutc_pin_pc2); // Set EVOUTC as event user
+ Event2.set_user(event::user::evouta_pin_pa2); // Set EVOUTA as event user
+ myEvent.set_user_pin(PIN_PD2); // Set pin PD2 (EVOUTD) as event user
+
+ // Start event channels
+ Event1.start();
+ Event2.start();
+ myEvent.start();
+}
+
+void loop()
+{
+ // Print info about Event4 and its event user
+ print_event_info(Event1);
+ print_user_info(event::user::evoutc_pin_pc2);
+
+ // Print info about Event5 and its event user
+ print_event_info(Event2);
+ print_user_info(event::user::evouta_pin_pa2);
+
+ // Print info about myEvent and its user
+ Event& myEvent = Event::get_generator_channel(PIN_PA2);
+ print_event_info(myEvent);
+ print_user_info(event::user::evoutd_pin_pd2);
+
+ delay(5000);
+}
diff --git a/megaavr/libraries/Event/examples/Route_logic_pins/Route_logic_pins.ino b/megaavr/libraries/Event/examples/Route_logic_pins/Route_logic_pins.ino
new file mode 100644
index 0000000..223cd40
--- /dev/null
+++ b/megaavr/libraries/Event/examples/Route_logic_pins/Route_logic_pins.ino
@@ -0,0 +1,61 @@
+/***********************************************************************|
+| megaAVR event system library |
+| |
+| Route_logic_pins.ino |
+| |
+| A library for interfacing with the megaAVR event system. |
+| Developed in 2021 by MCUdude |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use the configurable logic peripherals on the |
+| megaAVR to create a 3-input AND gate using logic block 0, but we |
+| utilize the event system to route logic input 0 and 1 to pins PC0 and |
+| PC1 instead of the default pins. |
+| Here's how 0x80 turns out to be the correct value to create a 3-input |
+| AND gate: |
+| 3-input AND truth table: |
+| If we look at the truth table |PA2|PC1|PC0| Y | |
+| to the right, we can see that |---|---|---|---| |
+| all binary values for Y can | 0 | 0 | 0 | 0 | |
+| be represented as 10000000. | 0 | 0 | 1 | 0 | |
+| If we convert this 8-bit | 0 | 1 | 0 | 0 | |
+| binary number into hex, we | 0 | 1 | 1 | 0 | |
+| get 0x80. | 1 | 0 | 0 | 0 | |
+| | 1 | 0 | 1 | 0 | |
+| In this example the output pin, | 1 | 1 | 0 | 0 | |
+| PA3 will go high if all three | 1 | 1 | 1 | 1 | |
+| inputs are high. |
+| |
+| See Microchip's application note AN2451 for more information. |
+|***********************************************************************/
+
+#include
+#include
+
+void setup()
+{
+ // Initialize Event channel 2 and 3
+ Event2.set_generator(event::gen2::pin_pc0); // Set pin PC0 as event generator
+ Event3.set_generator(event::gen3::pin_pc1); // Set pin PC1 as event generator
+ Event2.set_user(event::user::ccl0_event_a); // Set CCL0 (Logic0) event A as user
+ Event3.set_user(event::user::ccl0_event_b); // Set CCL0 (Logic0) event B as user
+
+ // Initialize logic block 0
+ Logic0.enable = true; // Enable logic block 0
+ Logic0.input0 = logic::in::event_a; // Connect input 0 to ccl0_event_a (PC0 through Event2)
+ Logic0.input1 = logic::in::event_b; // Connect input 0 to ccl0_event_b (PC1 through Event3)
+ Logic0.input2 = logic::in::input; // Set PA2 as input
+ Logic0.output = logic::out::enable; // Enable logic block 0 output pin (PA3)
+ Logic0.truth = 0x80; // Set truth table
+ Logic0.init();
+
+ // Start event channels and the logic hardware
+ Event2.start();
+ Event3.start();
+ Logic::start();
+}
+
+void loop()
+{
+
+}
diff --git a/megaavr/libraries/Event/examples/Simple_event/Simple_event.ino b/megaavr/libraries/Event/examples/Simple_event/Simple_event.ino
new file mode 100644
index 0000000..68ec388
--- /dev/null
+++ b/megaavr/libraries/Event/examples/Simple_event/Simple_event.ino
@@ -0,0 +1,52 @@
+/***********************************************************************|
+| megaAVR event system library |
+| |
+| Simple_Event.ino |
+| |
+| A library for interfacing with the megaAVR event system. |
+| Developed in 2021 by MCUdude |
+| https://github.com/MCUdude/ |
+| |
+| In this example we look at two different ways of setting up a simple |
+| Event generator ans user. In the first example use pin PA0 as an |
+| event generator, and pin PC2 and PD2 as event users. In practice, |
+| pin PC2 and PD2 will follow PA0's state. |
+| In the other example we just provide "Arduino pins" as generator and |
+| user, and let the library take care of the rest. |
+| |
+| See Microchip's application note AN2451 for more information. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Since pin PE0 is only available on event generator channel 4 and 5, we use Event4 as our object
+ // Note that we use gen4:: to refer to functionality unique to event channel 4
+ Event0.set_generator(event::gen0::pin_pa0); // Set pin PA0 as event generator
+
+ // For more information about EVOUT, see the PORTMUX section in the datasheet
+ Event0.set_user(event::user::evoutc_pin_pc2); // Set EVOUTC as event user
+ Event0.set_user(event::user::evoutd_pin_pd2); // Set EVOUTD as event user
+
+ // Start event channel
+ Event0.start();
+
+
+
+ // A different approach is to let the library itself take care of which Event channel to use:
+
+ // Assign generator to an available channel
+ Event& myEvent = Event::assign_generator_pin(PIN_PA1);
+
+ // Connect a user, in this case an Arduino pin, to the myEvent channel
+ myEvent.set_user_pin(PIN_PA2);
+
+ // Start event channel
+ myEvent.start();
+}
+
+void loop()
+{
+
+}
diff --git a/megaavr/libraries/Event/keywords.txt b/megaavr/libraries/Event/keywords.txt
new file mode 100644
index 0000000..0a21fe2
--- /dev/null
+++ b/megaavr/libraries/Event/keywords.txt
@@ -0,0 +1,60 @@
+#######################################
+# Syntax Coloring Map For Event
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+get_channel_number KEYWORD2
+get_channel KEYWORD2
+get_generator_channel KEYWORD2
+get_generator KEYWORD2
+set_generator KEYWORD2
+assign_generator KEYWORD2
+assign_generator_pin KEYWORD2
+get_user_channel_number KEYWORD2
+get_user_channel KEYWORD2
+set_user KEYWORD2
+set_user_pin KEYWORD2
+clear_user KEYWORD2
+soft_event KEYWORD2
+gen_from_peripheral KEYWORD2
+user_from_peripheral KEYWORD2
+long_soft_event KEYWORD2
+start KEYWORD2
+stop KEYWORD2
+
+#######################################
+# Instances (KEYWORD2)
+#######################################
+
+Event KEYWORD2
+Event0 KEYWORD2
+Event1 KEYWORD2
+Event2 KEYWORD2
+Event3 KEYWORD2
+Event4 KEYWORD2
+Event5 KEYWORD2
+Event6 KEYWORD2
+Event7 KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################
+
+event LITERAL1
+gen LITERAL1
+gen0 LITERAL1
+gen1 LITERAL1
+gen2 LITERAL1
+gen3 LITERAL1
+gen4 LITERAL1
+gen5 LITERAL1
+gen6 LITERAL1
+gen7 LITERAL1
+user LITERAL1
diff --git a/megaavr/libraries/Event/library.properties b/megaavr/libraries/Event/library.properties
new file mode 100644
index 0000000..0f11f66
--- /dev/null
+++ b/megaavr/libraries/Event/library.properties
@@ -0,0 +1,9 @@
+name=Event System
+version=1.2.1
+author=MCUdude
+maintainer=MCUdude and Spence Konde
+sentence=A library for interfacing with the built-in event system
+paragraph=
+category=Signal Input/Output
+url=https://github.com/MCUdude/MegaCoreX
+architectures=megaavr
diff --git a/megaavr/libraries/Event/src/Event.cpp b/megaavr/libraries/Event/src/Event.cpp
new file mode 100644
index 0000000..577c4ba
--- /dev/null
+++ b/megaavr/libraries/Event/src/Event.cpp
@@ -0,0 +1,1180 @@
+#include "Event.h"
+
+// Pre-defined objects
+#if defined(EVSYS_CHANNEL0)
+ Event Event0(0, EVSYS_CHANNEL0);
+ Event Event_empty(255, EVSYS_CHANNEL0);
+#endif
+#if defined(EVSYS_CHANNEL1)
+ Event Event1(1, EVSYS_CHANNEL1);
+#endif
+#if defined(EVSYS_CHANNEL2)
+ Event Event2(2, EVSYS_CHANNEL2);
+#endif
+#if defined(EVSYS_CHANNEL3)
+ Event Event3(3, EVSYS_CHANNEL3);
+#endif
+#if defined(EVSYS_CHANNEL4)
+ Event Event4(4, EVSYS_CHANNEL4);
+#endif
+#if defined(EVSYS_CHANNEL5)
+ Event Event5(5, EVSYS_CHANNEL5);
+#endif
+#if defined(EVSYS_CHANNEL6)
+ Event Event6(6, EVSYS_CHANNEL6);
+#endif
+#if defined(EVSYS_CHANNEL7)
+ Event Event7(7, EVSYS_CHANNEL7);
+#endif
+#if defined(EVSYS_CHANNEL8)
+ Event Event8(8, EVSYS_CHANNEL8);
+#endif
+#if defined(EVSYS_CHANNEL9)
+ Event Event9(9, EVSYS_CHANNEL9);
+#endif
+
+
+/**
+ * @brief Construct a new Event object
+ *
+ * @param channel_num Event channel number
+ * @param channel_addr Register address to channel generator
+ */
+Event::Event(uint8_t channel_num, volatile uint8_t &channel_addr)
+ : channel_number(channel_num), channel_address(channel_addr) {
+}
+
+
+/**
+ * @brief Returns the event channel number in use
+ *
+ * @return uint8_t Event channel number
+ */
+uint8_t Event::get_channel_number() {
+ return channel_number;
+}
+
+
+/**
+ * @brief Returns the object associated with the passed channel number
+ *
+ * @param ch_number Channel number
+ * @return Event& Event object associated with the channel number.
+ * Returns the Event_empty object if invalid channel number
+ */
+Event& Event::get_channel(uint8_t ch_number) {
+ #if defined(EVSYS_CHANNEL0)
+ if(Event0.channel_number == ch_number) {
+ return Event0;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL1)
+ if(Event1.channel_number == ch_number) {
+ return Event1;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL2)
+ if(Event2.channel_number == ch_number) {
+ return Event2;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL3)
+ if(Event3.channel_number == ch_number) {
+ return Event3;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL4)
+ if(Event4.channel_number == ch_number) {
+ return Event4;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL5)
+ if(Event5.channel_number == ch_number) {
+ return Event5;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL6)
+ if(Event6.channel_number == ch_number) {
+ return Event6;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL7)
+ if(Event7.channel_number == ch_number) {
+ return Event7;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL8)
+ if(Event8.channel_number == ch_number) {
+ return Event8;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL9)
+ if(Event9.channel_number == ch_number) {
+ return Event9;
+ }
+ #endif
+
+ #if defined(EVSYS_CHANNEL0)
+ else {
+ return Event_empty;
+ }
+ #endif
+}
+
+
+/**
+ * @brief Returns the event channel object used for a particular event generator
+ *
+ * @param generator Event generator
+ * @return Event& Event channel object used with this event generator
+ */
+Event& Event::get_generator_channel(event::gen::generator_t generator) {
+ #if defined(EVSYS_CHANNEL0)
+ if(Event0.generator_type == generator) {
+ return Event0;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL1)
+ if(Event1.generator_type == generator) {
+ return Event1;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL2)
+ if(Event2.generator_type == generator) {
+ return Event2;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL3)
+ if(Event3.generator_type == generator) {
+ return Event3;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL4)
+ if(Event4.generator_type == generator) {
+ return Event4;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL5)
+ if(Event5.generator_type == generator) {
+ return Event5;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL6)
+ if(Event6.generator_type == generator) {
+ return Event6;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL7)
+ if(Event7.generator_type == generator) {
+ return Event7;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL8)
+ if(Event8.generator_type == generator) {
+ return Event8;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL9)
+ if(Event9.generator_type == generator) {
+ return Event9;
+ }
+ #endif
+
+ #if defined(EVSYS_CHANNEL0)
+ else {
+ return Event_empty;
+ }
+ #endif
+}
+
+
+/**
+ * @brief Returns the event channel object used for a particular event generator Arduino pin
+ *
+ * @param generator_pin Event generator Arduino pin number
+ * @return Event& Event channel object used with this event generator
+ */
+Event& Event::get_generator_channel(uint8_t generator_pin) {
+ uint8_t port = digitalPinToPort(generator_pin);
+ uint8_t port_pin = digitalPinToBitPosition(generator_pin);
+
+ if(port != NOT_A_PIN && port_pin != NOT_A_PIN) {
+ uint8_t gen = 0x40 | (port & 0x01) << 3 | port_pin;
+ if(port == PA || port == PB) {
+ #if defined(EVSYS_CHANNEL0)
+ if(Event0.generator_type == gen) {
+ return Event0;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL1)
+ else if(Event1.generator_type == gen) {
+ return Event1;
+ }
+ #endif
+ }
+ else if(port == PC || port == PD) {
+ #if defined(EVSYS_CHANNEL2)
+ if(Event2.generator_type == gen) {
+ return Event2;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL3)
+ else if(Event3.generator_type == gen) {
+ return Event3;
+ }
+ #endif
+ }
+ else if(port == PE || port == PF) {
+ #if defined(EVSYS_CHANNEL4)
+ if(Event4.generator_type == gen) {
+ return Event4;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL5)
+ else if(Event5.generator_type == gen) {
+ return Event5;
+ }
+ #endif
+ }
+ #if defined(Dx_64_PINS)
+ else if(port == PG) {
+ if(Event6.generator_type == gen) {
+ return Event6;
+ }
+ else if(Event7.generator_type == gen) {
+ return Event7;
+ }
+ }
+ #endif
+ }
+
+ #if defined(EVSYS_CHANNEL0)
+ return Event_empty;
+ #endif
+}
+
+
+/**
+ * @brief Returns the generator type a particular channel has
+ *
+ * @return uint8_t Generator type. Returns 0 if no generator is used
+ */
+uint8_t Event::get_generator() {
+ return generator_type;
+}
+
+
+/**
+ * @brief Sets a generator for a particular event channel
+ *
+ * @param event_generator Set generator.
+ * Use event::gen:: for functionality present on all event channels.
+ * Use genN:: for functionality present on channel N.
+ */
+void Event::set_generator(event::gen::generator_t event_generator) {
+ // Store event generator setting for use in start() and stop()
+ generator_type = (uint8_t)event_generator;
+}
+
+
+/**
+ * @brief Function that lets you use an Arduino pin as event generator.
+ * Note that you'll have to manually keep track of which event channel
+ * objects to use to make sure the passed Arduino pin is supported.
+ * A different approach is to use Event::assign_generator_pin(), which
+ * automatically picks the correct event channel for you.
+ *
+ * @param pin_number Arduino pin number to use as event generator
+ */
+void Event::set_generator(uint8_t pin_number) {
+ uint8_t port = digitalPinToPort(pin_number);
+ uint8_t port_pin = digitalPinToBitPosition(pin_number);
+
+ // Store event generator setting for use in start() and stop()
+ if(port != NOT_A_PIN && port_pin != NOT_A_PIN) {
+ generator_type = 0x40 | (port & 0x01) << 3 | port_pin;
+ }
+ else {
+ generator_type = event::gen::disable;
+ }
+}
+
+
+/**
+ * @brief Static member function that sets a port pin as event
+ * generator and returns the object it has select as event channel.
+ * It will always try to select the lowest channel number as possible.
+ *
+ * @param port Port to use as event generator
+ * @param port_pin Pin number on port to use as event generator
+ * @return Event& Event channel object used as the event channel. Returns the
+ * Event_empty object if passed Arduino pin is invalid or no event
+ * channel is available
+ */
+Event& Event::assign_generator_pin(uint8_t port, uint8_t port_pin) {
+ if(port != NOT_A_PIN && port_pin != NOT_A_PIN) {
+ #if defined(MEGACOREX) || defined(DXCORE)
+ uint8_t gen = 0x40 | (port & 0x01) << 3 | port_pin;
+ if(port == PA || port == PB) {
+ if(Event0.generator_type == event::gen::disable || Event0.generator_type == gen) {
+ Event0.generator_type = gen;
+ return Event0;
+ }
+ else if(Event1.generator_type == event::gen::disable || Event1.generator_type == gen) {
+ Event1.generator_type = gen;
+ return Event1;
+ }
+ }
+ else if(port == PC || port == PD) {
+ if(Event2.generator_type == event::gen::disable || Event2.generator_type == gen) {
+ Event2.generator_type = gen;
+ return Event2;
+ }
+ else if(Event3.generator_type == event::gen::disable || Event3.generator_type == gen) {
+ Event3.generator_type = gen;
+ return Event3;
+ }
+ }
+ else if(port == PE || port == PF) {
+ if(Event4.generator_type == event::gen::disable || Event4.generator_type == gen) {
+ Event4.generator_type = gen;
+ return Event4;
+ }
+ else if(Event5.generator_type == event::gen::disable || Event5.generator_type == gen) {
+ Event5.generator_type = gen;
+ return Event5;
+ }
+ }
+ #if defined(Dx_64_PINS)
+ else if(port == PG) {
+ if(Event6.generator_type == event::gen::disable || Event6.generator_type == gen) {
+ Event6.generator_type = gen;
+ return Event6;
+ }
+ else if(Event7.generator_type == event::gen::disable || Event7.generator_type == gen) {
+ Event7.generator_type = gen;
+ return Event7;
+ }
+ }
+ #endif
+
+ return Event_empty;
+ #elif defined(TINY_2_SERIES)
+ if(port != PC) {
+ uint8_t gen = port_pin | (port == PB ? 0x40 : 0x48);
+ if(Event0.generator_type == event::gen::disable || Event0.generator_type == gen) {
+ Event0.generator_type = gen;
+ return Event0;
+ }
+ else if(Event1.generator_type == event::gen::disable || Event1.generator_type == gen) {
+ Event1.generator_type = gen;
+ return Event1;
+ }
+ }
+ if(port != PB) {
+ uint8_t gen = port_pin | (port == PA ? 0x40 : 0x48);
+ if(Event2.generator_type == event::gen::disable || Event2.generator_type == gen) {
+ Event2.generator_type = gen;
+ return Event2;
+ }
+ else if(Event3.generator_type == event::gen::disable || Event3.generator_type == gen) {
+ Event3.generator_type = gen;
+ return Event3;
+ }
+ }
+ if(port != PA)
+ {
+ uint8_t gen = port_pin | (port == PC ? 0x40 : 0x48);
+ if(Event4.generator_type == event::gen::disable || Event4.generator_type == gen) {
+ Event4.generator_type = gen;
+ return Event4;
+ }
+ else if(Event5.generator_type == event::gen::disable || Event5.generator_type == gen) {
+ Event5.generator_type = gen;
+ return Event5;
+ }
+ }
+ return Event_empty;
+ #elif defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ uint8_t gen = port_pin + 0x0A;
+ #if !defined(__AVR_ATtinyxy2__)
+ if(port == PA) {
+ #endif
+ if(Event2.generator_type == event::gen::disable || Event2.generator_type == gen) {
+ Event2.generator_type = gen;
+ return Event2;
+ }
+ gen += 3;
+ if(Event0.generator_type == event::gen::disable || Event0.generator_type == gen) {
+ Event0.generator_type = gen;
+ return Event0;
+ }
+ #if !defined(__AVR_ATtinyxy2__)
+ }
+ #endif
+ if(port == PB) {
+ if(Event3.generator_type == event::gen::disable || Event3.generator_type == gen) {
+ Event3.generator_type = gen;
+ return Event3;
+ }
+ #if defined(TINY_1_SERIES) // No Event1 on 0-series
+ gen -= 2;
+ if(Event1.generator_type == event::gen::disable || Event1.generator_type == gen) {
+ Event1.generator_type = gen;
+ return Event1;
+ }
+ #endif
+ }
+ #if defined(PIN_PC0) // can't test if PORTx is defined - all are defined everywhere)
+ if(port == PC) {
+ #if defined(TINY_1_SERIES) // no event 4 on 0-series
+ if(Event4.generator_type == event::gen::disable || Event4.generator_type == gen) {
+ Event4.generator_type = gen;
+ return Event4;
+ }
+ #endif
+ gen -= 3;
+ if(Event0.generator_type == event::gen::disable || Event0.generator_type == gen) {
+ Event0.generator_type = gen;
+ return Event0;
+ }
+ }
+ #endif // PC-bearing parts end here
+
+ #endif // end of tiny 0/1 assign_generator_pin()
+ }
+ return Event_empty;
+}
+
+
+/**
+ * @brief Static member function that sets an Arduino pin as event
+ * generator and returns the object it has select as event channel.
+ * It will always try to select the lowest channel number as possible.
+ *
+ * @param pin_number Arduino pin number to use as event generator
+ * @return Event& Event channel object used as the event channel. Returns the
+ * Event_empty object if passed Arduino pin is invalid or no event
+ * channel is available
+ */
+Event& Event::assign_generator_pin(uint8_t pin_number) {
+ uint8_t port = digitalPinToPort(pin_number);
+ uint8_t port_pin = digitalPinToBitPosition(pin_number);
+ return Event::assign_generator_pin(port, port_pin);
+}
+
+
+/**
+ * @brief Static member function that takes a event::gen:: generator as a parameter and
+ * finds an available channel for it. Starts with the highest possible channel
+ * number, 7, and iterate down to 0
+ *
+ * @param event_generator generator to assign to an event channel
+ * @return Event& Reference to the event object the generator has been assigned to.
+ * Returns the Event_empty object if no generator has been assigned to a channel
+ */
+Event& Event::assign_generator(event::gen::generator_t event_generator) {
+ // Check if generator is already in use
+ Event& channel = Event::get_generator_channel(event_generator);
+ if(channel.get_channel_number() != 255) {
+ return channel;
+ }
+
+ else {
+ #if defined(EVSYS_CHANNEL9)
+ if(Event9.get_generator() == event::gen::disable) {
+ Event9.set_generator(event_generator);
+ return Event9;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL8)
+ if(Event8.get_generator() == event::gen::disable) {
+ Event8.set_generator(event_generator);
+ return Event8;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL7)
+ if(Event7.get_generator() == event::gen::disable) {
+ Event7.set_generator(event_generator);
+ return Event7;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL6)
+ if(Event6.get_generator() == event::gen::disable) {
+ Event6.set_generator(event_generator);
+ return Event6;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL5)
+ if(Event5.get_generator() == event::gen::disable) {
+ Event5.set_generator(event_generator);
+ return Event5;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL4)
+ if(Event4.get_generator() == event::gen::disable) {
+ Event4.set_generator(event_generator);
+ return Event4;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL3)
+ if(Event3.get_generator() == event::gen::disable) {
+ Event3.set_generator(event_generator);
+ return Event3;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL2)
+ if(Event2.get_generator() == event::gen::disable) {
+ Event2.set_generator(event_generator);
+ return Event2;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL1)
+ if(Event1.get_generator() == event::gen::disable) {
+ Event1.set_generator(event_generator);
+ return Event1;
+ }
+ else
+ #endif
+ #if defined(EVSYS_CHANNEL0)
+ if(Event0.get_generator() == event::gen::disable) {
+ Event0.set_generator(event_generator);
+ return Event0;
+ }
+ else
+ #endif
+ return channel; // if we're on this branch, we know chan is Event_empty
+ }
+}
+
+
+/**
+ * @brief Returns the Event channel number a particular user is connected to
+ *
+ * @param event_user The event user to check
+ * @return int8_t Event channel number.
+ * Returns -1 if not connected to any event channel
+ */
+int8_t Event::get_user_channel_number(event::user::user_t event_user) {
+ // Figure out what user register to read from to based on the passed parameter
+ volatile uint8_t *user_register = &EVSYS_USERCCLLUT0A + (volatile uint8_t&)event_user;
+
+ // Return which channel the user is connected to
+ return *user_register - 1;
+}
+
+
+/**
+ * @brief Returns the Event channel object a particular user is connected to
+ *
+ * @param event_user The event user to check
+ * @return Event& Event channel object. Returns the Event_empty object if the
+ * user is not connected to any event channel
+ */
+Event& Event::get_user_channel(event::user::user_t event_user) {
+ int8_t ch_number = get_user_channel_number(event_user);
+
+ #if defined(EVSYS_CHANNEL0)
+ if(Event0.channel_number == ch_number) {
+ return Event0;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL1)
+ if(Event1.channel_number == ch_number) {
+ return Event1;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL2)
+ if(Event2.channel_number == ch_number) {
+ return Event2;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL3)
+ if(Event3.channel_number == ch_number) {
+ return Event3;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL4)
+ if(Event4.channel_number == ch_number) {
+ return Event4;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL5)
+ if(Event5.channel_number == ch_number) {
+ return Event5;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL6)
+ if(Event6.channel_number == ch_number) {
+ return Event6;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL7)
+ if(Event7.channel_number == ch_number) {
+ return Event7;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL8)
+ if(Event8.channel_number == ch_number) {
+ return Event8;
+ }
+ #endif
+ #if defined(EVSYS_CHANNEL9)
+ if(Event9.channel_number == ch_number) {
+ return Event9;
+ }
+ #endif
+
+ #if defined(EVSYS_CHANNEL0)
+ else {
+ return Event_empty;
+ }
+ #endif
+}
+
+
+/**
+ * @brief Sets a user for a particular event channel
+ *
+ * @param event_user The event user to connect to a particular channel
+ */
+void Event::set_user(event::user::user_t event_user) {
+ // Figure out what user register to write to based on the passed parameter
+ uint8_t event_user_mask = event_user & 0x7F;
+
+ #if defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ volatile uint8_t *user_register = &EVSYS_ASYNCUSER0 + (volatile uint8_t&)event_user_mask;
+ #else
+ volatile uint8_t *user_register = &EVSYS_USERCCLLUT0A + (volatile uint8_t&)event_user_mask;
+ #endif
+
+ // Connect user to the channel we're working with
+ *user_register = channel_number + 1;
+
+ // Set PORTMUX pin swap for EVOUT if selected as channel generator
+ #if defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ if(event_user >= 0x08 && event_user <= 0x0A) {
+ PORTMUX.CTRLA |= (1 << (event_user - 0x08));
+ }
+ #else
+ if(event_user & 0x80) {
+ #if defined(MEGACOREX)
+ PORTMUX_EVSYSROUTEA |= (1 << ((event_user & 0x7F) - 0x09));
+ #elif defined(__AVR_DA__)
+ PORTMUX_EVSYSROUTEA |= (1 << ((event_user & 0x7F) - 0x0E));
+ #elif defined(__AVR_DB__) || defined(__AVR_DD__) || defined(TINY_2_SERIES)
+ PORTMUX_EVSYSROUTEA |= (1 << ((event_user & 0x7F) - 0x0D));
+ #endif
+ }
+ #endif
+}
+
+
+/**
+ * @brief Sets an Arduino pin as a user for a particular event channel
+ *
+ * @param pin_number The Arduino pin number to use as a channel user
+ * @return uint8_t Event channel user enum
+ (for instance event::user::evouta_pin_pa2 pin PIN_PA2 is passed)
+ * Returns -1 if invalid pin is passed
+ */
+int8_t Event::set_user_pin(uint8_t pin_number) {
+ uint8_t port = digitalPinToPort(pin_number);
+ uint8_t port_pin = digitalPinToBitPosition(pin_number);
+ int8_t event_user = -1;
+
+ if(port != NOT_A_PIN && port_pin != NOT_A_PIN) {
+ uint8_t evout_user = (uint8_t)event::user::evouta_pin_pa2;
+ if(port_pin == 2) {
+ event_user = (event::user::user_t)(evout_user + port);
+ }
+ #if !defined(TINY_0_SERIES) && !defined(TINY_1_SERIES)
+ else if(port_pin == 7) {
+ event_user = (event::user::user_t)(evout_user + port);
+ }
+
+ #endif
+ else {
+ return -1;
+ }
+ set_user((event::user::user_t)event_user);
+ }
+ return event_user;
+}
+
+
+/**
+ * @brief Clears/removed a user from a particular event channel if set
+ *
+ * @param event_user The event user to remove from a particular channel
+ */
+void Event::clear_user(event::user::user_t event_user) {
+ // Figure out what user register to write to based on the passed parameter
+ uint8_t event_user_mask = event_user & 0x7F;
+ volatile uint8_t *user_register = &EVSYS_USERCCLLUT0A + (volatile uint8_t&)event_user_mask;
+
+ // Disconnect from event generator
+ *user_register = 0x00;
+
+ // Clear PORTMUX pin swap for EVOUT if selected as channel generator
+ #if defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ if(event_user >= 0x08 && event_user <= 0x0A) {
+ PORTMUX.CTRLA &= ~(1 << (event_user - 0x08));
+ }
+ #else
+ if(event_user & 0x80) {
+ #if defined(MEGACOREX)
+ PORTMUX_EVSYSROUTEA &= ~(1 << ((event_user & 0x7F) - 0x09));
+ #elif defined(__AVR_DA__)
+ PORTMUX_EVSYSROUTEA &= ~(1 << ((event_user & 0x7F) - 0x0E));
+ #elif defined(__AVR_DB__) || defined(__AVR_DD__) || defined(TINY_2_SERIES)
+ PORTMUX_EVSYSROUTEA &= ~(1 << ((event_user & 0x7F) - 0x0D));
+ #endif
+ }
+ #endif
+}
+
+
+/**
+ * @brief Creates a software event for a particular event channel
+ *
+ */
+void Event::soft_event() {
+ // Write to the bit that represent the channel in the strobe register
+ #if defined(EVSYS_STROBE)
+ // megaAVR 0-series calls the register EVSYS.STROBE
+ EVSYS.STROBE = (1 << channel_number);
+ #elif defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ // Channels 0 and 1 are the sync channels, which are strobbed with the syncstrobe registers. The others are the async channels,
+ // strobed with the asyncstrobe. Since the sync strobe has only 2 possible thing s to strobe, bit 0 or bit 1 corresponding to byte
+ // values 1 and 2, we can just add 1 to the byte value to achieve that.
+ if(channel_number < 2) {
+ EVSYS.SYNCSTROBE = (channel_number + 1);
+ }
+ else {
+ EVSYS.ASYNCSTROBE = (1 << (channel_number - 2));
+ }
+ #else
+ // Everything newer calls the registers EVSYS.SWEVENTA or SWEVENTB for the few devices lucky enough to have more than 8 channels.
+ #if defined(EVSYS_SWEVENTB)
+ if(channel_number < 8) {
+ EVSYS.SWEVENTA = (1 << channel_number);
+ }
+ else {
+ /* Dirty trick: No available part has more than 10 event channels.
+ * So if we are strobing one of those last two, the value we are writing to the register is iwith 1 or 2 (as with sync channel
+ * on tiny 0/1). So channel number is 8 or 9, subtract 7 to get 1 or 2, and write that.
+ * Doesn't save much flash, but variable-shift operations are surprisignly inefficient in speed. The case for SWEVENTA involves
+ * a loop, 5 clocks in duration per bit
+ */
+ EVSYS.SWEVENTB = channel_number - 7;
+ }
+ #else
+ EVSYS.SWEVENTA = (1 << channel_number);
+ #endif
+ #endif
+}
+
+
+/**
+ * @brief Creates a software event for a particular event channel with a set
+ * time duration
+ *
+ * @param length Length in CPU clock cycles
+ */
+void Event::long_soft_event(uint8_t length) {
+ uint8_t channel = channel_number;
+ uint16_t strobeaddr;
+ #if defined(EVSYS_STROBE)
+ strobeaddr = (uint16_t)&EVSYS_STROBE;
+ #elif defined(EVSYS_SYNCSTROBE)
+ if(channel > 1)
+ strobeaddr = (uint16_t)&EVSYS_ASYNCSTROBE;
+ else
+ strobeaddr = (uint16_t)&EVSYS_SYNCSTROBE;
+ #elif defined(EVSYS_SWEVENTB)
+ if(channel > 7) {
+ channel -= 8;
+ strobeaddr = (uint16_t)&EVSYS_SWEVENTB;
+ }
+ else {
+ strobeaddr = (uint16_t)&EVSYS_SWEVENTA;
+ }
+ #elif defined(EVSYS_SWEVENTA)
+ strobeaddr = (uint16_t)&EVSYS_SWEVENTA;
+ #else
+ #error "Don't know the strobe register!"
+ #endif
+ channel = (1 << channel);
+ __asm__ __volatile__ (
+ "in r0, 0x3F" "\n\t" // Save SREG
+ "cli" "\n\t" // Interrupts off
+ "cpi %1, 4" "\n\t"
+ "brcs long_soft2" "\n\t" // Less than 4 -> 2
+ "breq long_soft4" "\n\t" // Equal to 4 -> 4
+ "cpi %1, 10" "\n\t" // Compare with 8
+ "brcs long_soft6" "\n\t" // Less than 10 (but more than 4) -> 6
+ "breq long_soft10""\n\t" // Equal to 10 -> 10
+ "st Z, %0" "\n\t" // Otherwise they get 16.
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "long_soft10:" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "long_soft6:" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "long_soft4:" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "long_soft2:" "\n\t"
+ "st Z, %0" "\n\t"
+ "st Z, %0" "\n\t"
+ "out 0x3f, r0" "\n" // Restore SREG, reenable interrupts
+ ::"r"((uint8_t) channel),"d"((uint8_t) length),"z" ((uint16_t) strobeaddr));
+}
+
+
+/**
+ * @brief Static function used to get the generator number the analog
+ * comparator peripheral
+ *
+ * @param comp Analog comparator struct
+ * @return event::gen::generator_t generator type
+ */
+event::gen::generator_t Event::gen_from_peripheral(AC_t& comp)
+{
+ #if defined(TINY_1_SERIES) && PROGMEM_SIZE > 8192
+ // badCall("gen_from_peripheral() does not support channel-specific generators. The AC's larger 1-series are.");
+ #else
+ #if defined(AC0)
+ if(&comp == &AC0) {
+ return event::gen::ac0_out;
+ }
+ #if defined(AC1)
+ else if(&comp == &AC1) {
+ return event::gen::ac1_out;
+ }
+ #if defined(AC2)
+ else if(&comp == &AC2) {
+ return event::gen::ac2_out;
+ }
+ #endif
+ #endif
+ #endif
+ #endif
+ return (event::gen::generator_t) -1;
+}
+
+
+/**
+ * @brief Static function used to get the generator type from the CCL peripheral
+ *
+ * @param logic CCL struct
+ * @param logic_block Logic block number (0, 1, 2 or 3 for megaAVR-0's)
+ * @return event::gen::generator_t generator type
+ */
+event::gen::generator_t Event::gen_from_peripheral(CCL_t& logic, uint8_t logic_block) {
+ uint8_t retval = -1;
+ if(&logic == &CCL) {
+ #if defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ if(logic_block < 2)
+ #elif defined(CCL_LUT4CTRLA)
+ if(logic_block < 6)
+ #else
+ if(logic_block < 4)
+ #endif
+ {
+ retval = (int8_t)(event::gen::ccl0_out) + logic_block;
+ }
+ }
+ return (event::gen::generator_t)retval;
+}
+
+
+/**
+ * @brief Static function used to get the possible users the CCL peripheral has
+ * to offer
+ *
+ * @param logic CCL struct
+ * @param user_type
+ * @return event::user::user_t CCL user number.
+ */
+event::user::user_t Event::user_from_peripheral(CCL_t& logic, uint8_t user_type) {
+ uint8_t retval = -1;
+ if(&logic == &CCL) {
+ #if !defined(TINY_0_SERIES) && !defined(TINY_1_SERIES)
+ #if defined(CCL_TRUTH4)
+ if(user_type < 13)
+ #else
+ if(user_type < 9)
+ #endif
+ {
+ retval = user_type;
+ }
+ #else
+ if(user_type < 5) {
+ retval = user_type + 2;
+ }
+ #endif
+ }
+ return (event::user::user_t)retval;
+}
+
+
+/**
+ * @brief Static function used to get the generator type from timer A
+ *
+ * @param logic TCA struct
+ * @param event_type TCA has multiple generators. This parameter provides the number,
+ * and ranges from 0 to 4 for megaAVR-0's
+ * @return event::gen::generator_t generator type
+ */
+event::gen::generator_t Event::gen_from_peripheral(TCA_t& timer, uint8_t event_type) {
+ uint8_t retval = -1;
+ if(event_type < 5) {
+ #if defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ retval = event_type + 2;
+ #else
+ if(&TCA0 == &timer) {
+ retval = event_type + 0x80;
+ }
+ #if defined(TCA1)
+ else if(&TCA1 == &timer) {
+ retval = event_type += 0x88;
+ }
+ #endif
+ #endif
+ }
+ return (event::gen::generator_t)retval;
+}
+
+
+/**
+ * @brief Static function used to get the possible users the TCA timer has to offer
+ *
+ * @param timer TCA struct
+ * @param user_type TCA has only has one user on megaAVR-0's.
+ * Leave this parameter unused
+ * @return event::user::user_t TCA user number
+ */
+event::user::user_t Event::user_from_peripheral(TCA_t& timer, uint8_t user_type) {
+ uint8_t user = -1;
+
+ #if defined(TINY_0_SERIES) || defined(TINY_1_SERIES) || defined(MEGACOREX)
+ if(user_type != 0) {
+ return (event::user::user_t) -1;
+ }
+ #else
+ if(user_type > 1) {
+ return (event::user::user_t) -1;
+ }
+ #endif
+ user = user_type; // 0 or 1 for event user a or b (on parts with both, or 0 for parts that only have one
+ #if defined(TCA1)
+ if(&timer == &TCA1) {
+ user += 2;
+ } else
+ #endif
+ if(&timer != &TCA0) {
+ return (event::user::user_t) -1;
+ }
+ #if defined(__AVR_DA__)
+ user += 0x1B;
+ #elif defined(__AVR_DB__) || defined(__AVR_DD__)
+ user += 0x1A;
+ #elif defined(MEGACOREX)
+ user += 0x13;
+ #elif defined(TINY_2_SERIES)
+ user += 0x0E;
+ #else
+ user += 0x10;
+ #endif
+ return (event::user::user_t)user;
+}
+
+
+/**
+ * @brief Static function used to get the generator type from timer B
+ *
+ * @param timer TCB struct
+ * @param event_type TCB only has one generators on megaAVR-0's.
+ * Leave this parameter unused
+ * @return event::gen::generator_t generator type
+ */
+event::gen::generator_t Event::gen_from_peripheral(TCB_t& timer, uint8_t event_type) {
+ int8_t gentype = -1;
+ #if defined(TINY_0_OR_1_SERIES)
+ // badCall("gen_from_peripheral() does not support channel-specific generators. The TCBs on 0/1-series are.");
+ #else
+ #if defined(MEGACOREX) // Dx-series and 2-series have ovf event, others don't.
+ if(event_type != 1) {
+ return (event::gen::generator_t) -1;
+ }
+ else {
+ gentype = 0;
+ }
+ #else
+ if(event_type < 2) {
+ gentype = event_type;
+ }
+ #endif
+ if(&timer == &TCB0) {
+ gentype += (uint8_t)event::gen::tcb0_capt;
+ } else
+ #if defined(TCB1)
+ if (&timer == &TCB1) {
+ gentype += (uint8_t)event::gen::tcb1_capt;
+ } else
+ #endif
+ #if defined(TCB2)
+ if (&timer == &TCB2) {
+ gentype += (uint8_t)event::gen::tcb2_capt;
+ } else
+ #endif
+ #if defined(TCB3)
+ if (&timer == &TCB3) {
+ gentype += (uint8_t)event::gen::tcb3_capt;
+ } else
+ #endif
+ #if defined(TCB4)
+ if (&timer == &TCB4) {
+ gentype += (uint8_t)event::gen::tcb4_capt;
+ } else
+ #endif
+ {
+ gentype = -1;
+ }
+ #endif
+ return (event::gen::generator_t) gentype;
+}
+
+
+/**
+ * @brief Static function used to get the possible users the TCB timer has to offer
+ *
+ * @param timer TCB struct
+ * @param user_type
+ * @return event::user::user_t TCA user number
+ */
+event::user::user_t Event::user_from_peripheral(TCB_t& timer, uint8_t user_type) {
+ uint8_t user = -1;
+ #if defined(TINY_0_SERIES) || defined(TINY_1_SERIES) || defined(MEGACOREX) // Dx-series and 2-series have event count input, others don't.
+ if (user_type != 1) {
+ return (event::user::user_t) -1;
+ }
+ else {
+ user = 0;
+ }
+ #else
+ if (user_type < 2) {
+ user = user_type;
+ }
+ #endif
+ if (&timer == &TCB0) {
+ user += (uint8_t)event::user::tcb0_capt;
+ } else
+ #if defined(TCB1)
+ if (&timer == &TCB1) {
+ user += (uint8_t)event::user::tcb1_capt;
+ } else
+ #endif
+ #if defined(TCB2)
+ if (&timer == &TCB2) {
+ user += (uint8_t)event::user::tcb2_capt;
+ } else
+ #endif
+ #if defined(TCB3)
+ if (&timer == &TCB3) {
+ user += (uint8_t)event::user::tcb3_capt;
+ } else
+ #endif
+ #if defined(TCB4)
+ if (&timer == &TCB4) {
+ user += (uint8_t)event::user::tcb4_capt;
+ } else
+ #endif
+ {
+ user = -1;
+ }
+ return (event::user::user_t)user;
+}
+
+
+/**
+ * @brief Static function used to get the possible users the USART peripheral has
+ * to offer
+ *
+ * @param usart USART struct
+ * @return event::user::user_t USART related event channel user
+ */
+event::user::user_t Event::user_from_peripheral(USART_t& usart) {
+ if(&usart == &USART0) {
+ return event::user::usart0_irda;
+ }
+ #if defined(USART1)
+ else if(&usart == &USART1) {
+ return event::user::usart1_irda;
+ }
+ #endif
+ #if defined(USART2)
+ else if(&usart == &USART2) {
+ return event::user::usart2_irda;
+ }
+ #endif
+ #if defined(USART3)
+ else if(&usart == &USART3) {
+ return event::user::usart3_irda;
+ }
+ #endif
+ #if defined(USART4)
+ else if(&usart == &USART4) {
+ return event::user::usart4_irda;
+ }
+ #endif
+ #if defined(USART5)
+ else if(&usart == &USART5) {
+ return event::user::usart5_irda;
+ }
+ #endif
+ return (event::user::user_t) -1;
+}
+
+
+/**
+ * @brief Starts the event generator for a particular event channel
+ *
+ * @param state Optional parameter. Defaults to true
+ */
+void Event::start(bool state) {
+ if(state) {
+ // Write event generator setting to EVSYS_CHANNELn register
+ channel_address = generator_type;
+ }
+ else {
+ // Disable event generator
+ channel_address = event::gen::disable;
+ }
+}
+
+
+/**
+ * @brief Stops the event generator for a particular event channel
+ *
+ */
+void Event::stop() {
+ start(false);
+}
diff --git a/megaavr/libraries/Event/src/Event.h b/megaavr/libraries/Event/src/Event.h
new file mode 100644
index 0000000..512391e
--- /dev/null
+++ b/megaavr/libraries/Event/src/Event.h
@@ -0,0 +1,1381 @@
+#ifndef EVENT_H
+#define EVENT_H
+
+#include
+
+#if defined(MEGATINYCORE)
+ #if (MEGATINYCORE_SERIES == 0)
+ #define TINY_0_SERIES
+ #elif (MEGATINYCORE_SERIES == 1)
+ #define TINY_1_SERIES
+ #elif (MEGATINYCORE_SERIES == 2)
+ #define TINY_2_SERIES
+ #endif
+#endif
+
+namespace event {
+#if defined(MEGACOREX) || defined(DXCORE)
+ // Features present on all generator channels
+ namespace gen {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ updi_synch = 0x01,
+ rtc_ovf = 0x06,
+ rtc_cmp = 0x07,
+ ccl0_out = 0x10,
+ ccl1_out = 0x11,
+ ccl2_out = 0x12,
+ ccl3_out = 0x13,
+ ac0_out = 0x20,
+#if defined(AC1)
+ ac1_out = 0x21,
+#endif
+#if defined(AC2)
+ ac2_out = 0x22,
+#endif
+ adc0_ready = 0x24,
+ usart0_xck = 0x60,
+ usart1_xck = 0x61,
+ usart2_xck = 0x62,
+#if defined(USART3)
+ usart3_xck = 0x63,
+#endif
+ spi0_sck = 0x68,
+ tca0_ovf_lunf = 0x80,
+ tca0_hunf = 0x81,
+ tca0_cmp0 = 0x84,
+ tca0_cmp1 = 0x85,
+ tca0_cmp2 = 0x86,
+ tcb0_capt = 0xA0,
+ tcb0 = 0xA0,
+ tcb1_capt = 0xA2,
+ tcb1 = 0xA2,
+ tcb2_capt = 0xA4,
+ tcb2 = 0xA4,
+#if defined(TCB3)
+ tcb3_capt = 0xA6,
+ tcb3 = 0xA6,
+#endif
+#if defined(TCB4)
+ tcb4_capt = 0xA8,
+ tcb4 = 0xA8,
+#endif
+#if defined(__AVR_DA__) || defined(__AVR_DB__)
+ ccl4_out = 0x14,
+ ccl5_out = 0x15,
+ zcd0_out = 0x30,
+ zcd1_out = 0x31,
+#if defined(ZCD2)
+ zcd2_out = 0x32,
+#endif
+#if defined(USART4)
+ usart4_xck = 0x64,
+#endif
+#if defined(USART5)
+ usart5_xck = 0x65,
+#endif
+ spi1_sck = 0x69,
+#if defined(TCA1)
+ tca1_ovf_lunf = 0x88,
+ tca1_hunf = 0x89,
+ tca1_cmp0 = 0x8C,
+ tca1_cmp1 = 0x8D,
+ tca1_cmp2 = 0x8E,
+#endif
+#endif // defined(__AVR_DA__) || defined(__AVR_DB__)
+#if defined(DXCORE)
+// These are present on every modern part released since the 0/1-series and will probably continue to be, so check
+ tcb0_ovf = 0xA1,
+ tcb1_ovf = 0xA3,
+#if defined(TCB2)
+ tcb2_ovf = 0xA5,
+#endif
+#if defined(TCB3)
+ tcb3_ovf = 0xA7,
+#endif
+#if defined(TCB4)
+ tcb4_ovf = 0xA9,
+#endif
+#endif
+#if defined(TCD0)
+ tcd0_cmpbclr = 0xB0,
+ tcd0_cmpaset = 0xB1,
+ tcd0_cmpbset = 0xB2,
+ tcd0_progev = 0xB3,
+#endif
+#if defined(MVIO)
+ mvio_ok = 0x05,
+#endif
+#if defined(ZCD3)
+ zcd3_out = 0x30, // The ZCD is numbered differently, I think just because it's on different pins. Still has the same event channel
+#endif
+#if defined(__AVR_DB__)
+ opamp0_ready = 0x34,
+ opamp1_ready = 0x35,
+#if defined(OPAMP2)
+ opamp2_ready = 0x36,
+#endif
+#endif // defined(__AVR_DB__)
+ };
+ };
+
+// Features unique to event generator channel 0
+#if defined(EVSYS_CHANNEL0)
+ namespace gen0 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div8192 = 0x08,
+ rtc_div4096 = 0x09,
+ rtc_div2048 = 0x0A,
+ rtc_div1024 = 0x0B,
+ pin_pa0 = 0x40,
+ pin_pa1 = 0x41,
+#if !defined(DXCORE) || defined(PIN_PA2)
+ pin_pa2 = 0x42,
+ pin_pa3 = 0x43,
+ pin_pa4 = 0x44,
+ pin_pa5 = 0x45,
+ pin_pa6 = 0x46,
+ pin_pa7 = 0x47,
+#endif
+#if defined(PIN_PB0)
+ pin_pb0 = 0x48,
+ pin_pb1 = 0x49,
+ pin_pb2 = 0x4A,
+ pin_pb3 = 0x4B,
+ pin_pb4 = 0x4C,
+ pin_pb5 = 0x4D,
+#endif
+#if defined(PIN_PB6)
+ pin_pb6 = 0x4E,
+ pin_pb7 = 0x4F,
+#endif
+ };
+ };
+#endif
+
+// Features unique to event generator channel 1
+#if defined(EVSYS_CHANNEL1)
+ namespace gen1 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div512 = 0x08,
+ rtc_div256 = 0x09,
+ rtc_div128 = 0x0A,
+ rtc_div64 = 0x0B,
+ pin_pa0 = 0x40,
+ pin_pa1 = 0x41,
+#if defined(PIN_PA2)
+ pin_pa2 = 0x42,
+ pin_pa3 = 0x43,
+ pin_pa4 = 0x44,
+ pin_pa5 = 0x45,
+ pin_pa6 = 0x46,
+ pin_pa7 = 0x47,
+#endif
+#if defined(PIN_PB0)
+ pin_pb0 = 0x48,
+ pin_pb1 = 0x49,
+ pin_pb2 = 0x4A,
+ pin_pb3 = 0x4B,
+ pin_pb4 = 0x4C,
+ pin_pb5 = 0x4D,
+#endif
+#if defined(PIN_PB6)
+ pin_pb6 = 0x4E,
+ pin_pb7 = 0x4F,
+#endif
+ };
+ };
+#endif
+
+// Features unique to event generator channel 2
+#if defined(EVSYS_CHANNEL2)
+ namespace gen2 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div8192 = 0x08,
+ rtc_div4096 = 0x09,
+ rtc_div2048 = 0x0A,
+ rtc_div1024 = 0x0B,
+#if !defined(DD_14_PINS) // Can't just check PIN_PC0 - the 0-pin of any port with any pins present is always defined by DxCore.
+ // I considered both ways, but there are to many reasons we need to have the 0-pin defined.
+ pin_pc0 = 0x40,
+#endif
+ pin_pc1 = 0x41,
+ pin_pc2 = 0x42,
+ pin_pc3 = 0x43,
+#if defined(PIN_PC4)
+ pin_pc4 = 0x44,
+ pin_pc5 = 0x45,
+ pin_pc6 = 0x46,
+ pin_pc7 = 0x47,
+#endif
+#if defined(PIN_PD1) // See above for note on PIN_PD0 and why we can't test that, this even impacts DBs.
+#if !defined(MVIO) || defined(__AVR_ATmegax09__) || defined(Dx_48_PINS) || defined(Dx_64_PINS)
+ pin_pd0 = 0x48,
+#endif
+ pin_pd1 = 0x49,
+ pin_pd2 = 0x4A,
+ pin_pd3 = 0x4B,
+#endif
+ pin_pd4 = 0x4C,
+ pin_pd5 = 0x4D,
+ pin_pd6 = 0x4E,
+ pin_pd7 = 0x4F,
+ };
+};
+#endif
+
+// Features unique to event generator channel 3
+#if defined(EVSYS_CHANNEL3)
+ namespace gen3 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div512 = 0x08,
+ rtc_div256 = 0x09,
+ rtc_div128 = 0x0A,
+ rtc_div64 = 0x0B,
+#if !defined(DD_14_PINS)
+ pin_pc0 = 0x40,
+#endif
+ pin_pc1 = 0x41,
+ pin_pc2 = 0x42,
+ pin_pc3 = 0x43,
+#if defined(PIN_PC4)
+ pin_pc4 = 0x44,
+ pin_pc5 = 0x45,
+ pin_pc6 = 0x46,
+ pin_pc7 = 0x47,
+#endif
+#if defined(PIN_PD1) // See above for note on PIN_PD0 and why we can't test that, this even impacts DBs.
+#if !defined(MVIO) || defined(__AVR_ATmegax09__) || defined(Dx_48_PINS) || defined(Dx_64_PINS)
+ pin_pd0 = 0x48,
+#endif
+ pin_pd1 = 0x49,
+ pin_pd2 = 0x4A,
+ pin_pd3 = 0x4B,
+#endif
+ pin_pd4 = 0x4C,
+ pin_pd5 = 0x4D,
+ pin_pd6 = 0x4E,
+ pin_pd7 = 0x4F,
+ };
+ };
+#endif
+
+// Features unique to event generator channel 4
+#if defined(EVSYS_CHANNEL4)
+ namespace gen4 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div8192 = 0x08,
+ rtc_div4096 = 0x09,
+ rtc_div2048 = 0x0A,
+ rtc_div1024 = 0x0B,
+#if defined(PIN_PE0)
+ pin_pe0 = 0x40,
+ pin_pe1 = 0x41,
+ pin_pe2 = 0x42,
+ pin_pe3 = 0x43,
+#endif
+#if defined(PIN_PE4)
+ pin_pe4 = 0x44,
+ pin_pe5 = 0x45,
+ pin_pe6 = 0x46,
+ pin_pe7 = 0x47,
+#endif
+ pin_pf0 = 0x48,
+ pin_pf1 = 0x49,
+#if defined(PIN_PF2)
+ pin_pf2 = 0x4A,
+ pin_pf3 = 0x4B,
+ pin_pf4 = 0x4C,
+ pin_pf5 = 0x4D,
+#endif
+ pin_pf6 = 0x4E,
+#if defined(PIN_PF7)
+ pin_pf7 = 0x4F,
+#endif
+ };
+ };
+#endif
+
+// Features unique to event generator channel 5
+#if defined(EVSYS_CHANNEL5)
+ namespace gen5 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div512 = 0x08,
+ rtc_div256 = 0x09,
+ rtc_div128 = 0x0A,
+ rtc_div64 = 0x0B,
+#if defined(PIN_PE0)
+ pin_pe0 = 0x40,
+ pin_pe1 = 0x41,
+ pin_pe2 = 0x42,
+ pin_pe3 = 0x43,
+#endif
+#if defined(PIN_PE4)
+ pin_pe4 = 0x44,
+ pin_pe5 = 0x45,
+ pin_pe6 = 0x46,
+ pin_pe7 = 0x47,
+#endif
+ pin_pf0 = 0x48,
+ pin_pf1 = 0x49,
+#if defined(PIN_PF2)
+ pin_pf2 = 0x4A,
+ pin_pf3 = 0x4B,
+ pin_pf4 = 0x4C,
+ pin_pf5 = 0x4D,
+#endif
+ pin_pf6 = 0x4E,
+#if defined(PIN_PF7)
+ pin_pf7 = 0x4F,
+#endif
+ };
+ };
+#endif
+
+// Features unique to event generator channel 6
+#if defined(EVSYS_CHANNEL6)
+ namespace gen6 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div8192 = 0x08,
+ rtc_div4096 = 0x09,
+ rtc_div2048 = 0x0A,
+ rtc_div1024 = 0x0B,
+#if defined(PIN_PG0)
+ pin_pg0 = 0x40,
+ pin_pg1 = 0x41,
+ pin_pg2 = 0x42,
+ pin_pg3 = 0x43,
+ pin_pg4 = 0x44,
+ pin_pg5 = 0x45,
+ pin_pg6 = 0x46,
+ pin_pg7 = 0x47,
+#endif
+ };
+ };
+#endif
+
+// Features unique to event generator channel 7
+#if defined(EVSYS_CHANNEL7)
+ namespace gen7 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div512 = 0x08,
+ rtc_div256 = 0x09,
+ rtc_div128 = 0x0A,
+ rtc_div64 = 0x0B,
+#if defined(PIN_PG0)
+ pin_pg0 = 0x40,
+ pin_pg1 = 0x41,
+ pin_pg2 = 0x42,
+ pin_pg3 = 0x43,
+ pin_pg4 = 0x44,
+ pin_pg5 = 0x45,
+ pin_pg6 = 0x46,
+ pin_pg7 = 0x47,
+#endif
+ };
+ };
+#endif
+
+// Features unique to event generator channel 8
+#if defined(EVSYS_CHANNEL8)
+ namespace gen8 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div8192 = 0x08,
+ rtc_div4096 = 0x09,
+ rtc_div2048 = 0x0A,
+ rtc_div1024 = 0x0B,
+ };
+ };
+#endif
+
+// Features unique to event generator channel 9
+#if defined(EVSYS_CHANNEL9)
+ namespace gen9 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ rtc_div512 = 0x08,
+ rtc_div256 = 0x09,
+ rtc_div128 = 0x0A,
+ rtc_div64 = 0x0B,
+ };
+ };
+#endif
+
+
+// Generator users
+ namespace user {
+ enum user_t : uint8_t {
+#if defined(MEGACOREX)
+ ccl0_event_a = 0x00,
+ ccl0_event_b = 0x01,
+ ccl1_event_a = 0x02,
+ ccl1_event_b = 0x03,
+ ccl2_event_a = 0x04,
+ ccl2_event_b = 0x05,
+ ccl3_event_a = 0x06,
+ ccl3_event_b = 0x07,
+ adc0_start = 0x08,
+ evouta_pin_pa2 = 0x09,
+#if defined(PIN_PB2)
+ evoutb_pin_pb2 = 0x0A,
+#endif
+ evoutc_pin_pc2 = 0x0B,
+ evoutd_pin_pd2 = 0x0C,
+#if defined(PIN_PE2)
+ evoute_pin_pe2 = 0x0D,
+#endif
+ evoutf_pin_pf2 = 0x0E,
+ usart0_irda = 0x0F,
+ usart1_irda = 0x10,
+ usart2_irda = 0x11,
+#if defined(USART3)
+ usart3_irda = 0x12,
+#endif
+ tca0 = 0x13,
+ tca0_cnt_a = 0x13,
+ tcb0 = 0x14,
+ tcb0_capt = 0x14,
+ tcb1 = 0x15,
+ tcb1_capt = 0x15,
+ tcb2 = 0x16,
+ tcb2_capt = 0x16,
+#if defined(TCB3)
+ tcb3 = 0x17,
+ tcb3_capt = 0x17,
+#endif
+ // "Unofficial" user generators. Uses EVOUT, but swaps the output pin using PORTMUX
+ evouta_pin_pa7 = 0x89,
+#if defined(PIN_PC7)
+ evoutc_pin_pc7 = 0x8B,
+#endif
+ evoutd_pin_pd7 = 0x8C,
+#endif // defined(MEGACOREX)
+
+#if defined(__AVR_DA__)
+ ccl0_event_a = 0x00,
+ ccl0_event_b = 0x01,
+ ccl1_event_a = 0x02,
+ ccl1_event_b = 0x03,
+ ccl2_event_a = 0x04,
+ ccl2_event_b = 0x05,
+ ccl3_event_a = 0x06,
+ ccl3_event_b = 0x07,
+#if defined(LUT4)
+ ccl4_event_a = 0x08,
+ ccl4_event_b = 0x09,
+ ccl5_event_a = 0x0A,
+ ccl5_event_b = 0x0B,
+#endif
+ adc0_start = 0x0C,
+ ptc_start = 0x0D,
+ evouta_pin_pa2 = 0x0E,
+#if defined(PIN_PB2)
+ evoutb_pin_pb2 = 0x0F,
+#endif
+ evoutc_pin_pc2 = 0x10,
+ evoutd_pin_pd2 = 0x11,
+#if defined(PIN_PE2)
+ evoute_pin_pe2 = 0x12,
+#endif
+#if defined(PIN_PF2)
+ evoutf_pin_pf2 = 0x13,
+#endif
+#if defined(PIN_PG2)
+ evoutg_pin_pg2 = 0x14,
+#endif
+ usart0_irda = 0x15,
+ usart1_irda = 0x16,
+ usart2_irda = 0x17,
+#if defined(USART5)
+ usart3_irda = 0x18,
+#endif
+#if defined(USART4)
+ usart4_irda = 0x19,
+#endif
+#if defined(USART5)
+ usart5_irda = 0x1A,
+#endif
+ tca0 = 0x1B,
+ tca0_cnt_a = 0x1B,
+ tca0_cnt_b = 0x1C,
+ tca1 = 0x1D,
+ tca1_cnt_a = 0x1D,
+ tca1_cnt_b = 0x1E,
+ tcb0_capt = 0x1F,
+ tcb0 = 0x1F,
+ tcb0_cnt = 0x20,
+ tcb1_capt = 0x21,
+ tcb1 = 0x21,
+ tcb1_cnt = 0x22,
+ tcb2_capt = 0x23,
+ tcb2 = 0x23,
+ tcb2_cnt = 0x24,
+#if defined(TCB3)
+ tcb3_capt = 0x25,
+ tcb3 = 0x25,
+ tcb3_cnt = 0x26,
+#endif
+#if defined(TCB4)
+ tcb4_capt = 0x27,
+ tcb4 = 0x27,
+ tcb4_cnt = 0x28,
+#endif
+ tcd0_in_a = 0x29,
+ tcd0_in_b = 0x2A,
+ // "Unofficial" user generators. Uses EVOUT, but swaps the output pin using PORTMUX
+ evouta_pin_pa7 = 0x8E,
+#if defined(PIN_PB7)
+ evoutb_pin_pb7 = 0x8F,
+#endif
+#if defined(PIN_PC7)
+ evoutc_pin_pc7 = 0x90,
+#endif
+ evoutd_pin_pd7 = 0x91,
+#if defined(PIN_PE7)
+ evoute_pin_pe7 = 0x92,
+#endif
+ // evoutf_pin_pf7 = 0x93, never available on DA/DB
+#if defined(PIN_PG7)
+ evoutg_pin_pg7 = 0x94,
+#endif
+#endif // defined(__AVR_DA__)
+#if defined(__AVR_DB__)
+ ccl0_event_a = 0x00,
+ ccl0_event_b = 0x01,
+ ccl1_event_a = 0x02,
+ ccl1_event_b = 0x03,
+ ccl2_event_a = 0x04,
+ ccl2_event_b = 0x05,
+ ccl3_event_a = 0x06,
+ ccl3_event_b = 0x07,
+#if defined(LUT4)
+ ccl4_event_a = 0x08,
+ ccl4_event_b = 0x09,
+ ccl5_event_a = 0x0A,
+ ccl5_event_b = 0x0B,
+#endif
+ adc0_start = 0x0C,
+ evouta_pin_pa2 = 0x0D,
+#if defined(PIN_PB2)
+ evoutb_pin_pb2 = 0x0E,
+#endif
+ evoutc_pin_pc2 = 0x0F,
+ evoutd_pin_pd2 = 0x10,
+#if defined(PIN_PE2)
+ evoute_pin_pe2 = 0x11,
+#endif
+#if defined(PIN_PF2)
+ evoutf_pin_pf2 = 0x12,
+#endif
+#if defined(PIN_PG2)
+ evoutg_pin_pg2 = 0x13,
+#endif
+ usart0_irda = 0x14,
+ usart1_irda = 0x15,
+ usart2_irda = 0x16,
+#if defined(USART3)
+ usart3_irda = 0x17,
+#endif
+#if defined(USART4)
+ usart4_irda = 0x18,
+#endif
+#if defined(USART5)
+ usart5_irda = 0x19,
+#endif
+ tca0 = 0x1A,
+ tca0_cnt_a = 0x1A,
+ tca0_cnt_b = 0x1B,
+ tca1 = 0x1C,
+ tca1_cnt_a = 0x1C,
+ tca1_cnt_b = 0x1D,
+ tcb0_capt = 0x1E,
+ tcb0_cnt = 0x1F,
+ tcb1_capt = 0x20,
+ tcb1_cnt = 0x21,
+ tcb2_capt = 0x22,
+ tcb2_cnt = 0x23,
+#if defined(TCB3)
+ tcb3_capt = 0x24,
+ tcb3_cnt = 0x25,
+#endif
+#if defined(TCB4)
+ tcb4_capt = 0x26,
+ tcb4_cnt = 0x27,
+#endif
+ tcd0_in_a = 0x28,
+ tcd0_in_b = 0x29,
+ opamp0_enable = 0x2A,
+ opamp0_disable = 0x2B,
+ opamp0_dump = 0x2C,
+ opamp0_drive = 0x2D,
+ opamp1_enable = 0x2E,
+ opamp1_disable = 0x2F,
+ opamp1_dump = 0x30,
+ opamp1_drive = 0x31,
+#if defined(OPAMP2)
+ opamp2_enable = 0x32,
+ opamp2_disable = 0x33,
+ opamp2_dump = 0x34,
+ opamp2_drive = 0x35,
+#endif
+ // "Unofficial" user generators. Uses EVOUT, but swaps the output pin using PORTMUX
+ evouta_pin_pa7 = 0x8D,
+#if defined(PIN_PB7)
+ evoutb_pin_pb7 = 0x8E,
+#endif
+#if defined(PIN_PC7)
+ evoutc_pin_pc7 = 0x8F,
+#endif
+ evoutd_pin_pd7 = 0x90,
+#if defined(PIN_PE7)
+ evoute_pin_pe7 = 0x91,
+#endif
+#if defined(PIN_PG7)
+ evoutg_pin_pg7 = 0x93,
+#endif
+#endif // defined(__AVR_DB__)
+
+#if defined(__AVR_DD__)
+ ccl0_event_a = 0x00,
+ ccl0_event_b = 0x01,
+ ccl1_event_a = 0x02,
+ ccl1_event_b = 0x03,
+ ccl2_event_a = 0x04,
+ ccl2_event_b = 0x05,
+ ccl3_event_a = 0x06,
+ ccl3_event_b = 0x07,
+ adc0_start = 0x0C,
+#if defined(PIN_PA2) // not on 14-pin ones.
+ evouta_pin_pa2 = 0x0D,
+#endif
+ evoutc_pin_pc2 = 0x0F,
+#if defined(PIN_PD2) // only on 28 or 32 pin ones.
+ evoutd_pin_pd2 = 0x10,
+#endif
+#if defined(PIN_PF2) // only on 32-pin ones.
+ evoutf_pin_pf2 = 0x12,
+#endif
+ usart0_irda = 0x14,
+ usart1_irda = 0x15,
+ tca0 = 0x1A,
+ tca0_cnt_a = 0x1A,
+ tca0_cnt_b = 0x1B,
+ tcb0 = 0x1E,
+ tcb0_capt = 0x1E,
+ tcb0_cnt = 0x1F,
+ tcb1 = 0x20,
+ tcb1_capt = 0x20,
+ tcb1_cnt = 0x21,
+ tcb2 = 0x22,
+ tcb2_capt = 0x22,
+ tcb2_cnt = 0x23,
+ tcd0_in_a = 0x28,
+ tcd0_in_b = 0x29,
+#if defined(PIN_PA7) // not on 14-pin ones.
+ evouta_pin_pa7 = 0x8D,
+#endif
+#if defined(PIN_PC7)
+ evoutc_pin_pc7 = 0x8F,
+#endif
+ evoutd_pin_pd7 = 0x90,
+#endif // __AVR_DD__
+ };
+};
+// END MegaCorex and DxCore definitions
+
+
+// tinyAVR-2 definitions
+#elif defined(TINY_2_SERIES)
+ namespace gen {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ updi_synch = 0x1,
+ rtc_ovf = 0x6,
+ rtc_cmp = 0x7,
+ ccl0_out = 0x10,
+ ccl1_out = 0x11,
+ ccl2_out = 0x12,
+ ccl3_out = 0x13,
+ ac0_out = 0x20,
+ adc0_ready = 0x24,
+ adc0_sample = 0x25,
+ adc0_window = 0x26,
+ usart0_xck = 0x60,
+ usart1_xck = 0x61,
+ spi0_sck = 0x68,
+ tca0_ovf_lunf = 0x80,
+ tca0_hunf = 0x81,
+ tca0_cmp0 = 0x84,
+ tca0_cmp1 = 0x85,
+ tca0_cmp2 = 0x86,
+ tcb0 = 0xA0,
+ tcb0_capt = 0xA0,
+ tcb0_ovf = 0xA1,
+ tcb1 = 0xA2,
+ tcb1_capt = 0xA2,
+ tcb1_ovf = 0xA3,
+ };
+ };
+
+ namespace gen0 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ rtc_div8192 = 0x08,
+ rtc_div4096 = 0x09,
+ rtc_div2048 = 0x0A,
+ rtc_div1024 = 0x0B,
+ pin_pa0 = 0x40,
+ pin_pa1 = 0x41,
+ pin_pa2 = 0x42,
+ pin_pa3 = 0x43,
+ pin_pa4 = 0x44,
+ pin_pa5 = 0x45,
+ pin_pa6 = 0x46,
+ pin_pa7 = 0x47,
+ pin_pb0 = 0x40,
+ pin_pb1 = 0x41,
+ pin_pb2 = 0x42,
+ pin_pb3 = 0x43,
+#if defined(PIN_PB4)
+ pin_pb4 = 0x44,
+ pin_pb5 = 0x45,
+#endif
+#if defined(PIN_PB6)
+ pin_pb6 = 0x46,
+ pin_pb7 = 0x47,
+#endif
+ };
+ };
+
+ namespace gen1 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ rtc_div512 = 0x08,
+ rtc_div256 = 0x09,
+ rtc_div128 = 0x0A,
+ rtc_div64 = 0x0B,
+ pin_pa0 = 0x40,
+ pin_pa1 = 0x41,
+ pin_pa2 = 0x42,
+ pin_pa3 = 0x43,
+ pin_pa4 = 0x44,
+ pin_pa5 = 0x45,
+ pin_pa6 = 0x46,
+ pin_pa7 = 0x47,
+ pin_pb0 = 0x40,
+ pin_pb1 = 0x41,
+ pin_pb2 = 0x42,
+ pin_pb3 = 0x43,
+#if defined(PIN_PB4)
+ pin_pb4 = 0x44,
+ pin_pb5 = 0x45,
+#endif
+#if defined(PIN_PB6)
+ pin_pb6 = 0x46,
+ pin_pb7 = 0x47,
+#endif
+ };
+ };
+
+ namespace gen2 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ rtc_div8192 = 0x08,
+ rtc_div4096 = 0x09,
+ rtc_div2048 = 0x0A,
+ rtc_div1024 = 0x0B,
+#if defined(PIN_PC0)
+ pin_pc0 = 0x40,
+ pin_pc1 = 0x41,
+ pin_pc2 = 0x42,
+ pin_pc3 = 0x43,
+#endif
+#if defined(PIN_PC4)
+ pin_pc4 = 0x44,
+ pin_pc5 = 0x45,
+#endif
+ pin_pa0 = 0x40,
+ pin_pa1 = 0x41,
+ pin_pa2 = 0x42,
+ pin_pa3 = 0x43,
+ pin_pa4 = 0x44,
+ pin_pa5 = 0x45,
+ pin_pa6 = 0x46,
+ pin_pa7 = 0x47,
+ };
+ };
+
+ namespace gen3 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ rtc_div512 = 0x08,
+ rtc_div256 = 0x09,
+ rtc_div128 = 0x0A,
+ rtc_div64 = 0x0B,
+#if defined(PIN_PC0)
+ pin_pc0 = 0x40,
+ pin_pc1 = 0x41,
+ pin_pc2 = 0x42,
+ pin_pc3 = 0x43,
+#endif
+#if defined(PIN_PC4)
+ pin_pc4 = 0x44,
+ pin_pc5 = 0x45,
+#endif
+ pin_pa0 = 0x40,
+ pin_pa1 = 0x41,
+ pin_pa2 = 0x42,
+ pin_pa3 = 0x43,
+ pin_pa4 = 0x44,
+ pin_pa5 = 0x45,
+ pin_pa6 = 0x46,
+ pin_pa7 = 0x47,
+ };
+ };
+
+ namespace gen4 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ rtc_div8192 = 0x08,
+ rtc_div4096 = 0x09,
+ rtc_div2048 = 0x0A,
+ rtc_div1024 = 0x0B,
+ pin_pb0 = 0x40,
+ pin_pb1 = 0x41,
+ pin_pb2 = 0x42,
+ pin_pb3 = 0x43,
+#if defined(PIN_PB4)
+ pin_pb4 = 0x44,
+ pin_pb5 = 0x45,
+#endif
+#if defined(PIN_PB6)
+ pin_pb6 = 0x46,
+ pin_pb7 = 0x47,
+#endif
+#if defined(PIN_PC0)
+ pin_pc0 = 0x40,
+ pin_pc1 = 0x41,
+ pin_pc2 = 0x42,
+ pin_pc3 = 0x43,
+#endif
+#if defined(PIN_PC4)
+ pin_pc4 = 0x44,
+ pin_pc5 = 0x45,
+#endif
+ };
+ };
+
+ namespace gen5 {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ rtc_div512 = 0x08,
+ rtc_div256 = 0x09,
+ rtc_div128 = 0x0A,
+ rtc_div64 = 0x0B,
+ pin_pb0 = 0x40,
+ pin_pb1 = 0x41,
+ pin_pb2 = 0x42,
+ pin_pb3 = 0x43,
+#if defined(PIN_PB4)
+ pin_pb4 = 0x44,
+ pin_pb5 = 0x45,
+#endif
+#if defined(PIN_PB6)
+ pin_pb6 = 0x46,
+ pin_pb7 = 0x47,
+#endif
+#if defined(PIN_PC0)
+ pin_pc0 = 0x40,
+ pin_pc1 = 0x41,
+ pin_pc2 = 0x42,
+ pin_pc3 = 0x43,
+#endif
+#if defined(PIN_PC4)
+ pin_pc4 = 0x44,
+ pin_pc5 = 0x45,
+#endif
+ };
+ };
+
+
+ namespace user {
+ enum user_t : uint8_t {
+ ccl0_event_a = 0x00,
+ ccl0_event_b = 0x01,
+ ccl1_event_a = 0x02,
+ ccl1_event_b = 0x03,
+ ccl2_event_a = 0x04,
+ ccl2_event_b = 0x05,
+ ccl3_event_a = 0x06,
+ ccl3_event_b = 0x07,
+ adc0_start = 0x08,
+ evouta_pin_pa2 = 0x09,
+ evouta_pin_pa7 = 0x89,
+ evoutb_pin_pb2 = 0x0A,
+#if defined(PIN_PB7)
+ evoutb_pin_pb7 = 0x8A,
+#endif
+#if defined(PIN_PC2)
+ evoutc_pin_pc2 = 0x0B,
+#endif
+ usart0_irda = 0x0C,
+ usart1_irda = 0x0D,
+ tca0 = 0x0E,
+ tca0_cnt_a = 0x0E,
+ tca0_cnt_b = 0x0F,
+ tcb0 = 0x11,
+ tcb0_capt = 0x11,
+ tcb0_cnt = 0x12,
+ tcb1 = 0x13,
+ tcb1_capt = 0x13,
+ tcb1_cnt = 0x14,
+ };
+ };
+
+// tinyAVR-0/1 definitions
+#elif defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ namespace gen0 {
+ enum generator_t : uint8_t {
+#if defined(PIN_PC0)
+ pin_pc0 = 0x07,
+ pin_pc1 = 0x08,
+ pin_pc2 = 0x09,
+ pin_pc3 = 0x0A,
+#endif
+#if defined(PIN_PC4)
+ pin_pc4 = 0x0B,
+ pin_pc5 = 0x0C,
+#endif
+ pin_pa0 = 0x0D,
+ pin_pa1 = 0x0E,
+ pin_pa2 = 0x0F,
+ pin_pa3 = 0x10,
+ pin_pa4 = 0x11,
+ pin_pa5 = 0x12,
+ pin_pa6 = 0x13,
+ pin_pa7 = 0x14,
+#if (PROGMEM_SIZE > 8192 && defined(TINY_1_SERIES))
+ tcb1 = 0x15,
+ tcb1_capt = 0x15,
+#endif
+ };
+ };
+ namespace gen2 {
+ enum generator_t : uint8_t {
+ pin_pa0 = 0x0A,
+ pin_pa1 = 0x0B,
+ pin_pa2 = 0x0C,
+ pin_pa3 = 0x0D,
+ pin_pa4 = 0x0E,
+ pin_pa5 = 0x0F,
+ pin_pa6 = 0x10,
+ pin_pa7 = 0x11,
+ updi = 0x12,
+#if (PROGMEM_SIZE > 8192 && defined(TINY_1_SERIES))
+ ac1_out = 0x13,
+ ac2_out = 0x14,
+#endif
+ };
+ };
+
+// Only on parts with > 8 pins does this have any unique options
+#if defined(__AVR_ATtinyxy4__) || defined(__AVR_ATtinyxy6__) || defined(__AVR_ATtinyxy7__)
+ namespace gen3 {
+ enum generator_t : uint8_t {
+ pin_pb0 = 0x0A,
+ pin_pb1 = 0x0B,
+ pin_pb2 = 0x0C,
+ pin_pb3 = 0x0D,
+#if defined(PIN_PB4)
+ pin_pb4 = 0x0E,
+ pin_pb5 = 0x0F,
+#endif
+#if defined(PIN_PB6)
+ pin_pb6 = 0x10,
+ pin_pb7 = 0x11,
+#endif
+#if (PROGMEM_SIZE > 8192 && MEGATINYCORE_SERIES == 1)
+ ac1_out = 0x12,
+ ac2_out = 0x13,
+#endif
+ };
+ };
+#endif
+
+#if defined(TINY_1_SERIES)
+
+#if defined(__AVR_ATtinyxy4__) || defined(__AVR_ATtinyxy6__) || defined(__AVR_ATtinyxy7__)
+ // Only 1-series parts have second sync channel.
+ // Only on parts with > 8 pins does it have any unique options
+ namespace gen1 {
+ enum generator_t : uint8_t {
+ pin_pb0 = 0x08,
+ pin_pb1 = 0x09,
+ pin_pb2 = 0x0A,
+ pin_pb3 = 0x0B,
+#if defined(PIN_PB0)
+ pin_pb4 = 0x0C,
+ pin_pb5 = 0x0D,
+#endif
+#if defined(PIN_PB6)
+ pin_pb6 = 0x0E,
+ pin_pb7 = 0x0F,
+#endif
+#if (PROGMEM_SIZE > 8192) // Only 16/32k 1-series, but only 1-series is here
+ tcb1 = 0x10,
+ tcb1_capt = 0x10,
+#endif
+ };
+ };
+#endif
+
+ // Only 1-series parts have third and fourth async sync channel.
+ // and only parts with 20/24 pins, or the 1614 have any items on this list available
+#if !(defined(__AVR_ATtinyxy2__) || (defined(__AVR_ATtinyxy4__) && PROGMEM_SIZE <= 8192))
+ namespace gen4 {
+ enum generator_t : uint8_t {
+#if defined(PIN_PC0)
+ pin_pc0 = 0x0A,
+ pin_pc1 = 0x0B,
+ pin_pc2 = 0x0C,
+ pin_pc3 = 0x0D,
+#endif
+#if defined(PIN_PC4)
+ pin_pc4 = 0x0E,
+ pin_pc5 = 0x0F,
+#endif
+#if (PROGMEM_SIZE > 8192) // Only 16/32k 1-series, but only 1-series is here
+ ac1_out = 0x10,
+ ac2_out = 0x11,
+#endif
+ };
+ };
+#endif
+
+ namespace gen5 {
+ enum generator_t : uint8_t {
+ rtc_div8192 = 0x0A,
+ rtc_div4096 = 0x0B,
+ rtc_div2048 = 0x0C,
+ rtc_div1024 = 0x0D,
+ rtc_div512 = 0x0E,
+ rtc_div256 = 0x0F,
+ rtc_div128 = 0x10,
+ rtc_div64 = 0x11,
+#if (PROGMEM_SIZE > 8192) // Only 16/32k 1-series
+ ac1_out = 0x12,
+ ac2_out = 0x13,
+#endif
+ };
+ };
+#endif // end of 1-series only part.
+
+ namespace gens {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ tcb0 = 0x01,
+ tcb0_capt = 0x01,
+ tca0_ovf_lunf = 0x02,
+ tca0_hunf = 0x03,
+ tca0_cmp0 = 0x04,
+ tca0_cmp1 = 0x05,
+ tca0_cmp2 = 0x06,
+ };
+ };
+
+ namespace gen {
+ enum generator_t : uint8_t {
+ disable = 0x00,
+ off = 0x00,
+ ccl_lut0 = 0x01,
+ ccl_lut1 = 0x02,
+ ac0_out = 0x03,
+#if defined(TINY_1_SERIES)
+ tcd0_cmpbclr = 0x04,
+ tcd0_cmpaset = 0x05,
+ tcd0_cmpbset = 0x06,
+ tcd0_progev = 0x07,
+#endif
+ rtc_ovf = 0x08,
+ rtc_cmp = 0x09,
+ };
+ };
+
+ namespace user {
+ enum user_t : uint8_t {
+ tcb0 = 0x00,
+ tcb0_capt = 0x00,
+ adc0_start = 0x01,
+ ccl0_event_a = 0x02,
+ ccl1_event_a = 0x03,
+ ccl0_event_b = 0x04,
+ ccl1_event_b = 0x05,
+ tcd0_in_a = 0x06,
+ tcd0_in_b = 0x07,
+ evouta_pin_pa2 = 0x08,
+ evoutb_pin_pb2 = 0x09,
+ evoutc_pin_pc2 = 0x0A,
+ tcb1 = 0x0B,
+ tcb1_capt = 0x0B,
+ adc1_start = 0x0c,
+ tca0 = 0x10,
+ tca0_cnt_a = 0x10,
+ usart0_irda = 0x11,
+ };
+ };
+#endif // TINY_0_SERIES || TINY_1_SERIES
+};
+
+// Legacy definitions
+namespace user { using namespace event::user; };
+namespace gen { using namespace event::gen; };
+#if defined(EVSYS_CHANNEL0)
+namespace gen0 { using namespace event::gen0; };
+#endif
+#if defined(EVSYS_CHANNEL1)
+namespace gen1 { using namespace event::gen1; };
+#endif
+#if defined(EVSYS_CHANNEL2)
+namespace gen2 { using namespace event::gen2; };
+#endif
+#if defined(EVSYS_CHANNEL3)
+namespace gen3 { using namespace event::gen3; };
+#endif
+#if defined(EVSYS_CHANNEL4)
+namespace gen4 { using namespace event::gen4; };
+#endif
+#if defined(EVSYS_CHANNEL5)
+namespace gen5 { using namespace event::gen5; };
+#endif
+#if defined(EVSYS_CHANNEL6)
+namespace gen6 { using namespace event::gen6; };
+#endif
+#if defined(EVSYS_CHANNEL7)
+namespace gen7 { using namespace event::gen7; };
+#endif
+#if defined(EVSYS_CHANNEL8)
+namespace gen8 { using namespace event::gen8; };
+#endif
+#if defined(EVSYS_CHANNEL9)
+namespace gen9 { using namespace event::gen9; };
+#endif
+#if defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+namespace gens { using namespace event::gens; };
+#endif
+
+class Event {
+ public:
+ Event(uint8_t channel_num, volatile uint8_t &channel_addr);
+ uint8_t get_channel_number();
+ static Event& get_channel(uint8_t channel_number);
+ static Event& get_generator_channel(event::gen::generator_t generator);
+ static Event& get_generator_channel(uint8_t generator_pin);
+ uint8_t get_generator();
+ void set_generator(event::gen::generator_t generator);
+ static Event& assign_generator(event::gen::generator_t event_generator);
+ void set_generator(uint8_t pin_number);
+ static Event& assign_generator_pin(uint8_t port, uint8_t port_pin);
+ static Event& assign_generator_pin(uint8_t pin_number);
+ static int8_t get_user_channel_number(event::user::user_t event_user);
+ static Event& get_user_channel(event::user::user_t event_user);
+ void set_user(event::user::user_t event_user);
+ int8_t set_user_pin(uint8_t pin_number);
+ static void clear_user(event::user::user_t event_user);
+ void soft_event();
+ void long_soft_event(uint8_t length);
+ // event_types: They start from 0x00 for inputs, outputs start at 0x40
+ static event::gen::generator_t gen_from_peripheral(AC_t& comp);
+ static event::gen::generator_t gen_from_peripheral(CCL_t& logic, uint8_t event_type = 0);
+ static event::user::user_t user_from_peripheral(CCL_t& logic, uint8_t user_type = 0);
+ static event::gen::generator_t gen_from_peripheral(TCA_t& timer, uint8_t event_type = 0);
+ static event::user::user_t user_from_peripheral(TCA_t& timer, uint8_t user_type = 0);
+ static event::gen::generator_t gen_from_peripheral(TCB_t& timer, uint8_t event_type = 0);
+ static event::user::user_t user_from_peripheral(TCB_t& timer, uint8_t user_type = 0);
+ static event::user::user_t user_from_peripheral(USART_t& usart);
+ void start(bool state = true);
+ void stop();
+
+ #if defined(EVSYS_CHANNEL0)
+ void get_generator_channel(event::gen0::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen0::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL1)
+ void get_generator_channel(event::gen1::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen1::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL2)
+ void get_generator_channel(event::gen2::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen2::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL3)
+ void get_generator_channel(event::gen3::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen3::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL4)
+ void get_generator_channel(event::gen4::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen4::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL5)
+ void get_generator_channel(event::gen5::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen5::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL6)
+ void get_generator_channel(event::gen6::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen6::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL7)
+ void get_generator_channel(event::gen7::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen7::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL8)
+ void get_generator_channel(event::gen8::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen8::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(EVSYS_CHANNEL9)
+ void get_generator_channel(event::gen9::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen9::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+ #if defined(TINY_0_SERIES) || defined(TINY_1_SERIES)
+ void get_generator_channel(event::gens::generator_t generator) { get_generator_channel((event::gen::generator_t)generator); }
+ void set_generator(event::gen::generator_t generator) { set_generator((event::gen::generator_t)generator); }
+ #endif
+
+ private:
+ const uint8_t channel_number; // Holds the event generator channel number
+ volatile uint8_t &channel_address; // Reference to the event channel address
+ uint8_t generator_type; // Generator type the event channel is using
+};
+
+#if defined(MEGACOREX) || defined(DXCORE) || defined(TINY_2_SERIES)
+ #if defined(EVSYS_CHANNEL0)
+ extern Event Event0;
+ #endif
+ #if defined(EVSYS_CHANNEL1)
+ extern Event Event1;
+ #endif
+ #if defined(EVSYS_CHANNEL2)
+ extern Event Event2;
+ #endif
+ #if defined(EVSYS_CHANNEL3)
+ extern Event Event3;
+ #endif
+ #if defined(EVSYS_CHANNEL4)
+ extern Event Event4;
+ #endif
+ #if defined(EVSYS_CHANNEL5)
+ extern Event Event5;
+ #endif
+ #if defined(EVSYS_CHANNEL6)
+ extern Event Event6;
+ #endif
+ #if defined(EVSYS_CHANNEL7)
+ extern Event Event7;
+ #endif
+ #if defined(EVSYS_CHANNEL8)
+ extern Event Event8;
+ #endif
+ #if defined(EVSYS_CHANNEL9)
+ extern Event Event9;
+ #endif
+
+// tinyAVR-0/1
+#else
+#if defined(EVSYS_SYNCCH0)
+ extern Event Event0;
+ #define EventSync0 Event0
+ #define EVSYS_CHANNEL0 EVSYS_SYNCCH0
+#endif
+#if defined(EVSYS_SYNCCH1)
+ extern Event Event1;
+ #define EventSync1 Event1
+ #define EVSYS_CHANNEL1 EVSYS_SYNCCH1
+#endif
+#if defined(EVSYS_ASYNCCH0)
+ extern Event Event2;
+ #define EventAsync0 Event2
+ #define EVSYS_CHANNEL2 EVSYS_ASYNCCH0
+#endif
+#if defined(EVSYS_ASYNCCH1)
+ extern Event Event3;
+ #define EventAsync1 Event3
+ #define EVSYS_CHANNEL3 EVSYS_ASYNCCH1
+#endif
+#if defined(EVSYS_ASYNCCH2)
+ extern Event Event4;
+ #define EventAsync2 Event4
+ #define EVSYS_CHANNEL4 EVSYS_ASYNCCH2
+#endif
+#if defined(EVSYS_ASYNCCH3)
+ extern Event Event5;
+ #define EventAsync3 Event5
+ #define EVSYS_CHANNEL5 EVSYS_ASYNCCH3
+#endif
+#if defined(EVSYS_SYNCUSER0)
+ #define EVSYS_USERTCA0CNTA EVSYS_SYNCUSER0
+#endif
+#if defined(EVSYS_SYNCUSER1)
+ #define EVSYS_USERUSART0IRDA EVSYS_SYNCUSER1
+#endif
+#if defined(EVSYS_ASYNCUSER0)
+ #define EVSYS_USERTCB0CAPT EVSYS_ASYNCUSER0
+#endif
+#if defined(EVSYS_ASYNCUSER1)
+ #define EVSYS_USERADC0START EVSYS_ASYNCUSER1
+#endif
+#if defined(EVSYS_ASYNCUSER2)
+ #define EVSYS_USERCCLLUT0A EVSYS_ASYNCUSER2
+#endif
+#if defined(EVSYS_ASYNCUSER3)
+ #define EVSYS_USERCCLLUT1A EVSYS_ASYNCUSER3
+#endif
+#if defined(EVSYS_ASYNCUSER4)
+ #define EVSYS_USERCCLLUT0B EVSYS_ASYNCUSER4
+#endif
+#if defined(EVSYS_ASYNCUSER5)
+ #define EVSYS_USERCCLLUT1B EVSYS_ASYNCUSER5
+#endif
+#if defined(EVSYS_ASYNCUSER6)
+ #define EVSYS_USERTCD0INPUTA EVSYS_ASYNCUSER6
+#endif
+#if defined(EVSYS_ASYNCUSER7)
+ #define EVSYS_USERTCD0INPUTB EVSYS_ASYNCUSER7
+#endif
+#if defined(EVSYS_ASYNCUSER8)
+ #define EVSYS_USEREVSYSEVOUTA EVSYS_ASYNCUSER8
+#endif
+#if defined(EVSYS_ASYNCUSER9)
+ #define EVSYS_USEREVSYSEVOUTB EVSYS_ASYNCUSER9
+#endif
+#if defined(EVSYS_ASYNCUSER10)
+ #define EVSYS_USEREVSYSEVOUTC EVSYS_ASYNCUSER10
+#endif
+#if defined(EVSYS_ASYNCUSER11)
+ #define EVSYS_USERTCB1CAPT EVSYS_ASYNCUSER11
+#endif
+#if defined(EVSYS_ASYNCUSER12)
+ #define EVSYS_USERADC1START EVSYS_ASYNCUSER12
+#endif
+#endif // tinyAVR-0/1
+
+#endif // EVENT_H
diff --git a/megaavr/libraries/HID/library.properties b/megaavr/libraries/HID/library.properties
deleted file mode 100644
index 499286d..0000000
--- a/megaavr/libraries/HID/library.properties
+++ /dev/null
@@ -1,9 +0,0 @@
-name=HID
-version=1.0
-author=Arduino
-maintainer=Arduino
-sentence=Module for PluggableUSB infrastructure. Exposes an API for devices like Keyboards, Mice and Gamepads.
-paragraph=
-category=Communication
-url=http://www.arduino.cc/en/Reference/HID
-architectures=megaavr
diff --git a/megaavr/libraries/HID/src/HID.cpp b/megaavr/libraries/HID/src/HID.cpp
deleted file mode 100644
index 21ede26..0000000
--- a/megaavr/libraries/HID/src/HID.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- Copyright (c) 2015, Arduino LLC
- Original code (pre-library): Copyright (c) 2011, Peter Barrett
-
- Permission to use, copy, modify, and/or distribute this software for
- any purpose with or without fee is hereby granted, provided that the
- above copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
- BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
- OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- */
-
-#include "HID.h"
-
-#if defined(USBCON)
-
-HID_& HID()
-{
- static HID_ obj;
- return obj;
-}
-
-int HID_::getInterface(uint8_t* interfaceCount)
-{
- *interfaceCount += 1; // uses 1
- HIDDescriptor hidInterface = {
- D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE),
- D_HIDREPORT(descriptorSize),
- D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, USB_EP_SIZE, 0x01)
- };
- return USB_SendControl(0, &hidInterface, sizeof(hidInterface));
-}
-
-int HID_::getDescriptor(USBSetup& setup)
-{
- // Check if this is a HID Class Descriptor request
- if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; }
- if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; }
-
- // In a HID Class Descriptor wIndex cointains the interface number
- if (setup.wIndex != pluggedInterface) { return 0; }
-
- int total = 0;
- HIDSubDescriptor* node;
- for (node = rootNode; node; node = node->next) {
- int res = USB_SendControl(TRANSFER_PGM, node->data, node->length);
- if (res == -1)
- return -1;
- total += res;
- }
-
- // Reset the protocol on reenumeration. Normally the host should not assume the state of the protocol
- // due to the USB specs, but Windows and Linux just assumes its in report mode.
- protocol = HID_REPORT_PROTOCOL;
-
- return total;
-}
-
-uint8_t HID_::getShortName(char *name)
-{
- name[0] = 'H';
- name[1] = 'I';
- name[2] = 'D';
- name[3] = 'A' + (descriptorSize & 0x0F);
- name[4] = 'A' + ((descriptorSize >> 4) & 0x0F);
- return 5;
-}
-
-void HID_::AppendDescriptor(HIDSubDescriptor *node)
-{
- if (!rootNode) {
- rootNode = node;
- } else {
- HIDSubDescriptor *current = rootNode;
- while (current->next) {
- current = current->next;
- }
- current->next = node;
- }
- descriptorSize += node->length;
-}
-
-int HID_::SendReport(uint8_t id, const void* data, int len)
-{
- auto ret = USB_Send(pluggedEndpoint, &id, 1);
- if (ret < 0) return ret;
- auto ret2 = USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, len);
- if (ret2 < 0) return ret2;
- return ret + ret2;
-}
-
-bool HID_::setup(USBSetup& setup)
-{
- if (pluggedInterface != setup.wIndex) {
- return false;
- }
-
- uint8_t request = setup.bRequest;
- uint8_t requestType = setup.bmRequestType;
-
- if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE)
- {
- if (request == HID_GET_REPORT) {
- // TODO: HID_GetReport();
- return true;
- }
- if (request == HID_GET_PROTOCOL) {
- // TODO: Send8(protocol);
- return true;
- }
- if (request == HID_GET_IDLE) {
- // TODO: Send8(idle);
- }
- }
-
- if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE)
- {
- if (request == HID_SET_PROTOCOL) {
- // The USB Host tells us if we are in boot or report mode.
- // This only works with a real boot compatible device.
- protocol = setup.wValueL;
- return true;
- }
- if (request == HID_SET_IDLE) {
- idle = setup.wValueL;
- return true;
- }
- if (request == HID_SET_REPORT)
- {
- //uint8_t reportID = setup.wValueL;
- //uint16_t length = setup.wLength;
- //uint8_t data[length];
- // Make sure to not read more data than USB_EP_SIZE.
- // You can read multiple times through a loop.
- // The first byte (may!) contain the reportID on a multreport.
- //USB_RecvControl(data, length);
- }
- }
-
- return false;
-}
-
-HID_::HID_(void) : PluggableUSBModule(1, 1, epType),
- rootNode(NULL), descriptorSize(0),
- protocol(HID_REPORT_PROTOCOL), idle(1)
-{
- epType[0] = EP_TYPE_INTERRUPT_IN;
- PluggableUSB().plug(this);
-}
-
-int HID_::begin(void)
-{
- return 0;
-}
-
-#endif /* if defined(USBCON) */
diff --git a/megaavr/libraries/HID/src/HID.h b/megaavr/libraries/HID/src/HID.h
deleted file mode 100644
index ad2b06b..0000000
--- a/megaavr/libraries/HID/src/HID.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- Copyright (c) 2015, Arduino LLC
- Original code (pre-library): Copyright (c) 2011, Peter Barrett
-
- Permission to use, copy, modify, and/or distribute this software for
- any purpose with or without fee is hereby granted, provided that the
- above copyright notice and this permission notice appear in all copies.
-
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
- BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
- OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- SOFTWARE.
- */
-
-#ifndef HID_h
-#define HID_h
-
-#include
-#include
-#include "api/PluggableUSB.h"
-
-#if defined(USBCON)
-
-#define _USING_HID
-
-// HID 'Driver'
-// ------------
-#define HID_GET_REPORT 0x01
-#define HID_GET_IDLE 0x02
-#define HID_GET_PROTOCOL 0x03
-#define HID_SET_REPORT 0x09
-#define HID_SET_IDLE 0x0A
-#define HID_SET_PROTOCOL 0x0B
-
-#define HID_HID_DESCRIPTOR_TYPE 0x21
-#define HID_REPORT_DESCRIPTOR_TYPE 0x22
-#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23
-
-// HID subclass HID1.11 Page 8 4.2 Subclass
-#define HID_SUBCLASS_NONE 0
-#define HID_SUBCLASS_BOOT_INTERFACE 1
-
-// HID Keyboard/Mouse bios compatible protocols HID1.11 Page 9 4.3 Protocols
-#define HID_PROTOCOL_NONE 0
-#define HID_PROTOCOL_KEYBOARD 1
-#define HID_PROTOCOL_MOUSE 2
-
-// Normal or bios protocol (Keyboard/Mouse) HID1.11 Page 54 7.2.5 Get_Protocol Request
-// "protocol" variable is used for this purpose.
-#define HID_BOOT_PROTOCOL 0
-#define HID_REPORT_PROTOCOL 1
-
-// HID Request Type HID1.11 Page 51 7.2.1 Get_Report Request
-#define HID_REPORT_TYPE_INPUT 1
-#define HID_REPORT_TYPE_OUTPUT 2
-#define HID_REPORT_TYPE_FEATURE 3
-
-typedef struct
-{
- uint8_t len; // 9
- uint8_t dtype; // 0x21
- uint8_t addr;
- uint8_t versionL; // 0x101
- uint8_t versionH; // 0x101
- uint8_t country;
- uint8_t desctype; // 0x22 report
- uint8_t descLenL;
- uint8_t descLenH;
-} HIDDescDescriptor;
-
-typedef struct
-{
- InterfaceDescriptor hid;
- HIDDescDescriptor desc;
- EndpointDescriptor in;
-} HIDDescriptor;
-
-class HIDSubDescriptor {
-public:
- HIDSubDescriptor *next = NULL;
- HIDSubDescriptor(const void *d, const uint16_t l) : data(d), length(l) { }
-
- const void* data;
- const uint16_t length;
-};
-
-class HID_ : public PluggableUSBModule
-{
-public:
- HID_(void);
- int begin(void);
- int SendReport(uint8_t id, const void* data, int len);
- void AppendDescriptor(HIDSubDescriptor* node);
-
-protected:
- // Implementation of the PluggableUSBModule
- int getInterface(uint8_t* interfaceCount);
- int getDescriptor(USBSetup& setup);
- bool setup(USBSetup& setup);
- uint8_t getShortName(char* name);
-
-private:
- unsigned int epType[1];
-
- HIDSubDescriptor* rootNode;
- uint16_t descriptorSize;
-
- uint8_t protocol;
- uint8_t idle;
-};
-
-// Replacement for global singleton.
-// This function prevents static-initialization-order-fiasco
-// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
-HID_& HID();
-
-#define D_HIDREPORT(length) { 9, 0x21, 0x01, 0x01, 0, 1, 0x22, lowByte(length), highByte(length) }
-
-#else
-
-#error "No Native USB support available on this board"
-
-#endif // USBCON
-
-#endif // HID_h
diff --git a/megaavr/libraries/Logic/README.md b/megaavr/libraries/Logic/README.md
new file mode 100644
index 0000000..c2fc999
--- /dev/null
+++ b/megaavr/libraries/Logic/README.md
@@ -0,0 +1,284 @@
+# Logic
+A library for interfacing with the CCL (Configurable Custom Logic) peripherals of the megaAVR-0 MCUs.
+Developed by MCUdude for use with [MegaCoreX](https://github.com/MCUdude/MegaCoreX), adapted to megaAVR ATtiny parts by [Tadashi G. Takaoka](https://github.com/tgtakaoka), and to Dx-series by [Spence Konde](https://github.com/SpenceKonde).
+The library is compatible with all these parts, but this README only covers the megaAVR-0 functionality.
+The megaAVR-0 has four independent internal logic blocks that can be individually customized.
+All of the megaTiny parts have 2 blocks of CCL available. The examples included assume the use of megaTinyCore in their defines to detect the applicable part.
+More useful information about CCL can be found in the [Microchip Application Note TB3218](http://ww1.microchip.com/downloads/en/AppNotes/TB3218-Getting-Started-with-CCL-90003218A.pdf) and in the [megaAVR-0 family data sheet](http://ww1.microchip.com/downloads/en/DeviceDoc/megaAVR0-series-Family-Data-Sheet-DS40002015B.pdf), part in question.
+
+
+## Logic
+Class for interfacing with the built-in logic block (sometimes referred to as `LUT`s - "LookUp Table").
+Use the predefined objects `Logic0`, `Logic1`, `Logic2` and `Logic3`. The logic blocks are paired, each pair sharing a single sequencer and `feedback` channel.
+Additionally, each logic block is associated with a specific port, having it's input on pins 0 through 2, and it's output on pin 3 or 6. In order: `PORTA`, `PORTC`, `PORTD` and `PORTF`.
+
+These objects expose all configuration options as member variables as documented below, as well as member methods to set the applicable registers.
+
+
+### enable
+Variable for enabling or disabling a logic block.
+Accepted values:
+```c++
+true; // Enable the current logic block
+false; // Disable the current logic block
+```
+
+##### Usage
+```c++
+Logic0.enable = true; // Enable logic block 0
+```
+
+##### Default state
+`Logic0.enable` defaults to `false` if not specified in the user program.
+
+### input0..input2
+Variable for setting what mode input 0..2 on a logic block should have.
+
+Accepted values for megaAVR 0-series parts:
+
+``` c++
+logic::in::masked; // Pin not in use
+logic::in::unused; // Pin not in use
+logic::in::disable; // Pin not in use
+logic::in::feedback; // Connect output of sequencer (if used) or even-numbered logic block (n or n-1) to this input
+logic::in::link; // Connect output of logic block n+1 to this input
+logic::in::event_0; // Connect input to event a
+logic::in::event_a; // Connect input to event a
+logic::in::event_1; // Connect input to event b
+logic::in::event_b; // Connect input to event b
+logic::in::pin; // Connect input to CCL IN0, IN1, IN2 for input 0, 1, 2, do not change pinMode
+logic::in::input_pullup; // Connect input to CCL IN0, IN1, IN2 for input 0, 1, 2, set input, pullup on
+logic::in::input; // Connect input to CCL IN0, IN1, IN2 for input 0, 1, 2, set input, pullup off
+logic::in::input_no_pullup; // Connect input to CCL IN0, IN1, IN2 for input 0, 1, 2, set input, pullup off
+logic::in::ac; // Connect input to the output of the internal analog comparator (input 0,1,2 from AC0,1,2)
+logic::in::uart; // Connect input to UART TX. Input 0 connects to UART0 TX, input 1 to UART1 TX, and input 2 to UART2 TX
+logic::in::spi; // Connect input to SPI. Input 0 and 1 connects to MOSI, and input 2 connects to SCK
+logic::in::tca0; // Connect input to TCA0. Input 0 connects to WO0, input 1 to WO1 and input2 to WO2
+logic::in::tca; // Connect input to TCA0. Input 0 connects to WO0, input 1 to WO1 and input2 to WO2
+logic::in::tcb; // Connect input to TCB. Input 0 connects to TCB0 W0, input 1 to TCB1 WO, and input 2 to TCB2 WO.
+```
+
+Notes specific to ATmega parts
+* On 28-pin versions of the ATmega 4808, 3208, 1608, and 808, IN1 and IN2 inputs for logic3 are not available. If all input pins for all logic blocks are needed, the event system can be used.
+* According to the datasheet for SPI as input source, inputs 0 and 1 connect to MOSI. Thus, on these parts, there is no input to the logic blocks for MISO.
+* If input on the highest-number Logic block is set to link, it will use the output of Logic0
+* If you need to link input to logic block other than the n+1 block, you can use the event system for that.
+
+
+##### Usage
+``` c++
+Logic0.input0 = logic::in::link; // Connect output from block 1 to input 0 of block 0
+Logic0.input1 = logic::in::input; // Connect the input 1 from block 0 to its GPIO
+Logic0.input2 = logic::in::input_pullup; // Connect the input 2 from block 0 to its GPIO, with pullup on
+```
+
+##### Default state
+`LogicN.inputN` defaults to `logic::in::unused` if not specified in the user program.
+
+
+### output
+Variable for changing the logic block output pin behavior. Note that the output of the logic block still can be used internally if the output pin is disabled.
+Accepted values:
+```c++
+logic::out::disable; // Disable the output GPIO pin. Useful when triggering an interrupt instead.
+logic::out::enable; // Enable the output GPIO pin
+```
+
+##### Usage
+```c++
+Logic0.output = logic::out::disable; // Disable the output GPIO pin.
+```
+
+##### Default state
+`LogicN.output` defaults to `logic::out::disable` if not specified in the user program.
+
+
+### output_swap
+Variable for pin swapping the physical output pin to its alternative position. See the pinout diagrams in the main MegaCoreX README for detailed info.
+Accepted values:
+```c++
+logic::out::no_swap; // Use default pin position, pin 3 on the port
+logic::out::pin_swap; // Use alternative position, pin 6 on the port
+```
+
+##### Usage
+```c++
+Logic0.output_swap = logic::out::no_swap; // No pin swap for output of block0
+```
+
+##### Default state
+`LogicN.output_swap` defaults to `logic::out::no_swap` if not specified in the user program.
+
+
+### filter
+Variable to control whether the output passes through a synchronizer or filter.
+Useful when multiple logic blocks are connected internally to prevent race conditions and glitches that could arise due to the asynchronous nature of CCL clocking.
+Alternately, the delay itself may be desirable, or it can be combined with a configuration which would oscillate asynchronously to instead output a prescaled clock, which could, in turn, be used with "clock on event" to provide a type B timer with a prescaled clock.
+Either filter or synchronizer is required for edge detector, below.
+Accepted values:
+```c++
+logic::filter::disable; // No filter used, asynchronous output.
+logic::filter::synchronizer; // Connect synchronizer to output; delays output by 2 clock cycles.
+logic::filter::synch; // Syntactic sugar for synchronizer
+logic::filter::sync; // Syntactic sugar for synchronizer
+logic::filter::filter; // Connect filter to output; delays output by 4 clock cycles, only passes output that is stable for >2 clock cycles.
+```
+
+##### Usage
+```c++
+Logic0.filter = logic::filter::filter; // Enable filter on output of block 0
+```
+
+##### Default state
+`LogicN.filter` defaults to `logic::filter::disable` if not specified in the user program.
+
+
+### clocksource
+Variable to set the clock source for the logic block; this is used for the synchronizer and filter only (otherwise, the logic blocks are asynchronous).
+If sequential logic is used, it is clocked from the clock source used by the even-numbered logic block.
+Accepted values:
+```c++
+logic::clocksource::clk_per; // Clock from the peripheral clock (ie, system clock)
+logic::clocksource::in2; // Clock from the selected input2; it is treated as a 0 in the truth table.
+```
+
+##### Usage
+```c++
+Logic0.clocksource = logic::clocksource::clk_per;
+```
+
+##### Default state
+`LogicN.clocksource` defaults to `logic::clocksource::clk_per` if not specified in the user program.
+
+
+### edgedetect
+Variable for controlling use of the edge detector. The edge detector can be used to generate a pulse when detecting a rising edge on its input. To detect a falling edge, the TRUTH table should be programmed to provide inverted output. In order to avoid unpredictable behavior, a valid filter option must be enabled. Note that this is likely only of use when the output is being used for sequential logic or as the input to another logic block; it looks particularly useful on the odd LUT input to a J-K flip-flop sequential logic unit.
+
+```c++
+logic::edgedetect::disable; // No edge detection used
+logic::edgedetect::enable; // Edge detection used
+```
+
+#### Usage
+```c++
+Logic0.edgedetect = logic::edgedetect::enable;
+```
+
+##### Default state
+`LogicN.edgedetect` defaults to `logic::edgedetect::disable` if not specified in the user program.
+
+
+### sequencer
+Variable for connecting a "sequencer" to the logic block output - these are latches or flip-flops which remember a state. There is 1 sequencer per 2 CCLs, each controls one of the two inputs to a flip flop or latch; this option is ignored for the odd-numbered logic blocks. Flip-flops are clocked from the same clock source as the even logic block, latches are asynchronous.
+
+Accepted values:
+```c++
+logic::sequencer::disable; // No sequencer connected
+logic::sequencer::d_flip_flop; // D flip flop sequencer connected
+logic::sequencer::jk_flip_flop; // JK flip flop sequencer connected
+logic::sequencer::d_latch; // Gated D latch sequencer connected - note that on most megaAVR parts, this doesn't work. See the Errata.
+logic::sequencer::rs_latch; // RS latch sequencer connected
+```
+
+##### Usage
+```c++
+Logic0.sequencer = logic::sequencer::disable; // Disable sequencer
+```
+
+##### Default state
+`LogicN.sequencer` defaults to `logic::sequencer::disable` if not specified in the user program.
+
+
+### truth
+Variable to hold the 8-bit truth table value.
+Accepted values between 0x00 and 0xFF.
+
+##### Usage
+```c++
+Logic0.truth = 0xF0;
+```
+
+##### Default state
+`LogicN.truth` defaults to `0x00` if not specified in the user program.
+
+
+
+## init()
+Method for initializing a logic block; the settings you have previously configured will be applied and pins configured as requested at this time only.
+
+##### Usage
+```c++
+Logic0.init(); // Initialize block 0
+Logic1.init(); // Initialize block 1
+```
+
+
+## start()
+Method for starting the CCL hardware after desired blocks have been initialized using `LogicN.init()`.
+
+##### Usage
+```c++
+Logic::start(); // Start CCL hardware
+```
+
+
+## stop()
+Method for stopping the CCL hardware, for example to reconfigure the logic blocks.
+
+##### Usage
+```c++
+Logic::stop(); // Stop CCL
+```
+
+## Reconfiguring
+There are TWO levels of "enable protection" on the CCL hardware. According to the Silicon Errata, only one of these is intended.
+As always, it's anyone's guess when or if this issue will be corrected in a future silicon revision.
+The intended enable-protection is that a given logic block cannot be reconfigured while enabled.
+This is handled by `init()` - you can write your new setting to a logic block, call `LogicN.init()` and it will briefly disable the logic block, make the changes, and reenable it.
+
+The unintended layer is that no logic block can be reconfigured without also disabling the whole CCL system.
+Changes can be freely made to the `Logic` classes, however, only the `init()` method will apply those changes, and you must call `Logic::stop()` before calling them, and `Logic::start()` afterwards.
+
+##### Example
+```c++
+// logic blocks 0, 1 configured, initialized, and in use
+Logic1.truth=0x55; // new truth table
+Logic1.input2=logic::in::tca0; // and different input 2
+Logic3.enabled=true; // enable another LUT
+Logic3.input0=logic::in::link; // Use link from LUT0
+Logic3.input1=logic::in::ac; // and the analog comparator
+Logic3.input2=logic::in::pin; // and the LUT3 IN2 pin
+Logic3.truth=0x79; // truth table for LUT3
+
+Logic3.attachInterrupt(RISING,interruptFunction);
+
+// Interrupt now attached - but - Logic3 not enabled, and logic1 is using old settings
+
+Logic::stop(); // have to turn off Logic0 too, even though I might not want to
+Logic1.init(); // apply changes to logic block 1
+Logic3.init(); // apply settings to logic block 3 for the first time
+Logic::start(); // reenable
+```
+
+## attachInterrupt()
+Method for enabling interrupts for a specific block.
+Valid arguments for the third parameters are `RISING`, `FALLING` and `CHANGE`.
+
+##### Usage
+```c++
+Logic0.attachInterrupt(blinkLED, RISING); // Runthe blinkLED function when the putput goes high
+
+void blinkLED()
+{
+ digitalWrite(myLedPin, CHANGE);
+}
+```
+
+
+## detachInterrupt()
+Method for disabling interrupts for a specific block.
+
+##### Usage
+```c++
+Logic0.detachInterrupt(); // Disable interrupts for block 0
+```
diff --git a/megaavr/libraries/Logic/examples/Five_input_NOR/Five_input_NOR.ino b/megaavr/libraries/Logic/examples/Five_input_NOR/Five_input_NOR.ino
new file mode 100644
index 0000000..71fd7ef
--- /dev/null
+++ b/megaavr/libraries/Logic/examples/Five_input_NOR/Five_input_NOR.ino
@@ -0,0 +1,56 @@
+/***********************************************************************|
+| megaAVR Configurable Custom Logic library |
+| |
+| Five_input_NOR.ino |
+| |
+| A library for interfacing with the megaAVR Configurable Custom Logic. |
+| Developed in 2019 by MCUdude. |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use two logic blocks to get five inputs. |
+| The output of block 1 is connected to one of the inputs of block 0. |
+| With the correct truth tables values we can make the output of |
+| block 0 go high when all inputs are low. |
+| |
+| See Microchip's application note TB3218 for more information. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Initialize logic block 1
+ // Logic block 1 has three inputs, PC0, PC1 and PC2.
+ // It's output, PC3 is disabled because we connect the output signal to block 0 internally
+ Logic1.enable = true; // Enable logic block 1
+ Logic1.input0 = logic::in::input_pullup; // Set PC0 as input with pullup
+ Logic1.input1 = logic::in::input_pullup; // Set PC1 as input with pullup
+ Logic1.input2 = logic::in::input_pullup; // Set PC2 as input with pullup
+ Logic1.output = logic::out::disable; // No output on PC3
+ Logic1.filter = logic::filter::disable; // No output filter enabled
+ Logic1.truth = 0xFE; // Set truth table
+
+ // Initialize logic block 0
+ // Logic block 0 has three inputs, PA0, PA1 and PA2.
+ // input2 is internally connected to the output of block1 (which means PA2 is freed up)
+ // Block 0 output on PA3
+ Logic0.enable = true; // Enable logic block 0
+ Logic0.input0 = logic::in::input_pullup; // Set PA0 as input with pullup
+ Logic0.input1 = logic::in::input_pullup; // Set PA1 as input with pullup
+ Logic0.input2 = logic::in::link; // Route output from block 1 to this input internally
+ Logic0.output = logic::out::enable; // Enable logic block 0 output pin (PA3)
+ Logic0.filter = logic::filter::disable; // No output filter enabled
+ Logic0.truth = 0x01; // Set truth table
+
+ // Initialize logic block 0 and 1
+ Logic0.init();
+ Logic1.init();
+
+ // Start the AVR logic hardware
+ Logic::start();
+}
+
+void loop()
+{
+ // When using configurable custom logic the CPU isn't doing anything!
+}
diff --git a/megaavr/libraries/Logic/examples/Interrupt/Interrupt.ino b/megaavr/libraries/Logic/examples/Interrupt/Interrupt.ino
new file mode 100644
index 0000000..12993ef
--- /dev/null
+++ b/megaavr/libraries/Logic/examples/Interrupt/Interrupt.ino
@@ -0,0 +1,66 @@
+/***********************************************************************|
+| megaAVR Configurable Custom Logic library |
+| |
+| Interrupt.ino |
+| |
+| A library for interfacing with the megaAVR Configurable Custom Logic. |
+| Developed in 2019 by MCUdude. |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use the configurable logic peripherals the the |
+| megaAVR to create a 3-input NOR gate using logic block 2 on PORT D. |
+| We will use input on PD0, PD1 and PD2. Instead of having an output |
+| pin the logic block will instead trigger an interrupt that runs a |
+| user defined function. |
+| |
+| 3-input NOR truth table: |
+| If we look at the truth table |PD2|PD1|PD0| Y | |
+| to the right, we can see that |---|---|---|---| |
+| all binary values for Y can | 0 | 0 | 0 | 1 | |
+| be represented as 00000001. | 0 | 0 | 1 | 0 | |
+| If we convert this 8-bit | 0 | 1 | 0 | 0 | |
+| binary number into hex, we | 0 | 1 | 1 | 0 | |
+| get 0x01. | 1 | 0 | 0 | 0 | |
+| | 1 | 0 | 1 | 0 | |
+| In this example the output is | 1 | 1 | 0 | 0 | |
+| true if all inputs are low. | 1 | 1 | 1 | 0 | |
+| |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Modify the serial port to match your hardware
+ Serial.begin(9600);
+
+ // Initialize logic block 2
+ // Logic block 2 has three inputs, PA0, PA1 and PA2.
+ // It has one output, but this is disabled because we're using an interrupt instead.
+ Logic2.enable = true; // Enable logic block 2
+ Logic2.input0 = logic::in::input_pullup; // Set PD0 as input with pullup
+ Logic2.input1 = logic::in::input_pullup; // Set PD1 as input with pullup
+ Logic2.input2 = logic::in::input_pullup; // Set PD2 as input with pullup
+ Logic2.output = logic::out::disable; // Disable output on PD3 (we don't have to though)
+ Logic2.filter = logic::filter::disable; // No output filter enabled
+ Logic2.truth = 0x01; // Set truth table
+
+ // Initialize logic block 2
+ Logic2.init();
+
+ // Set interrupt (supports RISING, FALLING and CHANGE)
+ Logic2.attachInterrupt(interruptFunction, RISING);
+
+ // Start the AVR logic hardware
+ Logic::start();
+}
+
+void loop()
+{
+ // When using configurable custom logic the CPU isn't doing anything!
+}
+
+void interruptFunction()
+{
+ Serial.println("Output of logic block 2 went high!");
+}
diff --git a/megaavr/libraries/Logic/examples/Three_input_AND/Three_input_AND.ino b/megaavr/libraries/Logic/examples/Three_input_AND/Three_input_AND.ino
new file mode 100644
index 0000000..9f74d2e
--- /dev/null
+++ b/megaavr/libraries/Logic/examples/Three_input_AND/Three_input_AND.ino
@@ -0,0 +1,56 @@
+/***********************************************************************|
+| megaAVR Configurable Custom Logic library |
+| |
+| Three_input_AND.ino |
+| |
+| A library for interfacing with the megaAVR Configurable Custom Logic. |
+| Developed in 2019 by MCUdude. |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use the configurable logic peripherals the the |
+| megaAVR to create a 3-input AND gate using logic block 0 on PORT A. |
+| The example is pretty straight forward, but the truth table value may |
+| be a little difficult to understand at first glance. |
+| Here's how 0x80 turns out to be the correct value to create a 3-input |
+| AND gate: |
+| 3-input AND truth table: |
+| If we look at the truth table |PA2|PA1|PA0| Y | |
+| to the right, we can see that |---|---|---|---| |
+| all binary values for Y can | 0 | 0 | 0 | 0 | |
+| be represented as 10000000. | 0 | 0 | 1 | 0 | |
+| If we convert this 8-bit | 0 | 1 | 0 | 0 | |
+| binary number into hex, we | 0 | 1 | 1 | 0 | |
+| get 0x80. | 1 | 0 | 0 | 0 | |
+| | 1 | 0 | 1 | 0 | |
+| In this example the output pin, | 1 | 1 | 0 | 0 | |
+| PA3 will go high if all three | 1 | 1 | 1 | 1 | |
+| inputs are high. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Initialize logic block 0
+ // Logic block 0 has three inputs, PA0, PA1 and PA2.
+ // It has one output, PA3, but can be swapped to PA6 if needed
+ Logic0.enable = true; // Enable logic block 0
+ Logic0.input0 = logic::in::input_pullup; // Set PA0 as input with pullup
+ Logic0.input1 = logic::in::input_pullup; // Set PA1 as input with pullup
+ Logic0.input2 = logic::in::input_pullup; // Set PA2 as input with pullup
+//Logic0.output_swap = logic::out::pin_swap; // Uncomment this line to route the output to PA6 instead of PA3
+ Logic0.output = logic::out::enable; // Enable logic block 0 output pin (PA3)
+ Logic0.filter = logic::filter::disable; // No output filter enabled
+ Logic0.truth = 0x80; // Set truth table
+
+ // Initialize logic block 0
+ Logic0.init();
+
+ // Start the AVR logic hardware
+ Logic::start();
+}
+
+void loop()
+{
+ // When using configurable custom logic the CPU isn't doing anything!
+}
diff --git a/megaavr/libraries/Logic/examples/Three_input_NAND/Three_input_NAND.ino b/megaavr/libraries/Logic/examples/Three_input_NAND/Three_input_NAND.ino
new file mode 100644
index 0000000..652dc2a
--- /dev/null
+++ b/megaavr/libraries/Logic/examples/Three_input_NAND/Three_input_NAND.ino
@@ -0,0 +1,56 @@
+/***********************************************************************|
+| megaAVR Configurable Custom Logic library |
+| |
+| Three_input_NAND.ino |
+| |
+| A library for interfacing with the megaAVR Configurable Custom Logic. |
+| Developed in 2019 by MCUdude. |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use the configurable logic peripherals the the |
+| megaAVR to create a 3-input NAND gate using logic block 0 on PORT A. |
+| The example is pretty straight forward, but the truth table value may |
+| be a little difficult to understand at first glance. |
+| Here's how 0x7F turns out to be the correct value to create a 3-input |
+| NAND gate: |
+| 3-input NAND truth table: |
+| If we look at the truth table |PA2|PA1|PA0| Y | |
+| to the right, we can see that |---|---|---|---| |
+| all binary values for Y can | 0 | 0 | 0 | 1 | |
+| be represented as 01111111. | 0 | 0 | 1 | 1 | |
+| If we convert this 8-bit | 0 | 1 | 0 | 1 | |
+| binary number into hex, we | 0 | 1 | 1 | 1 | |
+| get 0x7F. | 1 | 0 | 0 | 1 | |
+| | 1 | 0 | 1 | 1 | |
+| In this example the output pin | 1 | 1 | 0 | 1 | |
+| PA3 will go low if all three | 1 | 1 | 1 | 0 | |
+| inputs are high. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Initialize logic block 0
+ // Logic block 0 has three inputs, PA0, PA1 and PA2.
+ // It has one output, PA3, but can be swapped to PA6 if needed
+ Logic0.enable = true; // Enable logic block 0
+ Logic0.input0 = logic::in::input_pullup; // Set PA0 as input with pullup
+ Logic0.input1 = logic::in::input_pullup; // Set PA1 as input with pullup
+ Logic0.input2 = logic::in::input_pullup; // Set PA2 as input with pullup
+//Logic0.output_swap = logic::out::pin_swap; // Uncomment this line to route the output to PA6 instead of PA3
+ Logic0.output = logic::out::enable; // Enable logic block 0 output pin (PA3)
+ Logic0.filter = logic::filter::disable; // No output filter enabled
+ Logic0.truth = 0x7F; // Set truth table
+
+ // Initialize logic block 0
+ Logic0.init();
+
+ // Start the AVR logic hardware
+ Logic::start();
+}
+
+void loop()
+{
+ // When using configurable custom logic the CPU isn't doing anything!
+}
diff --git a/megaavr/libraries/Logic/examples/Three_input_OR/Three_input_OR.ino b/megaavr/libraries/Logic/examples/Three_input_OR/Three_input_OR.ino
new file mode 100644
index 0000000..0c9b473
--- /dev/null
+++ b/megaavr/libraries/Logic/examples/Three_input_OR/Three_input_OR.ino
@@ -0,0 +1,56 @@
+/***********************************************************************|
+| megaAVR Configurable Custom Logic library |
+| |
+| Three_input_OR.ino |
+| |
+| A library for interfacing with the megaAVR Configurable Custom Logic. |
+| Developed in 2019 by MCUdude. |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use the configurable logic peripherals the the |
+| megaAVR to create a 3-input OR gate using logic block 0 on PORT A. |
+| The example is pretty straight forward, but the truth table value may |
+| be a little difficult to understand at first glance. |
+| Here's how 0xFE turns out to be the correct value to create a 3-input |
+| OR gate: |
+| 3-input OR truth table: |
+| If we look at the truth table |PA2|PA1|PA0| Y | |
+| to the right, we can see that |---|---|---|---| |
+| all binary values for Y can | 0 | 0 | 0 | 0 | |
+| be represented as 11111110. | 0 | 0 | 1 | 1 | |
+| If we convert this 8-bit | 0 | 1 | 0 | 1 | |
+| binary number into hex, we | 0 | 1 | 1 | 1 | |
+| get 0xFE. | 1 | 0 | 0 | 1 | |
+| | 1 | 0 | 1 | 1 | |
+| In this example the output pin, | 1 | 1 | 0 | 1 | |
+| PA3 will go high if one or more | 1 | 1 | 1 | 1 | |
+| inputs are high. |
+|***********************************************************************/
+
+#include
+
+void setup()
+{
+ // Initialize logic block 0
+ // Logic block 0 has three inputs, PA0, PA1 and PA2.
+ // It has one output, PA3, but can be swapped to PA6 if needed
+ Logic0.enable = true; // Enable logic block 0
+ Logic0.input0 = logic::in::input_pullup; // Set PA0 as input with pullup
+ Logic0.input1 = logic::in::input_pullup; // Set PA1 as input with pullup
+ Logic0.input2 = logic::in::input_pullup; // Set PA2 as input with pullup
+//Logic0.output_swap = logic::out::pin_swap; // Uncomment this line to route the output to PA6 instead of PA3
+ Logic0.output = logic::out::enable; // Enable logic block 0 output pin (PA3)
+ Logic0.filter = logic::filter::disable; // No output filter enabled
+ Logic0.truth = 0xFE; // Set truth table
+
+ // Initialize logic block 0
+ Logic0.init();
+
+ // Start the AVR logic hardware
+ Logic::start();
+}
+
+void loop()
+{
+ // When using configurable custom logic the CPU isn't doing anything!
+}
diff --git a/megaavr/libraries/Logic/examples/Two_input_AND/Two_input_AND.ino b/megaavr/libraries/Logic/examples/Two_input_AND/Two_input_AND.ino
new file mode 100644
index 0000000..c7ed698
--- /dev/null
+++ b/megaavr/libraries/Logic/examples/Two_input_AND/Two_input_AND.ino
@@ -0,0 +1,57 @@
+/***********************************************************************|
+| megaAVR Configurable Custom Logic library |
+| |
+| Two_input_AND.ino |
+| |
+| A library for interfacing with the megaAVR Configurable Custom Logic. |
+| Developed in 2019 by MCUdude. |
+| https://github.com/MCUdude/ |
+| |
+| In this example we use the configurable logic peripherals the the |
+| megaAVR to create a 2-input AND gate using logic block 0 on PORT A. |
+| The example is pretty straight forward, but the truth table value may |
+| be a little difficult to understand at first glance. |
+| We will only use PA0 and PA1 as inputs. When the last input is |
+| disabled it will always be read as 0. |
+| Here's how 0x08 turns out to be the correct value to create a 2-input |
+| NAND gate: |
+| 2-input AND truth table: |
+| If we look at the truth table |PA2|PA1|PA0| Y | |
+| to the right, we can see that |---|---|---|---| |
+| all binary values for Y can | 0 | 0 | 0 | 0 | |
+| be represented as 00001000. | 0 | 0 | 1 | 0 | |
+| If we convert this 8-bit | 0 | 1 | 0 | 0 | |
+| binary number into hex, we | 0 | 1 | 1 | 1 | |
+| get 0x08. | 1 | 0 | 0 | 0 | PA2 is always 0 |
+| | 1 | 0 | 1 | 0 | PA2 is always 0 |
+| In this example the output pin, | 1 | 1 | 0 | 0 | PA2 is always 0 |
+| PA3 will only go high if the | 1 | 1 | 1 | 0 | PA2 is always 0 |
+| two input pins are high. |
+|***********************************************************************/
+
+#include