diff --git a/.github/workflows/githubci.yml b/.github/workflows/githubci.yml new file mode 100644 index 000000000..66322215c --- /dev/null +++ b/.github/workflows/githubci.yml @@ -0,0 +1,61 @@ +name: Build + +on: [pull_request, push] + +jobs: + build: + strategy: + fail-fast: false + matrix: + board: + # Alphabetical order + - 'circuitplayground_m0' + - 'feather_m4_can' + - 'hallowing' + - 'hallowing_m4' + - 'metro_m0' + - 'metro_m4' + - 'pybadge_m4' + - 'pygamer_m4' + - 'pyportal_m4' + - 'pyportal_m4_titano' + # with TinyUSB + - 'metro_m0:usbstack=tinyusb' + - 'metro_m4:speed=120,usbstack=tinyusb' + + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: 'true' + + - name: Install Arduino CLI and Tools + run: | + # make all our directories we need for files and libraries + mkdir $HOME/.arduino15 + mkdir $HOME/.arduino15/packages + mkdir $HOME/Arduino + mkdir $HOME/Arduino/libraries + curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh + echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH + + - name: Install BSP and Libraries + env: + BSP_URL: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json + BSP_PATH: .arduino15/packages/adafruit/hardware/samd + run: | + arduino-cli config init + arduino-cli core update-index + arduino-cli core update-index --additional-urls $BSP_URL + arduino-cli core install arduino:samd --additional-urls $BSP_URL + arduino-cli core install adafruit:samd --additional-urls $BSP_URL + # Replace release BSP with our code + BSP_VERSION=`eval ls $HOME/$BSP_PATH` + rm -r $HOME/$BSP_PATH/* + ln -s $GITHUB_WORKSPACE $HOME/$BSP_PATH/$BSP_VERSION + arduino-cli lib install "Adafruit NeoPixel" "Adafruit seesaw Library" "Adafruit SPIFlash" "FlashStorage" "MIDI Library" "SD" "SdFat - Adafruit Fork" + + - name: Build examples + run: python3 tools/build_all.py ${{ matrix.board }} diff --git a/.gitignore b/.gitignore index 2ad1d1f84..ef8f29944 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ *.bz2 +*.atsuo bootloaders/*/build/ +*~ +/libraries/**/build/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..8e657daeb --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "libraries/Adafruit_TinyUSB_Arduino"] + path = libraries/Adafruit_TinyUSB_Arduino + url = https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git +[submodule "libraries/Adafruit_ZeroDMA"] + path = libraries/Adafruit_ZeroDMA + url = https://github.com/adafruit/Adafruit_ZeroDMA diff --git a/README.md b/README.md index fca8a216d..8ed23e3aa 100644 --- a/README.md +++ b/README.md @@ -1,53 +1,28 @@ -# Arduino Core for SAMD21 CPU +# Arduino Core for SAMD21 and SAMD51 CPU -This repository contains the source code and configuration files of the Arduino Core -for Atmel's SAMD21 processor (used on the Arduino/Genuino Zero, MKR1000 and MKRZero boards). - -## Installation on Arduino IDE +[![Build Status](https://github.com/adafruit/ArduinoCore-samd/workflows/Build/badge.svg)](https://github.com/adafruit/ArduinoCore-samd/actions) -This core is available as a package in the Arduino IDE cores manager. -Just open the "Boards Manager" and install the package called: +This repository contains the source code and configuration files of the Arduino Core +for Atmel's SAMD21 and SAMD51 processor (used on the Arduino/Genuino Zero, MKR1000 and MKRZero boards). -"Arduino SAMD Boards (32-bit ARM Cortex-M0+)" +In particular, this adds support for the Adafruit SAMD Boards such as the Feather M0 -## Support +## Bugs or Issues -There is a dedicated section of the Arduino Forum for general discussion and project assistance: +* AREF must be tied to 3.3V for dac to work. This is a bug in the SAMD51 silicon. +* USB host mode doesn't work yet -http://forum.arduino.cc/index.php?board=98.0 +If you find a bug you can submit an issue here on github: -## Bugs or Issues +https://github.com/adafruit/ArduinoCore-samd -If you find a bug you can submit an issue here on github: +or if it is an issue with the upstream: https://github.com/arduino/ArduinoCore-samd/issues Before posting a new issue, please check if the same problem has been already reported by someone else to avoid duplicates. -## Contributions - -Contributions are always welcome. The preferred way to receive code cotribution is by submitting a -Pull Request on github. - -## Hourly builds - -This repository is under a Continuous Integration system that every hour checks if there are updates and -builds a release for testing (the so called "Hourly builds"). - -The hourly builds are available through Boards Manager. If you want to install them: - 1. Open the **Preferences** of the Arduino IDE. - 2. Add this URL `http://downloads.arduino.cc/Hourly/samd/package_samd-hourly-build_index.json` in the **Additional Boards Manager URLs** field, and click OK. - 3. Open the **Boards Manager** (menu Tools->Board->Board Manager...) - 4. Install **Arduino SAMD core - Hourly build** - 5. Select one of the boards under **SAMD Hourly build XX** in Tools->Board menu - 6. Compile/Upload as usual - -If you already installed an hourly build and you want to update it with the latest: - 1. Open the **Boards Manager** (menu Tools->Board->Board Manager...) - 2. Remove **Arduino SAMD core - Hourly build** - 3. Install again **Arduino SAMD core - Hourly build**, the Board Manager will download the latest build replacing the old one. - ## License and credits This core has been developed by Arduino LLC in collaboration with Atmel. diff --git a/boards.txt b/boards.txt index bffc5e85e..23b2fcddd 100644 --- a/boards.txt +++ b/boards.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2017 Arduino LLC. All right reserved. +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -14,475 +14,2572 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# Arduino/Genuino Zero (Prorgamming Port) -# --------------------------------------- -arduino_zero_edbg.name=Arduino/Genuino Zero (Programming Port) -arduino_zero_edbg.vid.0=0x03eb -arduino_zero_edbg.pid.0=0x2157 - -arduino_zero_edbg.upload.tool=openocd -arduino_zero_edbg.upload.protocol=sam-ba -arduino_zero_edbg.upload.maximum_size=262144 -arduino_zero_edbg.upload.use_1200bps_touch=false -arduino_zero_edbg.upload.wait_for_upload_port=false -arduino_zero_edbg.upload.native_usb=false -arduino_zero_edbg.build.mcu=cortex-m0plus -arduino_zero_edbg.build.f_cpu=48000000L -arduino_zero_edbg.build.usb_product="Arduino Zero" -arduino_zero_edbg.build.usb_manufacturer="Arduino LLC" -arduino_zero_edbg.build.board=SAMD_ZERO -arduino_zero_edbg.build.core=arduino -arduino_zero_edbg.build.extra_flags=-D__SAMD21G18A__ {build.usb_flags} -arduino_zero_edbg.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -arduino_zero_edbg.build.openocdscript=openocd_scripts/arduino_zero.cfg -arduino_zero_edbg.build.variant=arduino_zero -arduino_zero_edbg.build.variant_system_lib= -arduino_zero_edbg.build.vid=0x2341 -arduino_zero_edbg.build.pid=0x804d -arduino_zero_edbg.bootloader.tool=openocd -arduino_zero_edbg.bootloader.file=zero/samd21_sam_ba.bin - -# Arduino/Genuino Zero (Native USB Port) -# -------------------------------------- -arduino_zero_native.name=Arduino/Genuino Zero (Native USB Port) -arduino_zero_native.vid.0=0x2341 -arduino_zero_native.pid.0=0x804d -arduino_zero_native.vid.1=0x2341 -arduino_zero_native.pid.1=0x004d - -arduino_zero_native.vid.2=0x2341 -arduino_zero_native.pid.2=0x824d -# If the board is a 2341:824d use 2341:824d for build and set other parameters as well -arduino_zero_native.vid.2.build.vid=0x2341 -arduino_zero_native.vid.2.build.pid=0x824d -arduino_zero_native.vid.2.build.usb_product="Genuino Zero" -arduino_zero_native.vid.2.bootloader.file=zero/samd21_sam_ba_genuino.bin - -arduino_zero_native.vid.3=0x2341 -arduino_zero_native.pid.3=0x024d -# If the board is a 2341:024d use 2341:824d for build and set other parameters as well -arduino_zero_native.vid.3.build.vid=0x2341 -arduino_zero_native.vid.3.build.pid=0x824d -arduino_zero_native.vid.3.build.usb_product="Genuino Zero" -arduino_zero_native.vid.3.bootloader.file=zero/samd21_sam_ba_genuino.bin - -arduino_zero_native.upload.tool=bossac -arduino_zero_native.upload.protocol=sam-ba -arduino_zero_native.upload.maximum_size=262144 -arduino_zero_native.upload.use_1200bps_touch=true -arduino_zero_native.upload.wait_for_upload_port=true -arduino_zero_native.upload.native_usb=true -arduino_zero_native.build.mcu=cortex-m0plus -arduino_zero_native.build.f_cpu=48000000L -arduino_zero_native.build.usb_product="Arduino Zero" -arduino_zero_native.build.usb_manufacturer="Arduino LLC" -arduino_zero_native.build.board=SAMD_ZERO -arduino_zero_native.build.core=arduino -arduino_zero_native.build.extra_flags=-D__SAMD21G18A__ {build.usb_flags} -arduino_zero_native.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -arduino_zero_native.build.openocdscript=openocd_scripts/arduino_zero.cfg -arduino_zero_native.build.variant=arduino_zero -arduino_zero_native.build.variant_system_lib= -arduino_zero_native.build.vid=0x2341 -arduino_zero_native.build.pid=0x804d -arduino_zero_native.bootloader.tool=openocd -arduino_zero_native.bootloader.file=zero/samd21_sam_ba.bin - -# Arduino/Genuino MKR1000 -# ----------------------- -mkr1000.name=Arduino/Genuino MKR1000 -mkr1000.vid.0=0x2341 -mkr1000.pid.0=0x804e -mkr1000.vid.1=0x2341 -mkr1000.pid.1=0x004e - -mkr1000.vid.2=0x2341 -mkr1000.pid.2=0x824e -# If the board is a 2341:824e use 2341:824e for build and set other parameters as well -mkr1000.vid.2.build.vid=0x2341 -mkr1000.vid.2.build.pid=0x824e -mkr1000.vid.2.build.usb_product="Genuino MKR1000" -mkr1000.vid.2.bootloader.file=mkr1000/samd21_sam_ba_genuino_mkr1000.bin - -mkr1000.vid.3=0x2341 -mkr1000.pid.3=0x024e -# If the board is a 2341:024e use 2341:824e for build and set other parameters as well -mkr1000.vid.3.build.vid=0x2341 -mkr1000.vid.3.build.pid=0x824e -mkr1000.vid.3.build.usb_product="Genuino MKR1000" -mkr1000.vid.3.bootloader.file=mkr1000/samd21_sam_ba_genuino_mkr1000.bin - -mkr1000.upload.tool=bossac -mkr1000.upload.protocol=sam-ba -mkr1000.upload.maximum_size=262144 -mkr1000.upload.use_1200bps_touch=true -mkr1000.upload.wait_for_upload_port=true -mkr1000.upload.native_usb=true -mkr1000.build.mcu=cortex-m0plus -mkr1000.build.f_cpu=48000000L -mkr1000.build.usb_product="Arduino MKR1000" -mkr1000.build.usb_manufacturer="Arduino LLC" -mkr1000.build.board=SAMD_MKR1000 -mkr1000.build.core=arduino -mkr1000.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -mkr1000.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mkr1000.build.openocdscript=openocd_scripts/arduino_zero.cfg -mkr1000.build.variant=mkr1000 -mkr1000.build.vid=0x2341 -mkr1000.build.pid=0x804e -mkr1000.bootloader.tool=openocd -mkr1000.bootloader.file=mkr1000/samd21_sam_ba_arduino_mkr1000.bin - -# Arduino MKRZero -# --------------- -mkrzero.name=Arduino MKRZERO -mkrzero.vid.0=0x2341 -mkrzero.pid.0=0x804f -mkrzero.vid.1=0x2341 -mkrzero.pid.1=0x004f - -mkrzero.upload.tool=bossac -mkrzero.upload.protocol=sam-ba -mkrzero.upload.maximum_size=262144 -mkrzero.upload.use_1200bps_touch=true -mkrzero.upload.wait_for_upload_port=true -mkrzero.upload.native_usb=true -mkrzero.build.mcu=cortex-m0plus -mkrzero.build.f_cpu=48000000L -mkrzero.build.usb_product="Arduino MKRZero" -mkrzero.build.usb_manufacturer="Arduino LLC" -mkrzero.build.board=SAMD_MKRZERO -mkrzero.build.core=arduino -mkrzero.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -mkrzero.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mkrzero.build.openocdscript=openocd_scripts/arduino_zero.cfg -mkrzero.build.variant=mkrzero -mkrzero.build.vid=0x2341 -mkrzero.build.pid=0x804f -mkrzero.bootloader.tool=openocd -mkrzero.bootloader.file=mkrzero/samd21_sam_ba_arduino_mkrzero.bin - -# Arduino MKR WiFi 1010 -# -------------------- -mkrwifi1010.name=Arduino MKR WiFi 1010 -mkrwifi1010.vid.0=0x2341 -mkrwifi1010.pid.0=0x8054 -mkrwifi1010.vid.1=0x2341 -mkrwifi1010.pid.1=0x0054 - -mkrwifi1010.upload.tool=bossac -mkrwifi1010.upload.protocol=sam-ba -mkrwifi1010.upload.maximum_size=262144 -mkrwifi1010.upload.use_1200bps_touch=true -mkrwifi1010.upload.wait_for_upload_port=true -mkrwifi1010.upload.native_usb=true -mkrwifi1010.build.mcu=cortex-m0plus -mkrwifi1010.build.f_cpu=48000000L -mkrwifi1010.build.usb_product="Arduino MKR WiFi 1010" -mkrwifi1010.build.usb_manufacturer="Arduino LLC" -mkrwifi1010.build.board=SAMD_MKRWIFI1010 -mkrwifi1010.build.core=arduino -mkrwifi1010.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -DUSE_BQ24195L_PMIC -mkrwifi1010.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mkrwifi1010.build.openocdscript=openocd_scripts/arduino_zero.cfg -mkrwifi1010.build.variant=mkrwifi1010 -mkrwifi1010.build.vid=0x2341 -mkrwifi1010.build.pid=0x8054 -mkrwifi1010.bootloader.tool=openocd -mkrwifi1010.bootloader.file=mkrwifi1010/samd21_sam_ba_arduino_mkrwifi1010.bin - -# Arduino MKR FOX 1200 -# -------------------- -mkrfox1200.name=Arduino MKR FOX 1200 -mkrfox1200.vid.0=0x2341 -mkrfox1200.pid.0=0x8050 -mkrfox1200.vid.1=0x2341 -mkrfox1200.pid.1=0x0050 - -mkrfox1200.upload.tool=bossac -mkrfox1200.upload.protocol=sam-ba -mkrfox1200.upload.maximum_size=262144 -mkrfox1200.upload.use_1200bps_touch=true -mkrfox1200.upload.wait_for_upload_port=true -mkrfox1200.upload.native_usb=true -mkrfox1200.build.mcu=cortex-m0plus -mkrfox1200.build.f_cpu=48000000L -mkrfox1200.build.usb_product="Arduino MKR FOX 1200" -mkrfox1200.build.usb_manufacturer="Arduino LLC" -mkrfox1200.build.board=SAMD_MKRFox1200 -mkrfox1200.build.core=arduino -mkrfox1200.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -mkrfox1200.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mkrfox1200.build.openocdscript=openocd_scripts/arduino_zero.cfg -mkrfox1200.build.variant=mkrfox1200 -mkrfox1200.build.vid=0x2341 -mkrfox1200.build.pid=0x8050 -mkrfox1200.bootloader.tool=openocd -mkrfox1200.bootloader.file=mkrfox1200/samd21_sam_ba_arduino_mkrfox1200.bin - -# Arduino MKR WAN 1300 -# -------------------- -mkrwan1300.name=Arduino MKR WAN 1300 -mkrwan1300.vid.0=0x2341 -mkrwan1300.pid.0=0x8053 -mkrwan1300.vid.1=0x2341 -mkrwan1300.pid.1=0x0053 - -mkrwan1300.upload.tool=bossac -mkrwan1300.upload.protocol=sam-ba -mkrwan1300.upload.maximum_size=262144 -mkrwan1300.upload.use_1200bps_touch=true -mkrwan1300.upload.wait_for_upload_port=true -mkrwan1300.upload.native_usb=true -mkrwan1300.build.mcu=cortex-m0plus -mkrwan1300.build.f_cpu=48000000L -mkrwan1300.build.usb_product="Arduino MKR WAN 1300" -mkrwan1300.build.usb_manufacturer="Arduino LLC" -mkrwan1300.build.board=SAMD_MKRWAN1300 -mkrwan1300.build.core=arduino -mkrwan1300.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -mkrwan1300.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mkrwan1300.build.openocdscript=openocd_scripts/arduino_zero.cfg -mkrwan1300.build.variant=mkrwan1300 -mkrwan1300.build.vid=0x2341 -mkrwan1300.build.pid=0x8053 -mkrwan1300.bootloader.tool=openocd -mkrwan1300.bootloader.file=mkrwan1300/samd21_sam_ba_arduino_mkrwan1300.bin - -# Arduino MKR GSM 1400 -# -------------------- -mkrgsm1400.name=Arduino MKR GSM 1400 -mkrgsm1400.vid.0=0x2341 -mkrgsm1400.pid.0=0x8052 -mkrgsm1400.vid.1=0x2341 -mkrgsm1400.pid.1=0x0052 - -mkrgsm1400.upload.tool=bossac -mkrgsm1400.upload.protocol=sam-ba -mkrgsm1400.upload.maximum_size=262144 -mkrgsm1400.upload.use_1200bps_touch=true -mkrgsm1400.upload.wait_for_upload_port=true -mkrgsm1400.upload.native_usb=true -mkrgsm1400.build.mcu=cortex-m0plus -mkrgsm1400.build.f_cpu=48000000L -mkrgsm1400.build.usb_product="Arduino MKR GSM 1400" -mkrgsm1400.build.usb_manufacturer="Arduino LLC" -mkrgsm1400.build.board=SAMD_MKRGSM1400 -mkrgsm1400.build.core=arduino -mkrgsm1400.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -DUSE_BQ24195L_PMIC -mkrgsm1400.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mkrgsm1400.build.openocdscript=openocd_scripts/arduino_zero.cfg -mkrgsm1400.build.variant=mkrgsm1400 -mkrgsm1400.build.vid=0x2341 -mkrgsm1400.build.pid=0x8052 -mkrgsm1400.bootloader.tool=openocd -mkrgsm1400.bootloader.file=mkrgsm1400/samd21_sam_ba_arduino_mkrgsm1400.bin - -# Arduino MKR NB 1500 -# -------------------- -mkrnb1500.name=Arduino MKR NB 1500 -mkrnb1500.vid.0=0x2341 -mkrnb1500.pid.0=0x8055 -mkrnb1500.vid.1=0x2341 -mkrnb1500.pid.1=0x0055 - -mkrnb1500.upload.tool=bossac -mkrnb1500.upload.protocol=sam-ba -mkrnb1500.upload.maximum_size=262144 -mkrnb1500.upload.use_1200bps_touch=true -mkrnb1500.upload.wait_for_upload_port=true -mkrnb1500.upload.native_usb=true -mkrnb1500.build.mcu=cortex-m0plus -mkrnb1500.build.f_cpu=48000000L -mkrnb1500.build.usb_product="Arduino MKR NB 1500" -mkrnb1500.build.usb_manufacturer="Arduino LLC" -mkrnb1500.build.board=SAMD_MKRNB1500 -mkrnb1500.build.core=arduino -mkrnb1500.build.extra_flags=-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ {build.usb_flags} -DUSE_BQ24195L_PMIC -mkrnb1500.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mkrnb1500.build.openocdscript=openocd_scripts/arduino_zero.cfg -mkrnb1500.build.variant=mkrnb1500 -mkrnb1500.build.vid=0x2341 -mkrnb1500.build.pid=0x8055 -mkrnb1500.bootloader.tool=openocd -mkrnb1500.bootloader.file=mkrnb1500/samd21_sam_ba_arduino_mkrnb1500.bin - -# Adafruit Circuit Playground M0 -# ------------------------------ -adafruit_circuitplayground_m0.name=Adafruit Circuit Playground Express +menu.cache=Cache +menu.speed=CPU Speed +menu.opt=Optimize +menu.maxqspi=Max QSPI +menu.usbstack=USB Stack +menu.debug=Debug + +# ----------------------------------- +# Adafruit Feather M0 (SAMD21) +# ----------------------------------- +adafruit_feather_m0.name=Adafruit Feather M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_feather_m0.vid.0=0x239A +adafruit_feather_m0.pid.0=0x800B +adafruit_feather_m0.vid.1=0x239A +adafruit_feather_m0.pid.1=0x000B +adafruit_feather_m0.vid.2=0x239A +adafruit_feather_m0.pid.2=0x0015 + +# Upload +adafruit_feather_m0.upload.tool=bossac18 +adafruit_feather_m0.upload.protocol=sam-ba +adafruit_feather_m0.upload.maximum_size=262144 +adafruit_feather_m0.upload.offset=0x2000 +adafruit_feather_m0.upload.use_1200bps_touch=true +adafruit_feather_m0.upload.wait_for_upload_port=true +adafruit_feather_m0.upload.native_usb=true + +# Build +adafruit_feather_m0.build.mcu=cortex-m0plus +adafruit_feather_m0.build.f_cpu=48000000L +adafruit_feather_m0.build.usb_product="Feather M0" +adafruit_feather_m0.build.usb_manufacturer="Adafruit" +adafruit_feather_m0.build.board=SAMD_ZERO +adafruit_feather_m0.build.core=arduino +adafruit_feather_m0.build.extra_flags=-D__SAMD21G18A__ -DADAFRUIT_FEATHER_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_feather_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_feather_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_feather_m0.build.variant=feather_m0 +adafruit_feather_m0.build.variant_system_lib= +adafruit_feather_m0.build.vid=0x239A +adafruit_feather_m0.build.pid=0x800B +adafruit_feather_m0.bootloader.tool=openocd +adafruit_feather_m0.bootloader.file=featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin + +# Menu: Optimization +adafruit_feather_m0.menu.opt.small=Small (-Os) (standard) +adafruit_feather_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_feather_m0.menu.opt.fast=Fast (-O2) +adafruit_feather_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_feather_m0.menu.opt.faster=Faster (-O3) +adafruit_feather_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_feather_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_feather_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_feather_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_feather_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_feather_m0.menu.usbstack.arduino=Arduino +adafruit_feather_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_feather_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_feather_m0.menu.debug.off=Off +adafruit_feather_m0.menu.debug.on=On +adafruit_feather_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Feather M0 Express (SAMD21) +# ----------------------------------- +adafruit_feather_m0_express.name=Adafruit Feather M0 Express (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_feather_m0_express.vid.0=0x239A +adafruit_feather_m0_express.pid.0=0x801B +adafruit_feather_m0_express.vid.1=0x239A +adafruit_feather_m0_express.pid.1=0x001B + +# Upload +adafruit_feather_m0_express.upload.tool=bossac18 +adafruit_feather_m0_express.upload.protocol=sam-ba +adafruit_feather_m0_express.upload.maximum_size=262144 +adafruit_feather_m0_express.upload.offset=0x2000 +adafruit_feather_m0_express.upload.use_1200bps_touch=true +adafruit_feather_m0_express.upload.wait_for_upload_port=true +adafruit_feather_m0_express.upload.native_usb=true + +# Build +adafruit_feather_m0_express.build.mcu=cortex-m0plus +adafruit_feather_m0_express.build.f_cpu=48000000L +adafruit_feather_m0_express.build.usb_product="Feather M0 Express" +adafruit_feather_m0_express.build.usb_manufacturer="Adafruit" +adafruit_feather_m0_express.build.board=SAMD_FEATHER_M0_EXPRESS +adafruit_feather_m0_express.build.core=arduino +adafruit_feather_m0_express.build.extra_flags=-D__SAMD21G18A__ -DARDUINO_SAMD_FEATHER_M0 -DADAFRUIT_FEATHER_M0_EXPRESS -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_feather_m0_express.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_feather_m0_express.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_feather_m0_express.build.variant=feather_m0_express +adafruit_feather_m0_express.build.variant_system_lib= +adafruit_feather_m0_express.build.vid=0x239A +adafruit_feather_m0_express.build.pid=0x801B +adafruit_feather_m0_express.bootloader.tool=openocd +adafruit_feather_m0_express.bootloader.file=featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin + +# Menu: Optimization +adafruit_feather_m0_express.menu.opt.small=Small (-Os) (standard) +adafruit_feather_m0_express.menu.opt.small.build.flags.optimize=-Os +adafruit_feather_m0_express.menu.opt.fast=Fast (-O2) +adafruit_feather_m0_express.menu.opt.fast.build.flags.optimize=-O2 +adafruit_feather_m0_express.menu.opt.faster=Faster (-O3) +adafruit_feather_m0_express.menu.opt.faster.build.flags.optimize=-O3 +adafruit_feather_m0_express.menu.opt.fastest=Fastest (-Ofast) +adafruit_feather_m0_express.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_feather_m0_express.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_feather_m0_express.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_feather_m0_express.menu.usbstack.arduino=Arduino +adafruit_feather_m0_express.menu.usbstack.tinyusb=TinyUSB +adafruit_feather_m0_express.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_feather_m0_express.menu.debug.off=Off +adafruit_feather_m0_express.menu.debug.on=On +adafruit_feather_m0_express.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Metro M0 Express (SAMD21) +# ----------------------------------- +adafruit_metro_m0.name=Adafruit Metro M0 Express (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_metro_m0.vid.0=0x239A +adafruit_metro_m0.pid.0=0x8013 +adafruit_metro_m0.vid.1=0x239A +adafruit_metro_m0.pid.1=0x0013 + +# Upload +adafruit_metro_m0.upload.tool=bossac18 +adafruit_metro_m0.upload.protocol=sam-ba +adafruit_metro_m0.upload.maximum_size=262144 +adafruit_metro_m0.upload.offset=0x2000 +adafruit_metro_m0.upload.use_1200bps_touch=true +adafruit_metro_m0.upload.wait_for_upload_port=true +adafruit_metro_m0.upload.native_usb=true + +# Build +adafruit_metro_m0.build.mcu=cortex-m0plus +adafruit_metro_m0.build.f_cpu=48000000L +adafruit_metro_m0.build.usb_product="Metro M0 Express" +adafruit_metro_m0.build.usb_manufacturer="Adafruit" +adafruit_metro_m0.build.board=SAMD_ZERO +adafruit_metro_m0.build.core=arduino +adafruit_metro_m0.build.extra_flags=-D__SAMD21G18A__ -DADAFRUIT_METRO_M0_EXPRESS -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_metro_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_metro_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_metro_m0.build.variant=metro_m0 +adafruit_metro_m0.build.variant_system_lib= +adafruit_metro_m0.build.vid=0x239A +adafruit_metro_m0.build.pid=0x8013 +adafruit_metro_m0.bootloader.tool=openocd +adafruit_metro_m0.bootloader.file=metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.bin + +# Menu: Optimization +adafruit_metro_m0.menu.opt.small=Small (-Os) (standard) +adafruit_metro_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_metro_m0.menu.opt.fast=Fast (-O2) +adafruit_metro_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_metro_m0.menu.opt.faster=Faster (-O3) +adafruit_metro_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_metro_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_metro_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_metro_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_metro_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_metro_m0.menu.usbstack.arduino=Arduino +adafruit_metro_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_metro_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_metro_m0.menu.debug.off=Off +adafruit_metro_m0.menu.debug.on=On +adafruit_metro_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Circuit Playground Express (SAMD21) +# ----------------------------------- +adafruit_circuitplayground_m0.name=Adafruit Circuit Playground Express (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython adafruit_circuitplayground_m0.vid.0=0x239A adafruit_circuitplayground_m0.pid.0=0x8018 adafruit_circuitplayground_m0.vid.1=0x239A -adafruit_circuitplayground_m0.pid.1=0x0018 -adafruit_circuitplayground_m0.upload.tool=bossac +adafruit_circuitplayground_m0.pid.1=0x0019 + +# Upload +adafruit_circuitplayground_m0.upload.tool=bossac18 adafruit_circuitplayground_m0.upload.protocol=sam-ba adafruit_circuitplayground_m0.upload.maximum_size=262144 +adafruit_circuitplayground_m0.upload.offset=0x2000 adafruit_circuitplayground_m0.upload.use_1200bps_touch=true adafruit_circuitplayground_m0.upload.wait_for_upload_port=true adafruit_circuitplayground_m0.upload.native_usb=true + +# Build adafruit_circuitplayground_m0.build.mcu=cortex-m0plus adafruit_circuitplayground_m0.build.f_cpu=48000000L adafruit_circuitplayground_m0.build.usb_product="Circuit Playground Express" adafruit_circuitplayground_m0.build.usb_manufacturer="Adafruit" adafruit_circuitplayground_m0.build.board=SAMD_CIRCUITPLAYGROUND_EXPRESS adafruit_circuitplayground_m0.build.core=arduino -adafruit_circuitplayground_m0.build.extra_flags=-DCRYSTALLESS -DARDUINO_SAMD_ZERO -D__SAMD21G18A__ {build.usb_flags} +adafruit_circuitplayground_m0.build.extra_flags=-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_CIRCUITPLAYGROUND_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} adafruit_circuitplayground_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -adafruit_circuitplayground_m0.build.openocdscript=openocd_scripts/arduino_zero.cfg +adafruit_circuitplayground_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg adafruit_circuitplayground_m0.build.variant=circuitplay adafruit_circuitplayground_m0.build.variant_system_lib= adafruit_circuitplayground_m0.build.vid=0x239A adafruit_circuitplayground_m0.build.pid=0x8018 adafruit_circuitplayground_m0.bootloader.tool=openocd -adafruit_circuitplayground_m0.bootloader.file=circuitplay/circuitplay_m0_samd21g18_sam_ba.bin - -# Arduino M0 PRO (with) bootloader - Programming port -# --------------------------------------------------- -mzero_pro_bl_dbg.name=Arduino M0 Pro (Programming Port) -mzero_pro_bl_dbg.vid.0=0x03eb -mzero_pro_bl_dbg.pid.0=0x2111 -mzero_pro_bl_dbg.upload.tool=openocd-withbootsize -mzero_pro_bl_dbg.upload.protocol=sam-ba -mzero_pro_bl_dbg.upload.maximum_size=262144 -mzero_pro_bl_dbg.upload.use_1200bps_touch=false -mzero_pro_bl_dbg.upload.wait_for_upload_port=false -mzero_pro_bl_dbg.upload.native_usb=false -mzero_pro_bl_dbg.build.mcu=cortex-m0plus -mzero_pro_bl_dbg.build.f_cpu=48000000L -mzero_pro_bl_dbg.build.usb_product="Arduino M0 Pro" -mzero_pro_bl_dbg.build.board=SAM_ZERO -mzero_pro_bl_dbg.build.core=arduino -mzero_pro_bl_dbg.build.extra_flags=-D__SAMD21G18A__ -mthumb {build.usb_flags} -mzero_pro_bl_dbg.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mzero_pro_bl_dbg.build.openocdscript=openocd_scripts/arduino_zero.cfg -mzero_pro_bl_dbg.build.variant=arduino_mzero -mzero_pro_bl_dbg.build.variant_system_lib= -mzero_pro_bl_dbg.build.vid=0x2a03 -mzero_pro_bl_dbg.build.pid=0x804f -mzero_pro_bl_dbg.build.preferred_out_format=hex -mzero_pro_bl_dbg.bootloader.size=0x4000 - -mzero_pro_bl_dbg.bootloader.tool=openocd-withbootsize -mzero_pro_bl_dbg.bootloader.cmd_unprotect=at91samd bootloader 0 -mzero_pro_bl_dbg.bootloader.cmd_protect=at91samd bootloader 16384 -mzero_pro_bl_dbg.bootloader.cmd_protect_verify=at91samd bootloader -mzero_pro_bl_dbg.bootloader.file=mzero/Bootloader_D21_M0_Pro_150427.hex - -# Arduino M0 PRO (with) bootloader - Native port -# ---------------------------------------------- -mzero_pro_bl.name=Arduino M0 Pro (Native USB Port) -mzero_pro_bl.vid.0=0x2a03 -mzero_pro_bl.pid.0=0x004d -mzero_pro_bl.vid.1=0x2a03 -mzero_pro_bl.pid.1=0x804d -mzero_pro_bl.vid.2=0x2a03 -mzero_pro_bl.pid.2=0x004f -mzero_pro_bl.vid.3=0x2a03 -mzero_pro_bl.pid.3=0x804f -mzero_pro_bl.upload.tool=avrdude -mzero_pro_bl.upload.protocol=stk500v2 -mzero_pro_bl.upload.maximum_size=262144 -mzero_pro_bl.upload.use_1200bps_touch=true -mzero_pro_bl.upload.wait_for_upload_port=true -mzero_pro_bl.upload.native_usb=true -mzero_pro_bl.upload.speed=57600 -mzero_pro_bl.build.mcu=cortex-m0plus -mzero_pro_bl.build.f_cpu=48000000L -mzero_pro_bl.build.usb_product="Arduino M0 Pro" -mzero_pro_bl.build.board=SAM_ZERO -mzero_pro_bl.build.core=arduino -mzero_pro_bl.build.extra_flags=-D__SAMD21G18A__ -mthumb {build.usb_flags} -mzero_pro_bl.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mzero_pro_bl.build.openocdscript=openocd_scripts/arduino_zero.cfg -mzero_pro_bl.build.variant=arduino_mzero -mzero_pro_bl.build.variant_system_lib= -mzero_pro_bl.build.vid=0x2a03 -mzero_pro_bl.build.pid=0x804f -mzero_pro_bl.build.preferred_out_format=hex -mzero_pro_bl.bootloader.size=0x4000 -mzero_pro_bl.build.emu.mcu=atmega2560 -mzero_pro_bl.bootloader.tool=openocd-withbootsize -mzero_pro_bl.bootloader.file=mzero/Bootloader_D21_M0_Pro_150427.hex -mzero_pro_bl.bootloader.low_fuses=0xff - -# Arduino M0 (with) Bootloader -# ---------------------------- -mzero_bl.name=Arduino M0 -mzero_bl.vid.0=0x2a03 -mzero_bl.pid.0=0x004d -mzero_bl.vid.1=0x2a03 -mzero_bl.pid.1=0x804d -mzero_bl.vid.2=0x2a03 -mzero_bl.pid.2=0x004e -mzero_bl.vid.3=0x2a03 -mzero_bl.pid.3=0x804e -mzero_bl.upload.tool=avrdude -mzero_bl.upload.protocol=stk500v2 -mzero_bl.upload.maximum_size=262144 -mzero_bl.upload.use_1200bps_touch=true -mzero_bl.upload.wait_for_upload_port=true -mzero_bl.upload.native_usb=true -mzero_bl.upload.speed=57600 -mzero_bl.build.mcu=cortex-m0plus -mzero_bl.build.f_cpu=48000000L -mzero_bl.build.usb_product="Arduino M0" -mzero_bl.build.board=SAM_ZERO -mzero_bl.build.core=arduino -mzero_bl.build.extra_flags=-D__SAMD21G18A__ -mthumb {build.usb_flags} -mzero_bl.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -mzero_bl.build.openocdscript=openocd_scripts/arduino_zero.cfg -mzero_bl.build.variant=arduino_mzero -mzero_bl.build.variant_system_lib= -mzero_bl.build.vid=0x2a03 -mzero_bl.build.pid=0x804e -mzero_bl.build.preferred_out_format=hex -mzero_bl.bootloader.size=0x4000 -mzero_bl.build.emu.mcu=atmega2560 -mzero_bl.bootloader.tool=openocd-withbootsize -mzero_bl.bootloader.low_fuses=0xff -mzero_bl.bootloader.file=mzero/Bootloader_D21_M0_150515.hex - -# Arduino Tian (with) Bootloader -# ------------------------------ -tian.name=Arduino Tian -tian.upload.via_ssh=true -tian.vid.0=0x10C4 -tian.pid.0=0xEA70 -tian.descriptor.0=Enhanced Com Port - -tian.upload.tool=avrdude -#tian.upload.protocol=stk500v2 -tian.upload.protocol=wiring -tian.upload.maximum_size=262144 -tian.upload.use_1200bps_touch=true -tian.upload.wait_for_upload_port=true -tian.upload.native_usb=true -tian.upload.speed=57600 -tian.build.mcu=cortex-m0plus -tian.build.f_cpu=48000000L -tian.build.usb_product="Arduino Tian" -tian.build.board=SAMD_TIAN -tian.build.core=arduino -tian.build.extra_flags=-D__SAMD21G18A__ -mthumb {build.usb_flags} -tian.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld -tian.build.openocdscript=openocd_scripts/arduino_zero.cfg -tian.build.variant=arduino_mzero -tian.build.variant_system_lib= -tian.build.vid=0x2a03 -tian.build.pid=0x8052 -tian.build.preferred_out_format=hex -tian.bootloader.size=0x4000 -tian.build.emu.mcu=atmega2560 -tian.bootloader.tool=openocd-withbootsize -tian.bootloader.low_fuses=0xff -tian.bootloader.file=sofia/Sofia_Tian_151118.hex -tian.drivers=SiliconLabs-CP2105/Silicon Labs VCP Driver.pkg - -# Arduino Tian Console port (not for upload) -# ------------------------------------------ -tian_cons.name=Arduino Tian (MIPS Console port) -tian_cons.vid.0=0x10C4 -tian_cons.pid.0=0xEA70 -tian_cons.descriptor.0=Standard Com Port -tian_cons.hide=true -tian_cons.build.board=SAMD_TIAN +adafruit_circuitplayground_m0.bootloader.file=circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.bin + +# Menu: Optimization +adafruit_circuitplayground_m0.menu.opt.small=Small (-Os) (standard) +adafruit_circuitplayground_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_circuitplayground_m0.menu.opt.fast=Fast (-O2) +adafruit_circuitplayground_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_circuitplayground_m0.menu.opt.faster=Faster (-O3) +adafruit_circuitplayground_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_circuitplayground_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_circuitplayground_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_circuitplayground_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_circuitplayground_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_circuitplayground_m0.menu.usbstack.arduino=Arduino +adafruit_circuitplayground_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_circuitplayground_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_circuitplayground_m0.menu.debug.off=Off +adafruit_circuitplayground_m0.menu.debug.on=On +adafruit_circuitplayground_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Gemma M0 (SAMD21) +# ----------------------------------- +adafruit_gemma_m0.name=Adafruit Gemma M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_gemma_m0.vid.0=0x239A +adafruit_gemma_m0.pid.0=0x801C +adafruit_gemma_m0.vid.1=0x239A +adafruit_gemma_m0.pid.1=0x001C + +# Upload +adafruit_gemma_m0.upload.tool=bossac18 +adafruit_gemma_m0.upload.protocol=sam-ba +adafruit_gemma_m0.upload.maximum_size=262144 +adafruit_gemma_m0.upload.offset=0x2000 +adafruit_gemma_m0.upload.use_1200bps_touch=true +adafruit_gemma_m0.upload.wait_for_upload_port=true +adafruit_gemma_m0.upload.native_usb=true + +# Build +adafruit_gemma_m0.build.mcu=cortex-m0plus +adafruit_gemma_m0.build.f_cpu=48000000L +adafruit_gemma_m0.build.usb_product="Gemma M0" +adafruit_gemma_m0.build.usb_manufacturer="Adafruit" +adafruit_gemma_m0.build.board=GEMMA_M0 +adafruit_gemma_m0.build.core=arduino +adafruit_gemma_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_GEMMA_M0 -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_gemma_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_gemma_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_gemma_m0.build.variant=gemma_m0 +adafruit_gemma_m0.build.variant_system_lib= +adafruit_gemma_m0.build.vid=0x239A +adafruit_gemma_m0.build.pid=0x801C +adafruit_gemma_m0.bootloader.tool=openocd +adafruit_gemma_m0.bootloader.file=gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.bin + +# Menu: Optimization +adafruit_gemma_m0.menu.opt.small=Small (-Os) (standard) +adafruit_gemma_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_gemma_m0.menu.opt.fast=Fast (-O2) +adafruit_gemma_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_gemma_m0.menu.opt.faster=Faster (-O3) +adafruit_gemma_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_gemma_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_gemma_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_gemma_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_gemma_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_gemma_m0.menu.usbstack.arduino=Arduino +adafruit_gemma_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_gemma_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_gemma_m0.menu.debug.off=Off +adafruit_gemma_m0.menu.debug.on=On +adafruit_gemma_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Trinket M0 (SAMD21) +# ----------------------------------- +adafruit_trinket_m0.name=Adafruit Trinket M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_trinket_m0.vid.0=0x239A +adafruit_trinket_m0.pid.0=0x801E +adafruit_trinket_m0.vid.1=0x239A +adafruit_trinket_m0.pid.1=0x001E + +# Upload +adafruit_trinket_m0.upload.tool=bossac18 +adafruit_trinket_m0.upload.protocol=sam-ba +adafruit_trinket_m0.upload.maximum_size=262144 +adafruit_trinket_m0.upload.offset=0x2000 +adafruit_trinket_m0.upload.use_1200bps_touch=true +adafruit_trinket_m0.upload.wait_for_upload_port=true +adafruit_trinket_m0.upload.native_usb=true + +# Build +adafruit_trinket_m0.build.mcu=cortex-m0plus +adafruit_trinket_m0.build.f_cpu=48000000L +adafruit_trinket_m0.build.usb_product="Trinket M0" +adafruit_trinket_m0.build.usb_manufacturer="Adafruit" +adafruit_trinket_m0.build.board=TRINKET_M0 +adafruit_trinket_m0.build.core=arduino +adafruit_trinket_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_TRINKET_M0 -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_trinket_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_trinket_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_trinket_m0.build.variant=trinket_m0 +adafruit_trinket_m0.build.variant_system_lib= +adafruit_trinket_m0.build.vid=0x239A +adafruit_trinket_m0.build.pid=0x801E +adafruit_trinket_m0.bootloader.tool=openocd +adafruit_trinket_m0.bootloader.file=trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.bin + +# Menu: Optimization +adafruit_trinket_m0.menu.opt.small=Small (-Os) (standard) +adafruit_trinket_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_trinket_m0.menu.opt.fast=Fast (-O2) +adafruit_trinket_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_trinket_m0.menu.opt.faster=Faster (-O3) +adafruit_trinket_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_trinket_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_trinket_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_trinket_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_trinket_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_trinket_m0.menu.usbstack.arduino=Arduino +adafruit_trinket_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_trinket_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_trinket_m0.menu.debug.off=Off +adafruit_trinket_m0.menu.debug.on=On +adafruit_trinket_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit QT Py M0 (SAMD21) +# ----------------------------------- +adafruit_qtpy_m0.name=Adafruit QT Py M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_qtpy_m0.vid.0=0x239A +adafruit_qtpy_m0.pid.0=0x80CB +adafruit_qtpy_m0.vid.1=0x239A +adafruit_qtpy_m0.pid.1=0x00CB +adafruit_qtpy_m0.vid.2=0x239A +adafruit_qtpy_m0.pid.2=0x00CC + +# Upload +adafruit_qtpy_m0.upload.tool=bossac18 +adafruit_qtpy_m0.upload.protocol=sam-ba +adafruit_qtpy_m0.upload.maximum_size=262144 +adafruit_qtpy_m0.upload.offset=0x2000 +adafruit_qtpy_m0.upload.use_1200bps_touch=true +adafruit_qtpy_m0.upload.wait_for_upload_port=true +adafruit_qtpy_m0.upload.native_usb=true + +# Build +adafruit_qtpy_m0.build.mcu=cortex-m0plus +adafruit_qtpy_m0.build.f_cpu=48000000L +adafruit_qtpy_m0.build.usb_product="QT Py M0" +adafruit_qtpy_m0.build.usb_manufacturer="Adafruit" +adafruit_qtpy_m0.build.board=QTPY_M0 +adafruit_qtpy_m0.build.core=arduino +adafruit_qtpy_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_QTPY_M0 -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_qtpy_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_qtpy_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_qtpy_m0.build.variant=qtpy_m0 +adafruit_qtpy_m0.build.variant_system_lib= +adafruit_qtpy_m0.build.vid=0x239A +adafruit_qtpy_m0.build.pid=0x80CB +adafruit_qtpy_m0.bootloader.tool=openocd +adafruit_qtpy_m0.bootloader.file=qtpyM0/bootloader-qtpy_m0.bin + +# Menu: Optimization +adafruit_qtpy_m0.menu.opt.small=Small (-Os) (standard) +adafruit_qtpy_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_qtpy_m0.menu.opt.fast=Fast (-O2) +adafruit_qtpy_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_qtpy_m0.menu.opt.faster=Faster (-O3) +adafruit_qtpy_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_qtpy_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_qtpy_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_qtpy_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_qtpy_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_qtpy_m0.menu.usbstack.arduino=Arduino +adafruit_qtpy_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_qtpy_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_qtpy_m0.menu.debug.off=Off +adafruit_qtpy_m0.menu.debug.on=On +adafruit_qtpy_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit NeoPixel Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_neotrinkey_m0.name=Adafruit NeoPixel Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_neotrinkey_m0.vid.0=0x239A +adafruit_neotrinkey_m0.pid.0=0x80EF +adafruit_neotrinkey_m0.vid.1=0x239A +adafruit_neotrinkey_m0.pid.1=0x00EF +adafruit_neotrinkey_m0.vid.2=0x239A +adafruit_neotrinkey_m0.pid.2=0x80F0 + +# Upload +adafruit_neotrinkey_m0.upload.tool=bossac18 +adafruit_neotrinkey_m0.upload.protocol=sam-ba +adafruit_neotrinkey_m0.upload.maximum_size=262144 +adafruit_neotrinkey_m0.upload.offset=0x2000 +adafruit_neotrinkey_m0.upload.use_1200bps_touch=true +adafruit_neotrinkey_m0.upload.wait_for_upload_port=true +adafruit_neotrinkey_m0.upload.native_usb=true + +# Build +adafruit_neotrinkey_m0.build.mcu=cortex-m0plus +adafruit_neotrinkey_m0.build.f_cpu=48000000L +adafruit_neotrinkey_m0.build.usb_product="NeoPixel Trinkey M0" +adafruit_neotrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_neotrinkey_m0.build.board=NEOTRINKEY_M0 +adafruit_neotrinkey_m0.build.core=arduino +adafruit_neotrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_NEOTRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_neotrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_neotrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_neotrinkey_m0.build.variant=neotrinkey_m0 +adafruit_neotrinkey_m0.build.variant_system_lib= +adafruit_neotrinkey_m0.build.vid=0x239A +adafruit_neotrinkey_m0.build.pid=0x80EF +adafruit_neotrinkey_m0.bootloader.tool=openocd +adafruit_neotrinkey_m0.bootloader.file=neotrinkey_m0/bootloader-neotrinkey_m0.bin + +# Menu: Optimization +adafruit_neotrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_neotrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_neotrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_neotrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_neotrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_neotrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_neotrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_neotrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_neotrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_neotrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_neotrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_neotrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_neotrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_neotrinkey_m0.menu.debug.off=Off +adafruit_neotrinkey_m0.menu.debug.on=On +adafruit_neotrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Rotary Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_rotarytrinkey_m0.name=Adafruit Rotary Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_rotarytrinkey_m0.vid.0=0x239A +adafruit_rotarytrinkey_m0.pid.0=0x80FB +adafruit_rotarytrinkey_m0.vid.1=0x239A +adafruit_rotarytrinkey_m0.pid.1=0x00FB +adafruit_rotarytrinkey_m0.vid.2=0x239A +adafruit_rotarytrinkey_m0.pid.2=0x80FC + +# Upload +adafruit_rotarytrinkey_m0.upload.tool=bossac18 +adafruit_rotarytrinkey_m0.upload.protocol=sam-ba +adafruit_rotarytrinkey_m0.upload.maximum_size=262144 +adafruit_rotarytrinkey_m0.upload.offset=0x2000 +adafruit_rotarytrinkey_m0.upload.use_1200bps_touch=true +adafruit_rotarytrinkey_m0.upload.wait_for_upload_port=true +adafruit_rotarytrinkey_m0.upload.native_usb=true + +# Build +adafruit_rotarytrinkey_m0.build.mcu=cortex-m0plus +adafruit_rotarytrinkey_m0.build.f_cpu=48000000L +adafruit_rotarytrinkey_m0.build.usb_product="Rotary Trinkey M0" +adafruit_rotarytrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_rotarytrinkey_m0.build.board=ROTARYTRINKEY_M0 +adafruit_rotarytrinkey_m0.build.core=arduino +adafruit_rotarytrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_ROTARYTRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_rotarytrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_rotarytrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_rotarytrinkey_m0.build.variant=rotarytrinkey_m0 +adafruit_rotarytrinkey_m0.build.variant_system_lib= +adafruit_rotarytrinkey_m0.build.vid=0x239A +adafruit_rotarytrinkey_m0.build.pid=0x80FB +adafruit_rotarytrinkey_m0.bootloader.tool=openocd +adafruit_rotarytrinkey_m0.bootloader.file=rotarytrinkey_m0/bootloader-rotarytrinkey_m0.bin + +# Menu: Optimization +adafruit_rotarytrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_rotarytrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_rotarytrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_rotarytrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_rotarytrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_rotarytrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_rotarytrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_rotarytrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_rotarytrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_rotarytrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_rotarytrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_rotarytrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_rotarytrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_rotarytrinkey_m0.menu.debug.off=Off +adafruit_rotarytrinkey_m0.menu.debug.on=On +adafruit_rotarytrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit NeoKey Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_neokeytrinkey_m0.name=Adafruit NeoKey Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_neokeytrinkey_m0.vid.0=0x239A +adafruit_neokeytrinkey_m0.pid.0=0x80FF +adafruit_neokeytrinkey_m0.vid.1=0x239A +adafruit_neokeytrinkey_m0.pid.1=0x00FF +adafruit_neokeytrinkey_m0.vid.2=0x239A +adafruit_neokeytrinkey_m0.pid.2=0x8100 + +# Upload +adafruit_neokeytrinkey_m0.upload.tool=bossac18 +adafruit_neokeytrinkey_m0.upload.protocol=sam-ba +adafruit_neokeytrinkey_m0.upload.maximum_size=262144 +adafruit_neokeytrinkey_m0.upload.offset=0x2000 +adafruit_neokeytrinkey_m0.upload.use_1200bps_touch=true +adafruit_neokeytrinkey_m0.upload.wait_for_upload_port=true +adafruit_neokeytrinkey_m0.upload.native_usb=true + +# Build +adafruit_neokeytrinkey_m0.build.mcu=cortex-m0plus +adafruit_neokeytrinkey_m0.build.f_cpu=48000000L +adafruit_neokeytrinkey_m0.build.usb_product="NeoKey Trinkey M0" +adafruit_neokeytrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_neokeytrinkey_m0.build.board=NEOKEYTRINKEY_M0 +adafruit_neokeytrinkey_m0.build.core=arduino +adafruit_neokeytrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_NEOKEYTRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_neokeytrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_neokeytrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_neokeytrinkey_m0.build.variant=neokeytrinkey_m0 +adafruit_neokeytrinkey_m0.build.variant_system_lib= +adafruit_neokeytrinkey_m0.build.vid=0x239A +adafruit_neokeytrinkey_m0.build.pid=0x80FF +adafruit_neokeytrinkey_m0.bootloader.tool=openocd +adafruit_neokeytrinkey_m0.bootloader.file=neokeytrinkey_m0/bootloader-neokeytrinkey_m0.bin + +# Menu: Optimization +adafruit_neokeytrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_neokeytrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_neokeytrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_neokeytrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_neokeytrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_neokeytrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_neokeytrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_neokeytrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_neokeytrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_neokeytrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_neokeytrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_neokeytrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_neokeytrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_neokeytrinkey_m0.menu.debug.off=Off +adafruit_neokeytrinkey_m0.menu.debug.on=On +adafruit_neokeytrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Slide Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_slidetrinkey_m0.name=Adafruit Slide Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_slidetrinkey_m0.vid.0=0x239A +adafruit_slidetrinkey_m0.pid.0=0x8101 +adafruit_slidetrinkey_m0.vid.1=0x239A +adafruit_slidetrinkey_m0.pid.1=0x0101 +adafruit_slidetrinkey_m0.vid.2=0x239A +adafruit_slidetrinkey_m0.pid.2=0x8102 + +# Upload +adafruit_slidetrinkey_m0.upload.tool=bossac18 +adafruit_slidetrinkey_m0.upload.protocol=sam-ba +adafruit_slidetrinkey_m0.upload.maximum_size=262144 +adafruit_slidetrinkey_m0.upload.offset=0x2000 +adafruit_slidetrinkey_m0.upload.use_1200bps_touch=true +adafruit_slidetrinkey_m0.upload.wait_for_upload_port=true +adafruit_slidetrinkey_m0.upload.native_usb=true + +# Build +adafruit_slidetrinkey_m0.build.mcu=cortex-m0plus +adafruit_slidetrinkey_m0.build.f_cpu=48000000L +adafruit_slidetrinkey_m0.build.usb_product="Slide Trinkey M0" +adafruit_slidetrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_slidetrinkey_m0.build.board=SLIDETRINKEY_M0 +adafruit_slidetrinkey_m0.build.core=arduino +adafruit_slidetrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_SLIDETRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_slidetrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_slidetrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_slidetrinkey_m0.build.variant=slidetrinkey_m0 +adafruit_slidetrinkey_m0.build.variant_system_lib= +adafruit_slidetrinkey_m0.build.vid=0x239A +adafruit_slidetrinkey_m0.build.pid=0x8101 +adafruit_slidetrinkey_m0.bootloader.tool=openocd +adafruit_slidetrinkey_m0.bootloader.file=slidetrinkey_m0/bootloader-slidetrinkey_m0.bin + +# Menu: Optimization +adafruit_slidetrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_slidetrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_slidetrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_slidetrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_slidetrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_slidetrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_slidetrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_slidetrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_slidetrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_slidetrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_slidetrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_slidetrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_slidetrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_slidetrinkey_m0.menu.debug.off=Off +adafruit_slidetrinkey_m0.menu.debug.on=On +adafruit_slidetrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit ProxLight Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_proxlighttrinkey_m0.name=Adafruit ProxLight Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_proxlighttrinkey_m0.vid.0=0x239A +adafruit_proxlighttrinkey_m0.pid.0=0x8103 +adafruit_proxlighttrinkey_m0.vid.1=0x239A +adafruit_proxlighttrinkey_m0.pid.1=0x0103 +adafruit_proxlighttrinkey_m0.vid.2=0x239A +adafruit_proxlighttrinkey_m0.pid.2=0x8104 + +# Upload +adafruit_proxlighttrinkey_m0.upload.tool=bossac18 +adafruit_proxlighttrinkey_m0.upload.protocol=sam-ba +adafruit_proxlighttrinkey_m0.upload.maximum_size=262144 +adafruit_proxlighttrinkey_m0.upload.offset=0x2000 +adafruit_proxlighttrinkey_m0.upload.use_1200bps_touch=true +adafruit_proxlighttrinkey_m0.upload.wait_for_upload_port=true +adafruit_proxlighttrinkey_m0.upload.native_usb=true + +# Build +adafruit_proxlighttrinkey_m0.build.mcu=cortex-m0plus +adafruit_proxlighttrinkey_m0.build.f_cpu=48000000L +adafruit_proxlighttrinkey_m0.build.usb_product="ProxLight Trinkey M0" +adafruit_proxlighttrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_proxlighttrinkey_m0.build.board=PROXLIGHTTRINKEY_M0 +adafruit_proxlighttrinkey_m0.build.core=arduino +adafruit_proxlighttrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PROXLIGHTTRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_proxlighttrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_proxlighttrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_proxlighttrinkey_m0.build.variant=proxlighttrinkey_m0 +adafruit_proxlighttrinkey_m0.build.variant_system_lib= +adafruit_proxlighttrinkey_m0.build.vid=0x239A +adafruit_proxlighttrinkey_m0.build.pid=0x8103 +adafruit_proxlighttrinkey_m0.bootloader.tool=openocd +adafruit_proxlighttrinkey_m0.bootloader.file=proxlighttrinkey_m0/bootloader-proxlighttrinkey_m0.bin + +# Menu: Optimization +adafruit_proxlighttrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_proxlighttrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_proxlighttrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_proxlighttrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_proxlighttrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_proxlighttrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_proxlighttrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_proxlighttrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_proxlighttrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_proxlighttrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_proxlighttrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_proxlighttrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_proxlighttrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_proxlighttrinkey_m0.menu.debug.off=Off +adafruit_proxlighttrinkey_m0.menu.debug.on=On +adafruit_proxlighttrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit SHT4x Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_sht4xtrinkey_m0.name=Adafruit SHT4x Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_sht4xtrinkey_m0.vid.0=0x239A +adafruit_sht4xtrinkey_m0.pid.0=0x8153 +adafruit_sht4xtrinkey_m0.vid.1=0x239A +adafruit_sht4xtrinkey_m0.pid.1=0x0153 +adafruit_sht4xtrinkey_m0.vid.2=0x239A +adafruit_sht4xtrinkey_m0.pid.2=0x8154 + +# Upload +adafruit_sht4xtrinkey_m0.upload.tool=bossac18 +adafruit_sht4xtrinkey_m0.upload.protocol=sam-ba +adafruit_sht4xtrinkey_m0.upload.maximum_size=262144 +adafruit_sht4xtrinkey_m0.upload.offset=0x2000 +adafruit_sht4xtrinkey_m0.upload.use_1200bps_touch=true +adafruit_sht4xtrinkey_m0.upload.wait_for_upload_port=true +adafruit_sht4xtrinkey_m0.upload.native_usb=true + +# Build +adafruit_sht4xtrinkey_m0.build.mcu=cortex-m0plus +adafruit_sht4xtrinkey_m0.build.f_cpu=48000000L +adafruit_sht4xtrinkey_m0.build.usb_product="SHT4x Trinkey M0" +adafruit_sht4xtrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_sht4xtrinkey_m0.build.board=SHT4XTRINKEY_M0 +adafruit_sht4xtrinkey_m0.build.core=arduino +adafruit_sht4xtrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_SHT4XTRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_sht4xtrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_sht4xtrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_sht4xtrinkey_m0.build.variant=sht4xtrinkey_m0 +adafruit_sht4xtrinkey_m0.build.variant_system_lib= +adafruit_sht4xtrinkey_m0.build.vid=0x239A +adafruit_sht4xtrinkey_m0.build.pid=0x8153 +adafruit_sht4xtrinkey_m0.bootloader.tool=openocd +adafruit_sht4xtrinkey_m0.bootloader.file=sht4xtrinkey_m0/bootloader-sht4xtrinkey_m0.bin + +# Menu: Optimization +adafruit_sht4xtrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_sht4xtrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_sht4xtrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_sht4xtrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_sht4xtrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_sht4xtrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_sht4xtrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_sht4xtrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_sht4xtrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_sht4xtrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_sht4xtrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_sht4xtrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_sht4xtrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_sht4xtrinkey_m0.menu.debug.off=Off +adafruit_sht4xtrinkey_m0.menu.debug.on=On +adafruit_sht4xtrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Pixel Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_pixeltrinkey_m0.name=Adafruit Pixel Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_pixeltrinkey_m0.vid.0=0x239A +adafruit_pixeltrinkey_m0.pid.0=0x8155 +adafruit_pixeltrinkey_m0.vid.1=0x239A +adafruit_pixeltrinkey_m0.pid.1=0x0155 +adafruit_pixeltrinkey_m0.vid.2=0x239A +adafruit_pixeltrinkey_m0.pid.2=0x8156 + +# Upload +adafruit_pixeltrinkey_m0.upload.tool=bossac18 +adafruit_pixeltrinkey_m0.upload.protocol=sam-ba +adafruit_pixeltrinkey_m0.upload.maximum_size=262144 +adafruit_pixeltrinkey_m0.upload.offset=0x2000 +adafruit_pixeltrinkey_m0.upload.use_1200bps_touch=true +adafruit_pixeltrinkey_m0.upload.wait_for_upload_port=true +adafruit_pixeltrinkey_m0.upload.native_usb=true + +# Build +adafruit_pixeltrinkey_m0.build.mcu=cortex-m0plus +adafruit_pixeltrinkey_m0.build.f_cpu=48000000L +adafruit_pixeltrinkey_m0.build.usb_product="Pixel Trinkey M0" +adafruit_pixeltrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_pixeltrinkey_m0.build.board=PIXELTRINKEY_M0 +adafruit_pixeltrinkey_m0.build.core=arduino +adafruit_pixeltrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PIXELTRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_pixeltrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_pixeltrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_pixeltrinkey_m0.build.variant=pixeltrinkey_m0 +adafruit_pixeltrinkey_m0.build.variant_system_lib= +adafruit_pixeltrinkey_m0.build.vid=0x239A +adafruit_pixeltrinkey_m0.build.pid=0x8155 +adafruit_pixeltrinkey_m0.bootloader.tool=openocd +adafruit_pixeltrinkey_m0.bootloader.file=pixeltrinkey_m0/bootloader-pixeltrinkey_m0.bin + +# Menu: Optimization +adafruit_pixeltrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_pixeltrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_pixeltrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_pixeltrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_pixeltrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_pixeltrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_pixeltrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_pixeltrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_pixeltrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_pixeltrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_pixeltrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_pixeltrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_pixeltrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_pixeltrinkey_m0.menu.debug.off=Off +adafruit_pixeltrinkey_m0.menu.debug.on=On +adafruit_pixeltrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit TRRS Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_TRRStrinkey_m0.name=Adafruit TRRS Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_TRRStrinkey_m0.vid.0=0x239A +adafruit_TRRStrinkey_m0.pid.0=0x8157 +adafruit_TRRStrinkey_m0.vid.1=0x239A +adafruit_TRRStrinkey_m0.pid.1=0x0157 +adafruit_TRRStrinkey_m0.vid.2=0x239A +adafruit_TRRStrinkey_m0.pid.2=0x8158 + +# Upload +adafruit_TRRStrinkey_m0.upload.tool=bossac18 +adafruit_TRRStrinkey_m0.upload.protocol=sam-ba +adafruit_TRRStrinkey_m0.upload.maximum_size=262144 +adafruit_TRRStrinkey_m0.upload.offset=0x2000 +adafruit_TRRStrinkey_m0.upload.use_1200bps_touch=true +adafruit_TRRStrinkey_m0.upload.wait_for_upload_port=true +adafruit_TRRStrinkey_m0.upload.native_usb=true + +# Build +adafruit_TRRStrinkey_m0.build.mcu=cortex-m0plus +adafruit_TRRStrinkey_m0.build.f_cpu=48000000L +adafruit_TRRStrinkey_m0.build.usb_product="TRRS Trinkey M0" +adafruit_TRRStrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_TRRStrinkey_m0.build.board=TRRSTRINKEY_M0 +adafruit_TRRStrinkey_m0.build.core=arduino +adafruit_TRRStrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_TRRSTRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_TRRStrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_TRRStrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_TRRStrinkey_m0.build.variant=trrstrinkey_m0 +adafruit_TRRStrinkey_m0.build.variant_system_lib= +adafruit_TRRStrinkey_m0.build.vid=0x239A +adafruit_TRRStrinkey_m0.build.pid=0x8157 +adafruit_TRRStrinkey_m0.bootloader.tool=openocd +adafruit_TRRStrinkey_m0.bootloader.file=trrstrinkey_m0/bootloader-TRRStrinkey_m0.bin + +# Menu: Optimization +adafruit_TRRStrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_TRRStrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_TRRStrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_TRRStrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_TRRStrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_TRRStrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_TRRStrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_TRRStrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_TRRStrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_TRRStrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_TRRStrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_TRRStrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_TRRStrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_TRRStrinkey_m0.menu.debug.off=Off +adafruit_TRRStrinkey_m0.menu.debug.on=On +adafruit_TRRStrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Thumbstick Trinkey M0 (SAMD21) +# ----------------------------------- +adafruit_thumbsticktrinkey_m0.name=Adafruit Thumbstick Trinkey M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_thumbsticktrinkey_m0.vid.0=0x239A +adafruit_thumbsticktrinkey_m0.pid.0=0x8159 +adafruit_thumbsticktrinkey_m0.vid.1=0x239A +adafruit_thumbsticktrinkey_m0.pid.1=0x0159 +adafruit_thumbsticktrinkey_m0.vid.2=0x239A +adafruit_thumbsticktrinkey_m0.pid.2=0x8160 + +# Upload +adafruit_thumbsticktrinkey_m0.upload.tool=bossac18 +adafruit_thumbsticktrinkey_m0.upload.protocol=sam-ba +adafruit_thumbsticktrinkey_m0.upload.maximum_size=262144 +adafruit_thumbsticktrinkey_m0.upload.offset=0x2000 +adafruit_thumbsticktrinkey_m0.upload.use_1200bps_touch=true +adafruit_thumbsticktrinkey_m0.upload.wait_for_upload_port=true +adafruit_thumbsticktrinkey_m0.upload.native_usb=true + +# Build +adafruit_thumbsticktrinkey_m0.build.mcu=cortex-m0plus +adafruit_thumbsticktrinkey_m0.build.f_cpu=48000000L +adafruit_thumbsticktrinkey_m0.build.usb_product="Thumbstick Trinkey M0" +adafruit_thumbsticktrinkey_m0.build.usb_manufacturer="Adafruit" +adafruit_thumbsticktrinkey_m0.build.board=THUMBSTICKTRINKEY_M0 +adafruit_thumbsticktrinkey_m0.build.core=arduino +adafruit_thumbsticktrinkey_m0.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_THUMBSTICKTRINKEY_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_thumbsticktrinkey_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_thumbsticktrinkey_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_thumbsticktrinkey_m0.build.variant=thumbsticktrinkey_m0 +adafruit_thumbsticktrinkey_m0.build.variant_system_lib= +adafruit_thumbsticktrinkey_m0.build.vid=0x239A +adafruit_thumbsticktrinkey_m0.build.pid=0x8159 +adafruit_thumbsticktrinkey_m0.bootloader.tool=openocd +adafruit_thumbsticktrinkey_m0.bootloader.file=thumbsticktrinkey_m0/bootloader-thumbsticktrinkey_m0.bin + +# Menu: Optimization +adafruit_thumbsticktrinkey_m0.menu.opt.small=Small (-Os) (standard) +adafruit_thumbsticktrinkey_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_thumbsticktrinkey_m0.menu.opt.fast=Fast (-O2) +adafruit_thumbsticktrinkey_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_thumbsticktrinkey_m0.menu.opt.faster=Faster (-O3) +adafruit_thumbsticktrinkey_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_thumbsticktrinkey_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_thumbsticktrinkey_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_thumbsticktrinkey_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_thumbsticktrinkey_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_thumbsticktrinkey_m0.menu.usbstack.arduino=Arduino +adafruit_thumbsticktrinkey_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_thumbsticktrinkey_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_thumbsticktrinkey_m0.menu.debug.off=Off +adafruit_thumbsticktrinkey_m0.menu.debug.on=On +adafruit_thumbsticktrinkey_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit ItsyBitsy M0 Express (SAMD21) +# ----------------------------------- +adafruit_itsybitsy_m0.name=Adafruit ItsyBitsy M0 Express (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_itsybitsy_m0.vid.0=0x239A +adafruit_itsybitsy_m0.pid.0=0x800F +adafruit_itsybitsy_m0.vid.1=0x239A +adafruit_itsybitsy_m0.pid.1=0x000F +adafruit_itsybitsy_m0.vid.2=0x239A +adafruit_itsybitsy_m0.pid.2=0x8012 + +# Upload +adafruit_itsybitsy_m0.upload.tool=bossac18 +adafruit_itsybitsy_m0.upload.protocol=sam-ba +adafruit_itsybitsy_m0.upload.maximum_size=262144 +adafruit_itsybitsy_m0.upload.offset=0x2000 +adafruit_itsybitsy_m0.upload.use_1200bps_touch=true +adafruit_itsybitsy_m0.upload.wait_for_upload_port=true +adafruit_itsybitsy_m0.upload.native_usb=true + +# Build +adafruit_itsybitsy_m0.build.mcu=cortex-m0plus +adafruit_itsybitsy_m0.build.f_cpu=48000000L +adafruit_itsybitsy_m0.build.usb_product="ItsyBitsy M0 Express" +adafruit_itsybitsy_m0.build.usb_manufacturer="Adafruit" +adafruit_itsybitsy_m0.build.board=ITSYBITSY_M0 +adafruit_itsybitsy_m0.build.core=arduino +adafruit_itsybitsy_m0.build.extra_flags=-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_ITSYBITSY_M0 -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_itsybitsy_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_itsybitsy_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_itsybitsy_m0.build.variant=itsybitsy_m0 +adafruit_itsybitsy_m0.build.variant_system_lib= +adafruit_itsybitsy_m0.build.vid=0x239A +adafruit_itsybitsy_m0.build.pid=0x800F +adafruit_itsybitsy_m0.bootloader.tool=openocd +adafruit_itsybitsy_m0.bootloader.file=itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.bin + +# Menu: Optimization +adafruit_itsybitsy_m0.menu.opt.small=Small (-Os) (standard) +adafruit_itsybitsy_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_itsybitsy_m0.menu.opt.fast=Fast (-O2) +adafruit_itsybitsy_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_itsybitsy_m0.menu.opt.faster=Faster (-O3) +adafruit_itsybitsy_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_itsybitsy_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_itsybitsy_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_itsybitsy_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_itsybitsy_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_itsybitsy_m0.menu.usbstack.arduino=Arduino +adafruit_itsybitsy_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_itsybitsy_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_itsybitsy_m0.menu.debug.off=Off +adafruit_itsybitsy_m0.menu.debug.on=On +adafruit_itsybitsy_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit pIRKey (SAMD21) +# ----------------------------------- +adafruit_pirkey.name=Adafruit pIRKey (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_pirkey.vid.0=0x239A +adafruit_pirkey.pid.0=0x8027 +adafruit_pirkey.vid.1=0x239A +adafruit_pirkey.pid.1=0x0027 +adafruit_pirkey.vid.2=0x239A +adafruit_pirkey.pid.2=0x8028 + +# Upload +adafruit_pirkey.upload.tool=bossac18 +adafruit_pirkey.upload.protocol=sam-ba +adafruit_pirkey.upload.maximum_size=262144 +adafruit_pirkey.upload.offset=0x2000 +adafruit_pirkey.upload.use_1200bps_touch=true +adafruit_pirkey.upload.wait_for_upload_port=true +adafruit_pirkey.upload.native_usb=true + +# Build +adafruit_pirkey.build.mcu=cortex-m0plus +adafruit_pirkey.build.f_cpu=48000000L +adafruit_pirkey.build.usb_product="pIRKey" +adafruit_pirkey.build.usb_manufacturer="Adafruit" +adafruit_pirkey.build.board=PIRKEY +adafruit_pirkey.build.core=arduino +adafruit_pirkey.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PIRKEY -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_pirkey.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_pirkey.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_pirkey.build.variant=pirkey +adafruit_pirkey.build.variant_system_lib= +adafruit_pirkey.build.vid=0x239A +adafruit_pirkey.build.pid=0x8027 +adafruit_pirkey.bootloader.tool=openocd +adafruit_pirkey.bootloader.file=pirkey/bootloader-pirkey-v2.0.0-adafruit.5.bin + +# Menu: Optimization +adafruit_pirkey.menu.opt.small=Small (-Os) (standard) +adafruit_pirkey.menu.opt.small.build.flags.optimize=-Os +adafruit_pirkey.menu.opt.fast=Fast (-O2) +adafruit_pirkey.menu.opt.fast.build.flags.optimize=-O2 +adafruit_pirkey.menu.opt.faster=Faster (-O3) +adafruit_pirkey.menu.opt.faster.build.flags.optimize=-O3 +adafruit_pirkey.menu.opt.fastest=Fastest (-Ofast) +adafruit_pirkey.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_pirkey.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_pirkey.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_pirkey.menu.usbstack.arduino=Arduino +adafruit_pirkey.menu.usbstack.tinyusb=TinyUSB +adafruit_pirkey.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_pirkey.menu.debug.off=Off +adafruit_pirkey.menu.debug.on=On +adafruit_pirkey.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Hallowing M0 (SAMD21) +# ----------------------------------- +adafruit_hallowing.name=Adafruit Hallowing M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_hallowing.vid.0=0x239A +adafruit_hallowing.pid.0=0xDEAD +adafruit_hallowing.vid.1=0x239A +adafruit_hallowing.pid.1=0xD1ED +adafruit_hallowing.vid.2=0x239A +adafruit_hallowing.pid.2=0xB000 + +# Upload +adafruit_hallowing.upload.tool=bossac18 +adafruit_hallowing.upload.protocol=sam-ba +adafruit_hallowing.upload.maximum_size=262144 +adafruit_hallowing.upload.offset=0x2000 +adafruit_hallowing.upload.use_1200bps_touch=true +adafruit_hallowing.upload.wait_for_upload_port=true +adafruit_hallowing.upload.native_usb=true + +# Build +adafruit_hallowing.build.mcu=cortex-m0plus +adafruit_hallowing.build.f_cpu=48000000L +adafruit_hallowing.build.usb_product="Hallowing M0" +adafruit_hallowing.build.usb_manufacturer="Adafruit" +adafruit_hallowing.build.board=SAMD_HALLOWING +adafruit_hallowing.build.core=arduino +adafruit_hallowing.build.extra_flags=-D__SAMD21G18A__ -DCRYSTALLESS -DARDUINO_SAMD_HALLOWING_M0 -DADAFRUIT_HALLOWING -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_hallowing.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_hallowing.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_hallowing.build.variant=hallowing_m0_express +adafruit_hallowing.build.variant_system_lib= +adafruit_hallowing.build.vid=0x239A +adafruit_hallowing.build.pid=0xDEAD +adafruit_hallowing.bootloader.tool=openocd +adafruit_hallowing.bootloader.file=hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.bin + +# Menu: Optimization +adafruit_hallowing.menu.opt.small=Small (-Os) (standard) +adafruit_hallowing.menu.opt.small.build.flags.optimize=-Os +adafruit_hallowing.menu.opt.fast=Fast (-O2) +adafruit_hallowing.menu.opt.fast.build.flags.optimize=-O2 +adafruit_hallowing.menu.opt.faster=Faster (-O3) +adafruit_hallowing.menu.opt.faster.build.flags.optimize=-O3 +adafruit_hallowing.menu.opt.fastest=Fastest (-Ofast) +adafruit_hallowing.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_hallowing.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_hallowing.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_hallowing.menu.usbstack.arduino=Arduino +adafruit_hallowing.menu.usbstack.tinyusb=TinyUSB +adafruit_hallowing.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_hallowing.menu.debug.off=Off +adafruit_hallowing.menu.debug.on=On +adafruit_hallowing.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Crickit M0 (SAMD21) +# ----------------------------------- +adafruit_crickit_m0.name=Adafruit Crickit M0 (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_crickit_m0.vid.0=0x239A +adafruit_crickit_m0.pid.0=0x802D +adafruit_crickit_m0.vid.1=0x239A +adafruit_crickit_m0.pid.1=0x002D +adafruit_crickit_m0.vid.2=0x239A +adafruit_crickit_m0.pid.2=0x802D + +# Upload +adafruit_crickit_m0.upload.tool=bossac18 +adafruit_crickit_m0.upload.protocol=sam-ba +adafruit_crickit_m0.upload.maximum_size=262144 +adafruit_crickit_m0.upload.offset=0x2000 +adafruit_crickit_m0.upload.use_1200bps_touch=true +adafruit_crickit_m0.upload.wait_for_upload_port=true +adafruit_crickit_m0.upload.native_usb=true + +# Build +adafruit_crickit_m0.build.mcu=cortex-m0plus +adafruit_crickit_m0.build.f_cpu=48000000L +adafruit_crickit_m0.build.usb_product="Crickit M0" +adafruit_crickit_m0.build.usb_manufacturer="Adafruit" +adafruit_crickit_m0.build.board=CRICKIT_M0 +adafruit_crickit_m0.build.core=arduino +adafruit_crickit_m0.build.extra_flags=-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_CRICKIT_M0 -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_crickit_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_crickit_m0.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_crickit_m0.build.variant=crickit_m0 +adafruit_crickit_m0.build.variant_system_lib= +adafruit_crickit_m0.build.vid=0x239A +adafruit_crickit_m0.build.pid=0x802D +adafruit_crickit_m0.bootloader.tool=openocd +adafruit_crickit_m0.bootloader.file=crickit/samd21_sam_ba.bin + +# Menu: Optimization +adafruit_crickit_m0.menu.opt.small=Small (-Os) (standard) +adafruit_crickit_m0.menu.opt.small.build.flags.optimize=-Os +adafruit_crickit_m0.menu.opt.fast=Fast (-O2) +adafruit_crickit_m0.menu.opt.fast.build.flags.optimize=-O2 +adafruit_crickit_m0.menu.opt.faster=Faster (-O3) +adafruit_crickit_m0.menu.opt.faster.build.flags.optimize=-O3 +adafruit_crickit_m0.menu.opt.fastest=Fastest (-Ofast) +adafruit_crickit_m0.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_crickit_m0.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_crickit_m0.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_crickit_m0.menu.usbstack.arduino=Arduino +adafruit_crickit_m0.menu.usbstack.tinyusb=TinyUSB +adafruit_crickit_m0.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_crickit_m0.menu.debug.off=Off +adafruit_crickit_m0.menu.debug.on=On +adafruit_crickit_m0.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit BLM Badge (SAMD21) +# ----------------------------------- +adafruit_blm_badge.name=Adafruit BLM Badge (SAMD21) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_blm_badge.vid.0=0x239A +adafruit_blm_badge.pid.0=0x80BF +adafruit_blm_badge.vid.1=0x239A +adafruit_blm_badge.pid.1=0x00BF +adafruit_blm_badge.vid.2=0x239A +adafruit_blm_badge.pid.2=0x80C0 + +# Upload +adafruit_blm_badge.upload.tool=bossac18 +adafruit_blm_badge.upload.protocol=sam-ba +adafruit_blm_badge.upload.maximum_size=262144 +adafruit_blm_badge.upload.offset=0x2000 +adafruit_blm_badge.upload.use_1200bps_touch=true +adafruit_blm_badge.upload.wait_for_upload_port=true +adafruit_blm_badge.upload.native_usb=true + +# Build +adafruit_blm_badge.build.mcu=cortex-m0plus +adafruit_blm_badge.build.f_cpu=48000000L +adafruit_blm_badge.build.usb_product="BLM Badge" +adafruit_blm_badge.build.usb_manufacturer="Adafruit" +adafruit_blm_badge.build.board=BLM_BADGE_M0 +adafruit_blm_badge.build.core=arduino +adafruit_blm_badge.build.extra_flags=-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_BLM_BADGE -DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS {build.usb_flags} +adafruit_blm_badge.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_blm_badge.build.openocdscript=scripts/openocd/daplink_samd21.cfg +adafruit_blm_badge.build.variant=blm_badge +adafruit_blm_badge.build.variant_system_lib= +adafruit_blm_badge.build.vid=0x239A +adafruit_blm_badge.build.pid=0x80BF +adafruit_blm_badge.bootloader.tool=openocd +adafruit_blm_badge.bootloader.file=blmbadge/bootloader-blm_badge.bin + +# Menu: Optimization +adafruit_blm_badge.menu.opt.small=Small (-Os) (standard) +adafruit_blm_badge.menu.opt.small.build.flags.optimize=-Os +adafruit_blm_badge.menu.opt.fast=Fast (-O2) +adafruit_blm_badge.menu.opt.fast.build.flags.optimize=-O2 +adafruit_blm_badge.menu.opt.faster=Faster (-O3) +adafruit_blm_badge.menu.opt.faster.build.flags.optimize=-O3 +adafruit_blm_badge.menu.opt.fastest=Fastest (-Ofast) +adafruit_blm_badge.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_blm_badge.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_blm_badge.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: USB Stack +adafruit_blm_badge.menu.usbstack.arduino=Arduino +adafruit_blm_badge.menu.usbstack.tinyusb=TinyUSB +adafruit_blm_badge.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_blm_badge.menu.debug.off=Off +adafruit_blm_badge.menu.debug.on=On +adafruit_blm_badge.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Metro M4 (SAMD51) +# ----------------------------------- +adafruit_metro_m4.name=Adafruit Metro M4 (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_metro_m4.vid.0=0x239A +adafruit_metro_m4.pid.0=0x8020 +adafruit_metro_m4.vid.1=0x239A +adafruit_metro_m4.pid.1=0x0020 +adafruit_metro_m4.vid.2=0x239A +adafruit_metro_m4.pid.2=0x8021 +adafruit_metro_m4.vid.3=0x239A +adafruit_metro_m4.pid.3=0x0021 + +# Upload +adafruit_metro_m4.upload.tool=bossac18 +adafruit_metro_m4.upload.protocol=sam-ba +adafruit_metro_m4.upload.maximum_size=507904 +adafruit_metro_m4.upload.offset=0x4000 +adafruit_metro_m4.upload.use_1200bps_touch=true +adafruit_metro_m4.upload.wait_for_upload_port=true +adafruit_metro_m4.upload.native_usb=true + +# Build +adafruit_metro_m4.build.mcu=cortex-m4 +adafruit_metro_m4.build.f_cpu=120000000L +adafruit_metro_m4.build.usb_product="Metro M4" +adafruit_metro_m4.build.usb_manufacturer="Adafruit" +adafruit_metro_m4.build.board=METRO_M4 +adafruit_metro_m4.build.core=arduino +adafruit_metro_m4.build.extra_flags=-D__SAMD51J19A__ -DADAFRUIT_METRO_M4_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_metro_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_metro_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_metro_m4.build.variant=metro_m4 +adafruit_metro_m4.build.variant_system_lib= +adafruit_metro_m4.build.vid=0x239A +adafruit_metro_m4.build.pid=0x8020 +adafruit_metro_m4.bootloader.tool=openocd +adafruit_metro_m4.bootloader.file=metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin +adafruit_metro_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_metro_m4.menu.cache.on=Enabled +adafruit_metro_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_metro_m4.menu.cache.off=Disabled +adafruit_metro_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_metro_m4.menu.speed.120=120 MHz (standard) +adafruit_metro_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_metro_m4.menu.speed.150=150 MHz (overclock) +adafruit_metro_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_metro_m4.menu.speed.180=180 MHz (overclock) +adafruit_metro_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_metro_m4.menu.speed.200=200 MHz (overclock) +adafruit_metro_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_metro_m4.menu.opt.small=Small (-Os) (standard) +adafruit_metro_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_metro_m4.menu.opt.fast=Fast (-O2) +adafruit_metro_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_metro_m4.menu.opt.faster=Faster (-O3) +adafruit_metro_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_metro_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_metro_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_metro_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_metro_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_metro_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_metro_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_metro_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_metro_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_metro_m4.menu.usbstack.arduino=Arduino +adafruit_metro_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_metro_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_metro_m4.menu.debug.off=Off +adafruit_metro_m4.menu.debug.on=On +adafruit_metro_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Grand Central M4 (SAMD51) +# ----------------------------------- +adafruit_grandcentral_m4.name=Adafruit Grand Central M4 (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_grandcentral_m4.vid.0=0x239A +adafruit_grandcentral_m4.pid.0=0x8031 +adafruit_grandcentral_m4.vid.1=0x239A +adafruit_grandcentral_m4.pid.1=0x0031 +adafruit_grandcentral_m4.vid.2=0x239A +adafruit_grandcentral_m4.pid.2=0x0032 + +# Upload +adafruit_grandcentral_m4.upload.tool=bossac18 +adafruit_grandcentral_m4.upload.protocol=sam-ba +adafruit_grandcentral_m4.upload.maximum_size=1032192 +adafruit_grandcentral_m4.upload.offset=0x4000 +adafruit_grandcentral_m4.upload.use_1200bps_touch=true +adafruit_grandcentral_m4.upload.wait_for_upload_port=true +adafruit_grandcentral_m4.upload.native_usb=true + +# Build +adafruit_grandcentral_m4.build.mcu=cortex-m4 +adafruit_grandcentral_m4.build.f_cpu=120000000L +adafruit_grandcentral_m4.build.usb_product="Grand Central M4" +adafruit_grandcentral_m4.build.usb_manufacturer="Adafruit" +adafruit_grandcentral_m4.build.board=GRAND_CENTRAL_M4 +adafruit_grandcentral_m4.build.core=arduino +adafruit_grandcentral_m4.build.extra_flags=-D__SAMD51P20A__ -DADAFRUIT_GRAND_CENTRAL_M4 -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_grandcentral_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_grandcentral_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_grandcentral_m4.build.variant=grand_central_m4 +adafruit_grandcentral_m4.build.variant_system_lib= +adafruit_grandcentral_m4.build.vid=0x239A +adafruit_grandcentral_m4.build.pid=0x8031 +adafruit_grandcentral_m4.bootloader.tool=openocd +adafruit_grandcentral_m4.bootloader.file=grand_central_m4/bootloader-grandcentral_m4.bin +adafruit_grandcentral_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_grandcentral_m4.menu.cache.on=Enabled +adafruit_grandcentral_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_grandcentral_m4.menu.cache.off=Disabled +adafruit_grandcentral_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_grandcentral_m4.menu.speed.120=120 MHz (standard) +adafruit_grandcentral_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_grandcentral_m4.menu.speed.150=150 MHz (overclock) +adafruit_grandcentral_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_grandcentral_m4.menu.speed.180=180 MHz (overclock) +adafruit_grandcentral_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_grandcentral_m4.menu.speed.200=200 MHz (overclock) +adafruit_grandcentral_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_grandcentral_m4.menu.opt.small=Small (-Os) (standard) +adafruit_grandcentral_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_grandcentral_m4.menu.opt.fast=Fast (-O2) +adafruit_grandcentral_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_grandcentral_m4.menu.opt.faster=Faster (-O3) +adafruit_grandcentral_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_grandcentral_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_grandcentral_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_grandcentral_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_grandcentral_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_grandcentral_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_grandcentral_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_grandcentral_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_grandcentral_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_grandcentral_m4.menu.usbstack.arduino=Arduino +adafruit_grandcentral_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_grandcentral_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_grandcentral_m4.menu.debug.off=Off +adafruit_grandcentral_m4.menu.debug.on=On +adafruit_grandcentral_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit ItsyBitsy M4 (SAMD51) +# ----------------------------------- +adafruit_itsybitsy_m4.name=Adafruit ItsyBitsy M4 (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_itsybitsy_m4.vid.0=0x239A +adafruit_itsybitsy_m4.pid.0=0x802B +adafruit_itsybitsy_m4.vid.1=0x239A +adafruit_itsybitsy_m4.pid.1=0x002B + +# Upload +adafruit_itsybitsy_m4.upload.tool=bossac18 +adafruit_itsybitsy_m4.upload.protocol=sam-ba +adafruit_itsybitsy_m4.upload.maximum_size=507904 +adafruit_itsybitsy_m4.upload.offset=0x4000 +adafruit_itsybitsy_m4.upload.use_1200bps_touch=true +adafruit_itsybitsy_m4.upload.wait_for_upload_port=true +adafruit_itsybitsy_m4.upload.native_usb=true + +# Build +adafruit_itsybitsy_m4.build.mcu=cortex-m4 +adafruit_itsybitsy_m4.build.f_cpu=120000000L +adafruit_itsybitsy_m4.build.usb_product="ItsyBitsy M4" +adafruit_itsybitsy_m4.build.usb_manufacturer="Adafruit" +adafruit_itsybitsy_m4.build.board=ITSYBITSY_M4 +adafruit_itsybitsy_m4.build.core=arduino +adafruit_itsybitsy_m4.build.extra_flags=-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_ITSYBITSY_M4_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_itsybitsy_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_itsybitsy_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_itsybitsy_m4.build.variant=itsybitsy_m4 +adafruit_itsybitsy_m4.build.variant_system_lib= +adafruit_itsybitsy_m4.build.vid=0x239A +adafruit_itsybitsy_m4.build.pid=0x802B +adafruit_itsybitsy_m4.bootloader.tool=openocd +adafruit_itsybitsy_m4.bootloader.file=itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.bin +adafruit_itsybitsy_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_itsybitsy_m4.menu.cache.on=Enabled +adafruit_itsybitsy_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_itsybitsy_m4.menu.cache.off=Disabled +adafruit_itsybitsy_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_itsybitsy_m4.menu.speed.120=120 MHz (standard) +adafruit_itsybitsy_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_itsybitsy_m4.menu.speed.150=150 MHz (overclock) +adafruit_itsybitsy_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_itsybitsy_m4.menu.speed.180=180 MHz (overclock) +adafruit_itsybitsy_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_itsybitsy_m4.menu.speed.200=200 MHz (overclock) +adafruit_itsybitsy_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_itsybitsy_m4.menu.opt.small=Small (-Os) (standard) +adafruit_itsybitsy_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_itsybitsy_m4.menu.opt.fast=Fast (-O2) +adafruit_itsybitsy_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_itsybitsy_m4.menu.opt.faster=Faster (-O3) +adafruit_itsybitsy_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_itsybitsy_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_itsybitsy_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_itsybitsy_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_itsybitsy_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_itsybitsy_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_itsybitsy_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_itsybitsy_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_itsybitsy_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_itsybitsy_m4.menu.usbstack.arduino=Arduino +adafruit_itsybitsy_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_itsybitsy_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_itsybitsy_m4.menu.debug.off=Off +adafruit_itsybitsy_m4.menu.debug.on=On +adafruit_itsybitsy_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Feather M4 Express (SAMD51) +# ----------------------------------- +adafruit_feather_m4.name=Adafruit Feather M4 Express (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_feather_m4.vid.0=0x239A +adafruit_feather_m4.pid.0=0x8022 +adafruit_feather_m4.vid.1=0x239A +adafruit_feather_m4.pid.1=0x0022 +adafruit_feather_m4.vid.2=0x239A +adafruit_feather_m4.pid.2=0x8026 + +# Upload +adafruit_feather_m4.upload.tool=bossac18 +adafruit_feather_m4.upload.protocol=sam-ba +adafruit_feather_m4.upload.maximum_size=507904 +adafruit_feather_m4.upload.offset=0x4000 +adafruit_feather_m4.upload.use_1200bps_touch=true +adafruit_feather_m4.upload.wait_for_upload_port=true +adafruit_feather_m4.upload.native_usb=true + +# Build +adafruit_feather_m4.build.mcu=cortex-m4 +adafruit_feather_m4.build.f_cpu=120000000L +adafruit_feather_m4.build.usb_product="Feather M4 Express" +adafruit_feather_m4.build.usb_manufacturer="Adafruit" +adafruit_feather_m4.build.board=FEATHER_M4 +adafruit_feather_m4.build.core=arduino +adafruit_feather_m4.build.extra_flags=-D__SAMD51J19A__ -DADAFRUIT_FEATHER_M4_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_feather_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_feather_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_feather_m4.build.variant=feather_m4 +adafruit_feather_m4.build.variant_system_lib= +adafruit_feather_m4.build.vid=0x239A +adafruit_feather_m4.build.pid=0x8022 +adafruit_feather_m4.bootloader.tool=openocd +adafruit_feather_m4.bootloader.file=featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin +adafruit_feather_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_feather_m4.menu.cache.on=Enabled +adafruit_feather_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_feather_m4.menu.cache.off=Disabled +adafruit_feather_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_feather_m4.menu.speed.120=120 MHz (standard) +adafruit_feather_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_feather_m4.menu.speed.150=150 MHz (overclock) +adafruit_feather_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_feather_m4.menu.speed.180=180 MHz (overclock) +adafruit_feather_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_feather_m4.menu.speed.200=200 MHz (overclock) +adafruit_feather_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_feather_m4.menu.opt.small=Small (-Os) (standard) +adafruit_feather_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_feather_m4.menu.opt.fast=Fast (-O2) +adafruit_feather_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_feather_m4.menu.opt.faster=Faster (-O3) +adafruit_feather_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_feather_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_feather_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_feather_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_feather_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_feather_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_feather_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_feather_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_feather_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_feather_m4.menu.usbstack.arduino=Arduino +adafruit_feather_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_feather_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_feather_m4.menu.debug.off=Off +adafruit_feather_m4.menu.debug.on=On +adafruit_feather_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Feather M4 CAN (SAME51) +# ----------------------------------- +adafruit_feather_m4_can.name=Adafruit Feather M4 CAN (SAME51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_feather_m4_can.vid.0=0x239A +adafruit_feather_m4_can.pid.0=0x80CD +adafruit_feather_m4_can.vid.1=0x239A +adafruit_feather_m4_can.pid.1=0x00CD + +# Upload +adafruit_feather_m4_can.upload.tool=bossac18 +adafruit_feather_m4_can.upload.protocol=sam-ba +adafruit_feather_m4_can.upload.maximum_size=507904 +adafruit_feather_m4_can.upload.offset=0x4000 +adafruit_feather_m4_can.upload.use_1200bps_touch=true +adafruit_feather_m4_can.upload.wait_for_upload_port=true +adafruit_feather_m4_can.upload.native_usb=true + +# Build +adafruit_feather_m4_can.build.mcu=cortex-m4 +adafruit_feather_m4_can.build.f_cpu=120000000L +adafruit_feather_m4_can.build.usb_product="Feather M4 CAN" +adafruit_feather_m4_can.build.usb_manufacturer="Adafruit" +adafruit_feather_m4_can.build.board=FEATHER_M4_CAN +adafruit_feather_m4_can.build.core=arduino +adafruit_feather_m4_can.build.extra_flags=-D__SAME51J19A__ -DADAFRUIT_FEATHER_M4_EXPRESS -DADAFRUIT_FEATHER_M4_CAN -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_feather_m4_can.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_feather_m4_can.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_feather_m4_can.build.variant=feather_m4_can +adafruit_feather_m4_can.build.variant_system_lib= +adafruit_feather_m4_can.build.vid=0x239A +adafruit_feather_m4_can.build.pid=0x80CD +adafruit_feather_m4_can.bootloader.tool=openocd +adafruit_feather_m4_can.bootloader.file=featherM4/bootloader-feather_m4_express-v2.0.0-adafruit.5.bin +adafruit_feather_m4_can.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_feather_m4_can.menu.cache.on=Enabled +adafruit_feather_m4_can.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_feather_m4_can.menu.cache.off=Disabled +adafruit_feather_m4_can.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_feather_m4_can.menu.speed.120=120 MHz (standard) +adafruit_feather_m4_can.menu.speed.120.build.f_cpu=120000000L +adafruit_feather_m4_can.menu.speed.150=150 MHz (overclock) +adafruit_feather_m4_can.menu.speed.150.build.f_cpu=150000000L +adafruit_feather_m4_can.menu.speed.180=180 MHz (overclock) +adafruit_feather_m4_can.menu.speed.180.build.f_cpu=180000000L +adafruit_feather_m4_can.menu.speed.200=200 MHz (overclock) +adafruit_feather_m4_can.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_feather_m4_can.menu.opt.small=Small (-Os) (standard) +adafruit_feather_m4_can.menu.opt.small.build.flags.optimize=-Os +adafruit_feather_m4_can.menu.opt.fast=Fast (-O2) +adafruit_feather_m4_can.menu.opt.fast.build.flags.optimize=-O2 +adafruit_feather_m4_can.menu.opt.faster=Faster (-O3) +adafruit_feather_m4_can.menu.opt.faster.build.flags.optimize=-O3 +adafruit_feather_m4_can.menu.opt.fastest=Fastest (-Ofast) +adafruit_feather_m4_can.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_feather_m4_can.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_feather_m4_can.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_feather_m4_can.menu.maxqspi.50=50 MHz (standard) +adafruit_feather_m4_can.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_feather_m4_can.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_feather_m4_can.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_feather_m4_can.menu.usbstack.arduino=Arduino +adafruit_feather_m4_can.menu.usbstack.tinyusb=TinyUSB +adafruit_feather_m4_can.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_feather_m4_can.menu.debug.off=Off +adafruit_feather_m4_can.menu.debug.on=On +adafruit_feather_m4_can.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Trellis M4 (SAMD51) +# ----------------------------------- +adafruit_trellis_m4.name=Adafruit Trellis M4 (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_trellis_m4.vid.0=0x239A +adafruit_trellis_m4.pid.0=0x802F +adafruit_trellis_m4.vid.1=0x239A +adafruit_trellis_m4.pid.1=0x002F +adafruit_trellis_m4.vid.2=0x239A +adafruit_trellis_m4.pid.2=0x0030 + +# Upload +adafruit_trellis_m4.upload.tool=bossac18 +adafruit_trellis_m4.upload.protocol=sam-ba +adafruit_trellis_m4.upload.maximum_size=507904 +adafruit_trellis_m4.upload.offset=0x4000 +adafruit_trellis_m4.upload.use_1200bps_touch=true +adafruit_trellis_m4.upload.wait_for_upload_port=true +adafruit_trellis_m4.upload.native_usb=true + +# Build +adafruit_trellis_m4.build.mcu=cortex-m4 +adafruit_trellis_m4.build.f_cpu=120000000L +adafruit_trellis_m4.build.usb_product="Trellis M4" +adafruit_trellis_m4.build.usb_manufacturer="Adafruit" +adafruit_trellis_m4.build.board=TRELLIS_M4 +adafruit_trellis_m4.build.core=arduino +adafruit_trellis_m4.build.extra_flags=-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_TRELLIS_M4_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_trellis_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_trellis_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_trellis_m4.build.variant=trellis_m4 +adafruit_trellis_m4.build.variant_system_lib= +adafruit_trellis_m4.build.vid=0x239A +adafruit_trellis_m4.build.pid=0x802F +adafruit_trellis_m4.bootloader.tool=openocd +adafruit_trellis_m4.bootloader.file=trellisM4/bootloader-trellis_m4-v2.0.0-adafruit.5.bin +adafruit_trellis_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_trellis_m4.menu.cache.on=Enabled +adafruit_trellis_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_trellis_m4.menu.cache.off=Disabled +adafruit_trellis_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_trellis_m4.menu.speed.120=120 MHz (standard) +adafruit_trellis_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_trellis_m4.menu.speed.150=150 MHz (overclock) +adafruit_trellis_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_trellis_m4.menu.speed.180=180 MHz (overclock) +adafruit_trellis_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_trellis_m4.menu.speed.200=200 MHz (overclock) +adafruit_trellis_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_trellis_m4.menu.opt.small=Small (-Os) (standard) +adafruit_trellis_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_trellis_m4.menu.opt.fast=Fast (-O2) +adafruit_trellis_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_trellis_m4.menu.opt.faster=Faster (-O3) +adafruit_trellis_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_trellis_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_trellis_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_trellis_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_trellis_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_trellis_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_trellis_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_trellis_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_trellis_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_trellis_m4.menu.usbstack.arduino=Arduino +adafruit_trellis_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_trellis_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_trellis_m4.menu.debug.off=Off +adafruit_trellis_m4.menu.debug.on=On +adafruit_trellis_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit PyPortal M4 (SAMD51) +# ----------------------------------- +adafruit_pyportal_m4.name=Adafruit PyPortal M4 (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_pyportal_m4.vid.0=0x239A +adafruit_pyportal_m4.pid.0=0x8035 +adafruit_pyportal_m4.vid.1=0x239A +adafruit_pyportal_m4.pid.1=0x0035 +adafruit_pyportal_m4.vid.2=0x239A +adafruit_pyportal_m4.pid.2=0x8036 + +# Upload +adafruit_pyportal_m4.upload.tool=bossac18 +adafruit_pyportal_m4.upload.protocol=sam-ba +adafruit_pyportal_m4.upload.maximum_size=1032192 +adafruit_pyportal_m4.upload.offset=0x4000 +adafruit_pyportal_m4.upload.use_1200bps_touch=true +adafruit_pyportal_m4.upload.wait_for_upload_port=true +adafruit_pyportal_m4.upload.native_usb=true + +# Build +adafruit_pyportal_m4.build.mcu=cortex-m4 +adafruit_pyportal_m4.build.f_cpu=120000000L +adafruit_pyportal_m4.build.usb_product="PyPortal M4" +adafruit_pyportal_m4.build.usb_manufacturer="Adafruit" +adafruit_pyportal_m4.build.board=PYPORTAL_M4 +adafruit_pyportal_m4.build.core=arduino +adafruit_pyportal_m4.build.extra_flags=-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYPORTAL -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_pyportal_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_pyportal_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_pyportal_m4.build.variant=pyportal_m4 +adafruit_pyportal_m4.build.variant_system_lib= +adafruit_pyportal_m4.build.vid=0x239A +adafruit_pyportal_m4.build.pid=0x8035 +adafruit_pyportal_m4.bootloader.tool=openocd +adafruit_pyportal_m4.bootloader.file=metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin +adafruit_pyportal_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_pyportal_m4.menu.cache.on=Enabled +adafruit_pyportal_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_pyportal_m4.menu.cache.off=Disabled +adafruit_pyportal_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_pyportal_m4.menu.speed.120=120 MHz (standard) +adafruit_pyportal_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_pyportal_m4.menu.speed.150=150 MHz (overclock) +adafruit_pyportal_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_pyportal_m4.menu.speed.180=180 MHz (overclock) +adafruit_pyportal_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_pyportal_m4.menu.speed.200=200 MHz (overclock) +adafruit_pyportal_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_pyportal_m4.menu.opt.small=Small (-Os) (standard) +adafruit_pyportal_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_pyportal_m4.menu.opt.fast=Fast (-O2) +adafruit_pyportal_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_pyportal_m4.menu.opt.faster=Faster (-O3) +adafruit_pyportal_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_pyportal_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_pyportal_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_pyportal_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_pyportal_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_pyportal_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_pyportal_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_pyportal_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_pyportal_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_pyportal_m4.menu.usbstack.arduino=Arduino +adafruit_pyportal_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_pyportal_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_pyportal_m4.menu.debug.off=Off +adafruit_pyportal_m4.menu.debug.on=On +adafruit_pyportal_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit PyPortal M4 Titano (SAMD51) +# ----------------------------------- +adafruit_pyportal_m4_titano.name=Adafruit PyPortal M4 Titano (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_pyportal_m4_titano.vid.0=0x239A +adafruit_pyportal_m4_titano.pid.0=0x8053 +adafruit_pyportal_m4_titano.vid.1=0x239A +adafruit_pyportal_m4_titano.pid.1=0x8053 + +# Upload +adafruit_pyportal_m4_titano.upload.tool=bossac18 +adafruit_pyportal_m4_titano.upload.protocol=sam-ba +adafruit_pyportal_m4_titano.upload.maximum_size=1032192 +adafruit_pyportal_m4_titano.upload.offset=0x4000 +adafruit_pyportal_m4_titano.upload.use_1200bps_touch=true +adafruit_pyportal_m4_titano.upload.wait_for_upload_port=true +adafruit_pyportal_m4_titano.upload.native_usb=true + +# Build +adafruit_pyportal_m4_titano.build.mcu=cortex-m4 +adafruit_pyportal_m4_titano.build.f_cpu=120000000L +adafruit_pyportal_m4_titano.build.usb_product="PyPortal M4 Titano" +adafruit_pyportal_m4_titano.build.usb_manufacturer="Adafruit" +adafruit_pyportal_m4_titano.build.board=PYPORTAL_M4_TITANO +adafruit_pyportal_m4_titano.build.core=arduino +adafruit_pyportal_m4_titano.build.extra_flags=-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYPORTAL_M4_TITANO -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_pyportal_m4_titano.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_pyportal_m4_titano.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_pyportal_m4_titano.build.variant=pyportal_m4_titano +adafruit_pyportal_m4_titano.build.variant_system_lib= +adafruit_pyportal_m4_titano.build.vid=0x239A +adafruit_pyportal_m4_titano.build.pid=0x8053 +adafruit_pyportal_m4_titano.bootloader.tool=openocd +adafruit_pyportal_m4_titano.bootloader.file=metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin +adafruit_pyportal_m4_titano.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_pyportal_m4_titano.menu.cache.on=Enabled +adafruit_pyportal_m4_titano.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_pyportal_m4_titano.menu.cache.off=Disabled +adafruit_pyportal_m4_titano.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_pyportal_m4_titano.menu.speed.120=120 MHz (standard) +adafruit_pyportal_m4_titano.menu.speed.120.build.f_cpu=120000000L +adafruit_pyportal_m4_titano.menu.speed.150=150 MHz (overclock) +adafruit_pyportal_m4_titano.menu.speed.150.build.f_cpu=150000000L +adafruit_pyportal_m4_titano.menu.speed.180=180 MHz (overclock) +adafruit_pyportal_m4_titano.menu.speed.180.build.f_cpu=180000000L +adafruit_pyportal_m4_titano.menu.speed.200=200 MHz (overclock) +adafruit_pyportal_m4_titano.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_pyportal_m4_titano.menu.opt.small=Small (-Os) (standard) +adafruit_pyportal_m4_titano.menu.opt.small.build.flags.optimize=-Os +adafruit_pyportal_m4_titano.menu.opt.fast=Fast (-O2) +adafruit_pyportal_m4_titano.menu.opt.fast.build.flags.optimize=-O2 +adafruit_pyportal_m4_titano.menu.opt.faster=Faster (-O3) +adafruit_pyportal_m4_titano.menu.opt.faster.build.flags.optimize=-O3 +adafruit_pyportal_m4_titano.menu.opt.fastest=Fastest (-Ofast) +adafruit_pyportal_m4_titano.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_pyportal_m4_titano.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_pyportal_m4_titano.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_pyportal_m4_titano.menu.maxqspi.50=50 MHz (standard) +adafruit_pyportal_m4_titano.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_pyportal_m4_titano.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_pyportal_m4_titano.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_pyportal_m4_titano.menu.usbstack.arduino=Arduino +adafruit_pyportal_m4_titano.menu.usbstack.tinyusb=TinyUSB +adafruit_pyportal_m4_titano.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_pyportal_m4_titano.menu.debug.off=Off +adafruit_pyportal_m4_titano.menu.debug.on=On +adafruit_pyportal_m4_titano.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit pyBadge M4 Express (SAMD51) +# ----------------------------------- +adafruit_pybadge_m4.name=Adafruit pyBadge M4 Express (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_pybadge_m4.vid.0=0x239A +adafruit_pybadge_m4.pid.0=0x8033 +adafruit_pybadge_m4.vid.1=0x239A +adafruit_pybadge_m4.pid.1=0x0033 +adafruit_pybadge_m4.vid.2=0x239A +adafruit_pybadge_m4.pid.2=0x8034 +adafruit_pybadge_m4.vid.3=0x239A +adafruit_pybadge_m4.pid.3=0x0034 + +# Upload +adafruit_pybadge_m4.upload.tool=bossac18 +adafruit_pybadge_m4.upload.protocol=sam-ba +adafruit_pybadge_m4.upload.maximum_size=507904 +adafruit_pybadge_m4.upload.offset=0x4000 +adafruit_pybadge_m4.upload.use_1200bps_touch=true +adafruit_pybadge_m4.upload.wait_for_upload_port=true +adafruit_pybadge_m4.upload.native_usb=true + +# Build +adafruit_pybadge_m4.build.mcu=cortex-m4 +adafruit_pybadge_m4.build.f_cpu=120000000L +adafruit_pybadge_m4.build.usb_product="pyBadge M4 Express" +adafruit_pybadge_m4.build.usb_manufacturer="Adafruit" +adafruit_pybadge_m4.build.board=PYBADGE_M4 +adafruit_pybadge_m4.build.core=arduino +adafruit_pybadge_m4.build.extra_flags=-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_PYBADGE_M4_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_pybadge_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_pybadge_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_pybadge_m4.build.variant=pybadge_m4 +adafruit_pybadge_m4.build.variant_system_lib= +adafruit_pybadge_m4.build.vid=0x239A +adafruit_pybadge_m4.build.pid=0x8033 +adafruit_pybadge_m4.bootloader.tool=openocd +adafruit_pybadge_m4.bootloader.file=featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin +adafruit_pybadge_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_pybadge_m4.menu.cache.on=Enabled +adafruit_pybadge_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_pybadge_m4.menu.cache.off=Disabled +adafruit_pybadge_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_pybadge_m4.menu.speed.120=120 MHz (standard) +adafruit_pybadge_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_pybadge_m4.menu.speed.150=150 MHz (overclock) +adafruit_pybadge_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_pybadge_m4.menu.speed.180=180 MHz (overclock) +adafruit_pybadge_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_pybadge_m4.menu.speed.200=200 MHz (overclock) +adafruit_pybadge_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_pybadge_m4.menu.opt.small=Small (-Os) (standard) +adafruit_pybadge_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_pybadge_m4.menu.opt.fast=Fast (-O2) +adafruit_pybadge_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_pybadge_m4.menu.opt.faster=Faster (-O3) +adafruit_pybadge_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_pybadge_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_pybadge_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_pybadge_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_pybadge_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_pybadge_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_pybadge_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_pybadge_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_pybadge_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_pybadge_m4.menu.usbstack.arduino=Arduino +adafruit_pybadge_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_pybadge_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_pybadge_m4.menu.debug.off=Off +adafruit_pybadge_m4.menu.debug.on=On +adafruit_pybadge_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Metro M4 AirLift Lite (SAMD51) +# ----------------------------------- +adafruit_metro_m4_airliftlite.name=Adafruit Metro M4 AirLift Lite (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_metro_m4_airliftlite.vid.0=0x239A +adafruit_metro_m4_airliftlite.pid.0=0x8037 +adafruit_metro_m4_airliftlite.vid.1=0x239A +adafruit_metro_m4_airliftlite.pid.1=0x0037 + +# Upload +adafruit_metro_m4_airliftlite.upload.tool=bossac18 +adafruit_metro_m4_airliftlite.upload.protocol=sam-ba +adafruit_metro_m4_airliftlite.upload.maximum_size=507904 +adafruit_metro_m4_airliftlite.upload.offset=0x4000 +adafruit_metro_m4_airliftlite.upload.use_1200bps_touch=true +adafruit_metro_m4_airliftlite.upload.wait_for_upload_port=true +adafruit_metro_m4_airliftlite.upload.native_usb=true + +# Build +adafruit_metro_m4_airliftlite.build.mcu=cortex-m4 +adafruit_metro_m4_airliftlite.build.f_cpu=120000000L +adafruit_metro_m4_airliftlite.build.usb_product="Metro M4 AirLift Lite" +adafruit_metro_m4_airliftlite.build.usb_manufacturer="Adafruit" +adafruit_metro_m4_airliftlite.build.board=METRO_M4_AIRLIFT_LITE +adafruit_metro_m4_airliftlite.build.core=arduino +adafruit_metro_m4_airliftlite.build.extra_flags=-D__SAMD51J19A__ -DADAFRUIT_METRO_M4_AIRLIFT_LITE -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_metro_m4_airliftlite.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_metro_m4_airliftlite.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_metro_m4_airliftlite.build.variant=metro_m4_airlift +adafruit_metro_m4_airliftlite.build.variant_system_lib= +adafruit_metro_m4_airliftlite.build.vid=0x239A +adafruit_metro_m4_airliftlite.build.pid=0x8037 +adafruit_metro_m4_airliftlite.bootloader.tool=openocd +adafruit_metro_m4_airliftlite.bootloader.file=metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin +adafruit_metro_m4_airliftlite.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_metro_m4_airliftlite.menu.cache.on=Enabled +adafruit_metro_m4_airliftlite.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_metro_m4_airliftlite.menu.cache.off=Disabled +adafruit_metro_m4_airliftlite.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_metro_m4_airliftlite.menu.speed.120=120 MHz (standard) +adafruit_metro_m4_airliftlite.menu.speed.120.build.f_cpu=120000000L +adafruit_metro_m4_airliftlite.menu.speed.150=150 MHz (overclock) +adafruit_metro_m4_airliftlite.menu.speed.150.build.f_cpu=150000000L +adafruit_metro_m4_airliftlite.menu.speed.180=180 MHz (overclock) +adafruit_metro_m4_airliftlite.menu.speed.180.build.f_cpu=180000000L +adafruit_metro_m4_airliftlite.menu.speed.200=200 MHz (overclock) +adafruit_metro_m4_airliftlite.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_metro_m4_airliftlite.menu.opt.small=Small (-Os) (standard) +adafruit_metro_m4_airliftlite.menu.opt.small.build.flags.optimize=-Os +adafruit_metro_m4_airliftlite.menu.opt.fast=Fast (-O2) +adafruit_metro_m4_airliftlite.menu.opt.fast.build.flags.optimize=-O2 +adafruit_metro_m4_airliftlite.menu.opt.faster=Faster (-O3) +adafruit_metro_m4_airliftlite.menu.opt.faster.build.flags.optimize=-O3 +adafruit_metro_m4_airliftlite.menu.opt.fastest=Fastest (-Ofast) +adafruit_metro_m4_airliftlite.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_metro_m4_airliftlite.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_metro_m4_airliftlite.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_metro_m4_airliftlite.menu.maxqspi.50=50 MHz (standard) +adafruit_metro_m4_airliftlite.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_metro_m4_airliftlite.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_metro_m4_airliftlite.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_metro_m4_airliftlite.menu.usbstack.arduino=Arduino +adafruit_metro_m4_airliftlite.menu.usbstack.tinyusb=TinyUSB +adafruit_metro_m4_airliftlite.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_metro_m4_airliftlite.menu.debug.off=Off +adafruit_metro_m4_airliftlite.menu.debug.on=On +adafruit_metro_m4_airliftlite.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit PyGamer M4 Express (SAMD51) +# ----------------------------------- +adafruit_pygamer_m4.name=Adafruit PyGamer M4 Express (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_pygamer_m4.vid.0=0x239A +adafruit_pygamer_m4.pid.0=0x803D +adafruit_pygamer_m4.vid.1=0x239A +adafruit_pygamer_m4.pid.1=0x003D +adafruit_pygamer_m4.vid.2=0x239A +adafruit_pygamer_m4.pid.2=0x803E + +# Upload +adafruit_pygamer_m4.upload.tool=bossac18 +adafruit_pygamer_m4.upload.protocol=sam-ba +adafruit_pygamer_m4.upload.maximum_size=507904 +adafruit_pygamer_m4.upload.offset=0x4000 +adafruit_pygamer_m4.upload.use_1200bps_touch=true +adafruit_pygamer_m4.upload.wait_for_upload_port=true +adafruit_pygamer_m4.upload.native_usb=true + +# Build +adafruit_pygamer_m4.build.mcu=cortex-m4 +adafruit_pygamer_m4.build.f_cpu=120000000L +adafruit_pygamer_m4.build.usb_product="PyGamer M4 Express" +adafruit_pygamer_m4.build.usb_manufacturer="Adafruit" +adafruit_pygamer_m4.build.board=PYGAMER_M4 +adafruit_pygamer_m4.build.core=arduino +adafruit_pygamer_m4.build.extra_flags=-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_PYGAMER_M4_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_pygamer_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_pygamer_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_pygamer_m4.build.variant=pygamer_m4 +adafruit_pygamer_m4.build.variant_system_lib= +adafruit_pygamer_m4.build.vid=0x239A +adafruit_pygamer_m4.build.pid=0x803D +adafruit_pygamer_m4.bootloader.tool=openocd +adafruit_pygamer_m4.bootloader.file=featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin +adafruit_pygamer_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_pygamer_m4.menu.cache.on=Enabled +adafruit_pygamer_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_pygamer_m4.menu.cache.off=Disabled +adafruit_pygamer_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_pygamer_m4.menu.speed.120=120 MHz (standard) +adafruit_pygamer_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_pygamer_m4.menu.speed.150=150 MHz (overclock) +adafruit_pygamer_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_pygamer_m4.menu.speed.180=180 MHz (overclock) +adafruit_pygamer_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_pygamer_m4.menu.speed.200=200 MHz (overclock) +adafruit_pygamer_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_pygamer_m4.menu.opt.small=Small (-Os) (standard) +adafruit_pygamer_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_pygamer_m4.menu.opt.fast=Fast (-O2) +adafruit_pygamer_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_pygamer_m4.menu.opt.faster=Faster (-O3) +adafruit_pygamer_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_pygamer_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_pygamer_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_pygamer_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_pygamer_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_pygamer_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_pygamer_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_pygamer_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_pygamer_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_pygamer_m4.menu.usbstack.arduino=Arduino +adafruit_pygamer_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_pygamer_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_pygamer_m4.menu.debug.off=Off +adafruit_pygamer_m4.menu.debug.on=On +adafruit_pygamer_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit pyBadge AirLift M4 (SAMD51) +# ----------------------------------- +adafruit_pybadge_airlift_m4.name=Adafruit pyBadge AirLift M4 (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_pybadge_airlift_m4.vid.0=0x239A +adafruit_pybadge_airlift_m4.pid.0=0x8043 +adafruit_pybadge_airlift_m4.vid.1=0x239A +adafruit_pybadge_airlift_m4.pid.1=0x0043 +adafruit_pybadge_airlift_m4.vid.2=0x239A +adafruit_pybadge_airlift_m4.pid.2=0x8044 + +# Upload +adafruit_pybadge_airlift_m4.upload.tool=bossac18 +adafruit_pybadge_airlift_m4.upload.protocol=sam-ba +adafruit_pybadge_airlift_m4.upload.maximum_size=1032192 +adafruit_pybadge_airlift_m4.upload.offset=0x4000 +adafruit_pybadge_airlift_m4.upload.use_1200bps_touch=true +adafruit_pybadge_airlift_m4.upload.wait_for_upload_port=true +adafruit_pybadge_airlift_m4.upload.native_usb=true + +# Build +adafruit_pybadge_airlift_m4.build.mcu=cortex-m4 +adafruit_pybadge_airlift_m4.build.f_cpu=120000000L +adafruit_pybadge_airlift_m4.build.usb_product="pyBadge AirLift M4" +adafruit_pybadge_airlift_m4.build.usb_manufacturer="Adafruit" +adafruit_pybadge_airlift_m4.build.board=PYBADGE_AIRLIFT_M4 +adafruit_pybadge_airlift_m4.build.core=arduino +adafruit_pybadge_airlift_m4.build.extra_flags=-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYBADGE_AIRLIFT_M4 -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_pybadge_airlift_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_pybadge_airlift_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_pybadge_airlift_m4.build.variant=pybadge_airlift_m4 +adafruit_pybadge_airlift_m4.build.variant_system_lib= +adafruit_pybadge_airlift_m4.build.vid=0x239A +adafruit_pybadge_airlift_m4.build.pid=0x8043 +adafruit_pybadge_airlift_m4.bootloader.tool=openocd +adafruit_pybadge_airlift_m4.bootloader.file=featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin +adafruit_pybadge_airlift_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_pybadge_airlift_m4.menu.cache.on=Enabled +adafruit_pybadge_airlift_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_pybadge_airlift_m4.menu.cache.off=Disabled +adafruit_pybadge_airlift_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_pybadge_airlift_m4.menu.speed.120=120 MHz (standard) +adafruit_pybadge_airlift_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_pybadge_airlift_m4.menu.speed.150=150 MHz (overclock) +adafruit_pybadge_airlift_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_pybadge_airlift_m4.menu.speed.180=180 MHz (overclock) +adafruit_pybadge_airlift_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_pybadge_airlift_m4.menu.speed.200=200 MHz (overclock) +adafruit_pybadge_airlift_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_pybadge_airlift_m4.menu.opt.small=Small (-Os) (standard) +adafruit_pybadge_airlift_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_pybadge_airlift_m4.menu.opt.fast=Fast (-O2) +adafruit_pybadge_airlift_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_pybadge_airlift_m4.menu.opt.faster=Faster (-O3) +adafruit_pybadge_airlift_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_pybadge_airlift_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_pybadge_airlift_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_pybadge_airlift_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_pybadge_airlift_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_pybadge_airlift_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_pybadge_airlift_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_pybadge_airlift_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_pybadge_airlift_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_pybadge_airlift_m4.menu.usbstack.arduino=Arduino +adafruit_pybadge_airlift_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_pybadge_airlift_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_pybadge_airlift_m4.menu.debug.off=Off +adafruit_pybadge_airlift_m4.menu.debug.on=On +adafruit_pybadge_airlift_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit MONSTER M4SK (SAMD51) +# ----------------------------------- +adafruit_monster_m4sk.name=Adafruit MONSTER M4SK (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_monster_m4sk.vid.0=0x239A +adafruit_monster_m4sk.pid.0=0x8047 +adafruit_monster_m4sk.vid.1=0x239A +adafruit_monster_m4sk.pid.1=0x0047 +adafruit_monster_m4sk.vid.2=0x239A +adafruit_monster_m4sk.pid.2=0x8048 + +# Upload +adafruit_monster_m4sk.upload.tool=bossac18 +adafruit_monster_m4sk.upload.protocol=sam-ba +adafruit_monster_m4sk.upload.maximum_size=507904 +adafruit_monster_m4sk.upload.offset=0x4000 +adafruit_monster_m4sk.upload.use_1200bps_touch=true +adafruit_monster_m4sk.upload.wait_for_upload_port=true +adafruit_monster_m4sk.upload.native_usb=true + +# Build +adafruit_monster_m4sk.build.mcu=cortex-m4 +adafruit_monster_m4sk.build.f_cpu=120000000L +adafruit_monster_m4sk.build.usb_product="MONSTER M4SK" +adafruit_monster_m4sk.build.usb_manufacturer="Adafruit" +adafruit_monster_m4sk.build.board=MONSTER_M4SK +adafruit_monster_m4sk.build.core=arduino +adafruit_monster_m4sk.build.extra_flags=-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_MONSTER_M4SK_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_monster_m4sk.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_monster_m4sk.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_monster_m4sk.build.variant=monster_m4sk +adafruit_monster_m4sk.build.variant_system_lib= +adafruit_monster_m4sk.build.vid=0x239A +adafruit_monster_m4sk.build.pid=0x8047 +adafruit_monster_m4sk.bootloader.tool=openocd +adafruit_monster_m4sk.bootloader.file=featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin +adafruit_monster_m4sk.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_monster_m4sk.menu.cache.on=Enabled +adafruit_monster_m4sk.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_monster_m4sk.menu.cache.off=Disabled +adafruit_monster_m4sk.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_monster_m4sk.menu.speed.120=120 MHz (standard) +adafruit_monster_m4sk.menu.speed.120.build.f_cpu=120000000L +adafruit_monster_m4sk.menu.speed.150=150 MHz (overclock) +adafruit_monster_m4sk.menu.speed.150.build.f_cpu=150000000L +adafruit_monster_m4sk.menu.speed.180=180 MHz (overclock) +adafruit_monster_m4sk.menu.speed.180.build.f_cpu=180000000L +adafruit_monster_m4sk.menu.speed.200=200 MHz (overclock) +adafruit_monster_m4sk.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_monster_m4sk.menu.opt.small=Small (-Os) (standard) +adafruit_monster_m4sk.menu.opt.small.build.flags.optimize=-Os +adafruit_monster_m4sk.menu.opt.fast=Fast (-O2) +adafruit_monster_m4sk.menu.opt.fast.build.flags.optimize=-O2 +adafruit_monster_m4sk.menu.opt.faster=Faster (-O3) +adafruit_monster_m4sk.menu.opt.faster.build.flags.optimize=-O3 +adafruit_monster_m4sk.menu.opt.fastest=Fastest (-Ofast) +adafruit_monster_m4sk.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_monster_m4sk.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_monster_m4sk.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_monster_m4sk.menu.maxqspi.50=50 MHz (standard) +adafruit_monster_m4sk.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_monster_m4sk.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_monster_m4sk.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_monster_m4sk.menu.usbstack.arduino=Arduino +adafruit_monster_m4sk.menu.usbstack.tinyusb=TinyUSB +adafruit_monster_m4sk.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_monster_m4sk.menu.debug.off=Off +adafruit_monster_m4sk.menu.debug.on=On +adafruit_monster_m4sk.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Hallowing M4 (SAMD51) +# ----------------------------------- +adafruit_hallowing_m4.name=Adafruit Hallowing M4 (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_hallowing_m4.vid.0=0x239A +adafruit_hallowing_m4.pid.0=0x8049 +adafruit_hallowing_m4.vid.1=0x239A +adafruit_hallowing_m4.pid.1=0x0049 +adafruit_hallowing_m4.vid.2=0x239A +adafruit_hallowing_m4.pid.2=0x804A + +# Upload +adafruit_hallowing_m4.upload.tool=bossac18 +adafruit_hallowing_m4.upload.protocol=sam-ba +adafruit_hallowing_m4.upload.maximum_size=507904 +adafruit_hallowing_m4.upload.offset=0x4000 +adafruit_hallowing_m4.upload.use_1200bps_touch=true +adafruit_hallowing_m4.upload.wait_for_upload_port=true +adafruit_hallowing_m4.upload.native_usb=true + +# Build +adafruit_hallowing_m4.build.mcu=cortex-m4 +adafruit_hallowing_m4.build.f_cpu=120000000L +adafruit_hallowing_m4.build.usb_product="Hallowing M4" +adafruit_hallowing_m4.build.usb_manufacturer="Adafruit" +adafruit_hallowing_m4.build.board=HALLOWING_M4 +adafruit_hallowing_m4.build.core=arduino +adafruit_hallowing_m4.build.extra_flags=-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_HALLOWING_M4_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_hallowing_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_hallowing_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_hallowing_m4.build.variant=hallowing_m4 +adafruit_hallowing_m4.build.variant_system_lib= +adafruit_hallowing_m4.build.vid=0x239A +adafruit_hallowing_m4.build.pid=0x8049 +adafruit_hallowing_m4.bootloader.tool=openocd +adafruit_hallowing_m4.bootloader.file=featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin +adafruit_hallowing_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_hallowing_m4.menu.cache.on=Enabled +adafruit_hallowing_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_hallowing_m4.menu.cache.off=Disabled +adafruit_hallowing_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_hallowing_m4.menu.speed.120=120 MHz (standard) +adafruit_hallowing_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_hallowing_m4.menu.speed.150=150 MHz (overclock) +adafruit_hallowing_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_hallowing_m4.menu.speed.180=180 MHz (overclock) +adafruit_hallowing_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_hallowing_m4.menu.speed.200=200 MHz (overclock) +adafruit_hallowing_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_hallowing_m4.menu.opt.small=Small (-Os) (standard) +adafruit_hallowing_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_hallowing_m4.menu.opt.fast=Fast (-O2) +adafruit_hallowing_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_hallowing_m4.menu.opt.faster=Faster (-O3) +adafruit_hallowing_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_hallowing_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_hallowing_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_hallowing_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_hallowing_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_hallowing_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_hallowing_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_hallowing_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_hallowing_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_hallowing_m4.menu.usbstack.arduino=Arduino +adafruit_hallowing_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_hallowing_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_hallowing_m4.menu.debug.off=Off +adafruit_hallowing_m4.menu.debug.on=On +adafruit_hallowing_m4.menu.debug.on.build.flags.debug=-g + + +# ----------------------------------- +# Adafruit Matrix Portal M4 (SAMD51) +# ----------------------------------- +adafruit_matrixportal_m4.name=Adafruit Matrix Portal M4 (SAMD51) + +# VID/PID for Bootloader, Arduino & CircuitPython +adafruit_matrixportal_m4.vid.0=0x239A +adafruit_matrixportal_m4.pid.0=0x80C9 +adafruit_matrixportal_m4.vid.1=0x239A +adafruit_matrixportal_m4.pid.1=0x00C9 +adafruit_matrixportal_m4.vid.2=0x239A +adafruit_matrixportal_m4.pid.2=0x80CA + +# Upload +adafruit_matrixportal_m4.upload.tool=bossac18 +adafruit_matrixportal_m4.upload.protocol=sam-ba +adafruit_matrixportal_m4.upload.maximum_size=507904 +adafruit_matrixportal_m4.upload.offset=0x4000 +adafruit_matrixportal_m4.upload.use_1200bps_touch=true +adafruit_matrixportal_m4.upload.wait_for_upload_port=true +adafruit_matrixportal_m4.upload.native_usb=true + +# Build +adafruit_matrixportal_m4.build.mcu=cortex-m4 +adafruit_matrixportal_m4.build.f_cpu=120000000L +adafruit_matrixportal_m4.build.usb_product="Matrix Portal M4" +adafruit_matrixportal_m4.build.usb_manufacturer="Adafruit" +adafruit_matrixportal_m4.build.board=MATRIXPORTAL_M4 +adafruit_matrixportal_m4.build.core=arduino +adafruit_matrixportal_m4.build.extra_flags=-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_MATRIXPORTAL_M4_EXPRESS -D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 {build.usb_flags} +adafruit_matrixportal_m4.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld +adafruit_matrixportal_m4.build.openocdscript=scripts/openocd/daplink_samd51.cfg +adafruit_matrixportal_m4.build.variant=matrixportal_m4 +adafruit_matrixportal_m4.build.variant_system_lib= +adafruit_matrixportal_m4.build.vid=0x239A +adafruit_matrixportal_m4.build.pid=0x80C9 +adafruit_matrixportal_m4.bootloader.tool=openocd +adafruit_matrixportal_m4.bootloader.file=matrixportalM4/bootloader-matrixportal_m4.bin +adafruit_matrixportal_m4.compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" "-L{build.variant.path}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +# Menu: Cache +adafruit_matrixportal_m4.menu.cache.on=Enabled +adafruit_matrixportal_m4.menu.cache.on.build.cache_flags=-DENABLE_CACHE +adafruit_matrixportal_m4.menu.cache.off=Disabled +adafruit_matrixportal_m4.menu.cache.off.build.cache_flags= + +# Menu: Speed +adafruit_matrixportal_m4.menu.speed.120=120 MHz (standard) +adafruit_matrixportal_m4.menu.speed.120.build.f_cpu=120000000L +adafruit_matrixportal_m4.menu.speed.150=150 MHz (overclock) +adafruit_matrixportal_m4.menu.speed.150.build.f_cpu=150000000L +adafruit_matrixportal_m4.menu.speed.180=180 MHz (overclock) +adafruit_matrixportal_m4.menu.speed.180.build.f_cpu=180000000L +adafruit_matrixportal_m4.menu.speed.200=200 MHz (overclock) +adafruit_matrixportal_m4.menu.speed.200.build.f_cpu=200000000L + +# Menu: Optimization +adafruit_matrixportal_m4.menu.opt.small=Small (-Os) (standard) +adafruit_matrixportal_m4.menu.opt.small.build.flags.optimize=-Os +adafruit_matrixportal_m4.menu.opt.fast=Fast (-O2) +adafruit_matrixportal_m4.menu.opt.fast.build.flags.optimize=-O2 +adafruit_matrixportal_m4.menu.opt.faster=Faster (-O3) +adafruit_matrixportal_m4.menu.opt.faster.build.flags.optimize=-O3 +adafruit_matrixportal_m4.menu.opt.fastest=Fastest (-Ofast) +adafruit_matrixportal_m4.menu.opt.fastest.build.flags.optimize=-Ofast +adafruit_matrixportal_m4.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops) +adafruit_matrixportal_m4.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops + +# Menu: QSPI Speed +adafruit_matrixportal_m4.menu.maxqspi.50=50 MHz (standard) +adafruit_matrixportal_m4.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000 +adafruit_matrixportal_m4.menu.maxqspi.fcpu=CPU Speed / 2 +adafruit_matrixportal_m4.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({build.f_cpu}) + +# Menu: USB Stack +adafruit_matrixportal_m4.menu.usbstack.arduino=Arduino +adafruit_matrixportal_m4.menu.usbstack.tinyusb=TinyUSB +adafruit_matrixportal_m4.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB + +# Menu: Debug +adafruit_matrixportal_m4.menu.debug.off=Off +adafruit_matrixportal_m4.menu.debug.on=On +adafruit_matrixportal_m4.menu.debug.on.build.flags.debug=-g + diff --git a/bootloaders/blmbadge/bootloader-blm_badge.bin b/bootloaders/blmbadge/bootloader-blm_badge.bin new file mode 100644 index 000000000..2e30fc17f Binary files /dev/null and b/bootloaders/blmbadge/bootloader-blm_badge.bin differ diff --git a/bootloaders/circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.bin b/bootloaders/circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..50ae4b0a8 Binary files /dev/null and b/bootloaders/circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.elf b/bootloaders/circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..05827e0dc Binary files /dev/null and b/bootloaders/circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/circuitplay/circuitplay_m0_samd21g18_sam_ba.bin b/bootloaders/circuitplayM0/circuitplay_m0_samd21g18_sam_ba.bin similarity index 100% rename from bootloaders/circuitplay/circuitplay_m0_samd21g18_sam_ba.bin rename to bootloaders/circuitplayM0/circuitplay_m0_samd21g18_sam_ba.bin diff --git a/bootloaders/circuitplayM0/update-bootloader-circuitplay_m0-v2.0.0-adafruit.5.uf2 b/bootloaders/circuitplayM0/update-bootloader-circuitplay_m0-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..0652fa7f6 Binary files /dev/null and b/bootloaders/circuitplayM0/update-bootloader-circuitplay_m0-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/feather/Makefile b/bootloaders/feather/Makefile new file mode 100644 index 000000000..297c2098b --- /dev/null +++ b/bootloaders/feather/Makefile @@ -0,0 +1,183 @@ +# Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. +# Copyright (c) 2015 Arduino LLC. All right reserved. +# +# 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 + +# ----------------------------------------------------------------------------- +# Paths +ifeq ($(OS),Windows_NT) + + # Are we using mingw/msys/msys2/cygwin? + ifeq ($(TERM),xterm) + T=$(shell cygpath -u $(LOCALAPPDATA)) + MODULE_PATH?=$(T)/Arduino15/packages/arduino + ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- + RM=rm + SEP=/ + else + MODULE_PATH?=$(LOCALAPPDATA)/Arduino15/packages/arduino + ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- + RM=rm + SEP=\\ + endif +else + UNAME_S := $(shell uname -s) + + ifeq ($(UNAME_S),Linux) + MODULE_PATH?=$(HOME)/.arduino15/packages/arduino + ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- + RM=rm + SEP=/ + endif + + ifeq ($(UNAME_S),Darwin) + MODULE_PATH?=$(HOME)/Library/Arduino15/packages/arduino/ + ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- + RM=rm + SEP=/ + endif +endif + +BUILD_PATH=build + +# ----------------------------------------------------------------------------- +# Tools +CC=$(ARM_GCC_PATH)gcc +OBJCOPY=$(ARM_GCC_PATH)objcopy +NM=$(ARM_GCC_PATH)nm +SIZE=$(ARM_GCC_PATH)size + +# ----------------------------------------------------------------------------- +# Compiler options +CFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -c -std=gnu99 -ffunction-sections -fdata-sections -nostdlib -nostartfiles --param max-inline-insns-single=500 +ifdef DEBUG +CFLAGS+=-g3 -O1 -DDEBUG=1 +else +CFLAGS+=-Os -DDEBUG=0 +endif + +# Adafruit Feather Zero (0x239A 0x000B) +#CFLAGS_EXTRA?=-D__SAMD21G18A__ -DUSB_PID_HIGH=0x00 -DUSB_PID_LOW=0x0B -DUSB_VID_LOW=0x9A -DUSB_VID_HIGH=0x23 +# Adafruit Feather SAMR (0x239A 0x0014) +CFLAGS_EXTRA?=-D__SAMR21G18A__ -DUSB_PID_HIGH=0x00 -DUSB_PID_LOW=0x14 -DUSB_VID_LOW=0x9A -DUSB_VID_HIGH=0x23 +# Arduino Zero (PID == 0x004D) +# CFLAGS_EXTRA?=-D__SAMD21G18A__ -DUSB_PID_HIGH=0x00 -DUSB_PID_LOW=0x4D -DUSB_VID_LOW=0x41 -DUSB_VID_HIGH=0x23 +# Genuino Zero (PID == 0x024D) +# CFLAGS_EXTRA?=-D__SAMD21G18A__ -DUSB_PID_HIGH=0x02 -DUSB_PID_LOW=0x4D -DUSB_VID_LOW=0x41 -DUSB_VID_HIGH=0x23 +# Arduino MKR1000 (PID == 0x004E) +# CFLAGS_EXTRA?=-D__SAMD21G18A__ -DUSB_PID_HIGH=0x00 -DUSB_PID_LOW=0x4E -DUSB_VID_LOW=0x41 -DUSB_VID_HIGH=0x23 +# Genuino MKR1000 (PID == 0x024E) +# CFLAGS_EXTRA?=-D__SAMD21G18A__ -DUSB_PID_HIGH=0x02 -DUSB_PID_LOW=0x4E -DUSB_VID_LOW=0x41 -DUSB_VID_HIGH=0x23 + +# samd or samr +NAME=samr21_sam_ba + +INCLUDES=-I"$(MODULE_PATH)/tools/CMSIS/4.0.0-atmel/CMSIS/Include/" -I"$(MODULE_PATH)/tools/CMSIS/4.0.0-atmel/Device/ATMEL/" + +# ----------------------------------------------------------------------------- +# Linker options +LDFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all +LDFLAGS+=-Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols --specs=nano.specs --specs=nosys.specs + +# ----------------------------------------------------------------------------- +# Source files and objects +SOURCES= \ +board_driver_led.c \ +board_driver_serial.c \ +board_driver_usb.c \ +board_init.c \ +board_startup.c \ +main.c \ +sam_ba_usb.c \ +sam_ba_cdc.c \ +sam_ba_monitor.c \ +sam_ba_serial.c + +OBJECTS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.o)) +DEPS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.d)) + +ELF=$(NAME).elf +BIN=$(NAME).bin +HEX=$(NAME).hex + +ifneq "test$(AVRSTUDIO_EXE_PATH)" "test" +AS_BUILD=copy_for_atmel_studio +AS_CLEAN=clean_for_atmel_studio +else +AS_BUILD= +AS_CLEAN= +endif + + +all: print_info $(SOURCES) $(BIN) $(HEX) $(AS_BUILD) + +$(ELF): Makefile $(BUILD_PATH) $(OBJECTS) + @echo ---------------------------------------------------------- + @echo Creating ELF binary + "$(CC)" -L. -L$(BUILD_PATH) $(LDFLAGS) -Os -Wl,--gc-sections -save-temps -Tbootloader_samd21x18.ld -Wl,-Map,"$(BUILD_PATH)/$(NAME).map" -o "$(BUILD_PATH)/$(ELF)" -Wl,--start-group $(OBJECTS) -lm -Wl,--end-group + "$(NM)" "$(BUILD_PATH)/$(ELF)" >"$(BUILD_PATH)/$(NAME)_symbols.txt" + "$(SIZE)" --format=sysv -t -x $(BUILD_PATH)/$(ELF) + +$(BIN): $(ELF) + @echo ---------------------------------------------------------- + @echo Creating flash binary + "$(OBJCOPY)" -O binary $(BUILD_PATH)/$< $@ + +$(HEX): $(ELF) + @echo ---------------------------------------------------------- + @echo Creating flash binary + "$(OBJCOPY)" -O ihex $(BUILD_PATH)/$< $@ + +$(BUILD_PATH)/%.o: %.c + @echo ---------------------------------------------------------- + @echo Compiling $< to $@ + "$(CC)" $(CFLAGS) $(CFLAGS_EXTRA) $(INCLUDES) $< -o $@ + @echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +$(BUILD_PATH): + @echo ---------------------------------------------------------- + @echo Creating build folder + -mkdir $(BUILD_PATH) + +print_info: + @echo ---------------------------------------------------------- + @echo Compiling bootloader using + @echo BASE PATH = $(MODULE_PATH) + @echo GCC PATH = $(ARM_GCC_PATH) +# @echo OS = $(OS) +# @echo SHELL = $(SHELL) +# @echo TERM = $(TERM) +# "$(CC)" -v +# env + +copy_for_atmel_studio: $(BIN) $(HEX) + @echo ---------------------------------------------------------- + @echo Atmel Studio detected, copying ELF to project root for debug + cp $(BUILD_PATH)/$(ELF) . + +clean_for_atmel_studio: + @echo ---------------------------------------------------------- + @echo Atmel Studio detected, cleaning ELF from project root + -$(RM) ./$(ELF) + +clean: $(AS_CLEAN) + @echo ---------------------------------------------------------- + @echo Cleaning project + -$(RM) $(BIN) + -$(RM) $(HEX) + -$(RM) $(BUILD_PATH)/*.* + -rmdir $(BUILD_PATH) + +.phony: print_info $(BUILD_PATH) diff --git a/bootloaders/feather/README.md b/bootloaders/feather/README.md new file mode 100644 index 000000000..44f4e4e02 --- /dev/null +++ b/bootloaders/feather/README.md @@ -0,0 +1,75 @@ +# Arduino Zero Bootloader + +## 1- Prerequisites + +The project build is based on Makefile system. +Makefile is present at project root and try to handle multi-platform cases. + +Multi-plaform GCC is provided by ARM here: https://launchpad.net/gcc-arm-embedded/+download + +Atmel Studio contains both make and ARM GCC toolchain. You don't need to install them in this specific use case. + +### Windows + +* Native command line +Make binary can be obtained here: http://gnuwin32.sourceforge.net/packages/make.htm + +* Cygwin/MSys/MSys2/Babun/etc... +It is available natively in all distributions. + +* Atmel Studio +An Atmel Studio **7** Makefile-based project is present at project root, just open samd21_sam_ba.atsln file in AS7. + +### Linux + +Make is usually available by default. + +### OS X + +Make is available through XCode package. + + +## 2- Selecting available SAM-BA interfaces + +By default both USB and UART are made available, but this parameter can be modified in sam_ba_monitor.h, line 31: + +Set the define SAM_BA_INTERFACE to +* SAM_BA_UART_ONLY for only UART interface +* SAM_BA_USBCDC_ONLY for only USB CDC interface +* SAM_BA_BOTH_INTERFACES for enabling both the interfaces + +## 3- Behaviour + +This bootloader implements the double-tap on Reset button. +By quickly pressing this button two times, the board will reset and stay in bootloader, waiting for communication on either USB or USART. + +The USB port in use is the USB Native port, close to the Reset button. +The USART in use is the one available on pins D0/D1, labelled respectively RX/TX. Communication parameters are a baudrate at 115200, 8bits of data, no parity and 1 stop bit (8N1). + +## 4- Description + +**Pinmap** + +The following pins are used by the program : +PA25 : input/output (USB DP) +PA24 : input/output (USB DM) +PA11 : input (USART RX) +PA10 : output (USART TX) + +The application board shall avoid driving the PA25, PA24, PB23 and PB22 signals while the boot program is running (after a POR for example). + +**Clock system** + +CPU runs at 48MHz from Generic Clock Generator 0 on DFLL48M. + +Generic Clock Generator 1 is using external 32kHz oscillator and is the source of DFLL48M. + +USB and USART are using Generic Clock Generator 0 also. + +**Memory Mapping** + +Bootloader code will be located at 0x0 and executed before any applicative code. + +Applications compiled to be executed along with the bootloader will start at 0x2000 (see linker script bootloader_samd21x18.ld). + +Before jumping to the application, the bootloader changes the VTOR register to use the interrupt vectors of the application @0x2000.<- not required as application code is taking care of this. diff --git a/bootloaders/feather/board_definitions.h b/bootloaders/feather/board_definitions.h new file mode 100644 index 000000000..458e1b0a7 --- /dev/null +++ b/bootloaders/feather/board_definitions.h @@ -0,0 +1,72 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _BOARD_DEFINITIONS_H_ +#define _BOARD_DEFINITIONS_H_ + +/* + * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by + * quickly tapping two times on the reset button. + * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not + * be touched from the loaded application. + */ +#define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul) +#define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) + +/* + * If BOOT_LOAD_PIN is defined the bootloader is started if the selected + * pin is tied LOW. + */ +//#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 +//#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 +#define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f)) + +#define CPU_FREQUENCY (48000000ul) + +#define BOOT_USART_MODULE SERCOM0 +#define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0 +#define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE +#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 +#define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 +#define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 +#define BOOT_USART_PAD1 PINMUX_UNUSED +#define BOOT_USART_PAD0 PINMUX_UNUSED + +/* Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/* Master clock frequency */ +#define VARIANT_MCK CPU_FREQUENCY + +#define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) +#define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) + +/* + * LEDs definitions + */ +#define BOARD_LED_PORT (0) +#define BOARD_LED_PIN (17) + +#define BOARD_LEDRX_PORT (1) +#define BOARD_LEDRX_PIN (3) + +#define BOARD_LEDTX_PORT (0) +#define BOARD_LEDTX_PIN (27) + +#endif // _BOARD_DEFINITIONS_H_ diff --git a/bootloaders/feather/board_driver_led.c b/bootloaders/feather/board_driver_led.c new file mode 100644 index 000000000..1a2430aff --- /dev/null +++ b/bootloaders/feather/board_driver_led.c @@ -0,0 +1,22 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include "board_driver_led.h" + + diff --git a/bootloaders/feather/board_driver_led.h b/bootloaders/feather/board_driver_led.h new file mode 100644 index 000000000..6f1fd7580 --- /dev/null +++ b/bootloaders/feather/board_driver_led.h @@ -0,0 +1,41 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _BOARD_DRIVER_LED_ +#define _BOARD_DRIVER_LED_ + +#include +#include "board_definitions.h" + +inline void LED_init(void) { PORT->Group[BOARD_LED_PORT].DIRSET.reg = (1<Group[BOARD_LED_PORT].OUTSET.reg = (1<Group[BOARD_LED_PORT].OUTCLR.reg = (1<Group[BOARD_LED_PORT].OUTTGL.reg = (1<Group[BOARD_LEDRX_PORT].DIRSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDRX_PORT].OUTTGL.reg = (1<Group[BOARD_LEDTX_PORT].DIRSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDTX_PORT].OUTTGL.reg = (1<USART.SYNCBUSY.bit.ENABLE); + /* Disable the SERCOM UART module */ + sercom->USART.CTRLA.bit.ENABLE = 0; + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.SWRST); + /* Perform a software reset */ + sercom->USART.CTRLA.bit.SWRST = 1; + /* Wait for synchronization */ + while(sercom->USART.CTRLA.bit.SWRST); + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.SWRST || sercom->USART.SYNCBUSY.bit.ENABLE); + /* Update the UART pad settings, mode and data order settings */ + sercom->USART.CTRLA.reg = pad_conf | SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD; + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.CTRLB); + /* Enable transmit and receive and set data size to 8 bits */ + sercom->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0); + /* Load the baud value */ + sercom->USART.BAUD.reg = baud_val; + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.ENABLE); + /* Enable SERCOM UART */ + sercom->USART.CTRLA.bit.ENABLE = 1; +} + +void uart_disable(Sercom *sercom) +{ + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.ENABLE); + /* Disable SERCOM UART */ + sercom->USART.CTRLA.bit.ENABLE = 0; +} + +void uart_write_byte(Sercom *sercom, uint8_t data) +{ + /* Wait for Data Register Empty flag */ + while(!sercom->USART.INTFLAG.bit.DRE); + /* Write the data to DATA register */ + sercom->USART.DATA.reg = (uint16_t)data; +} + +uint8_t uart_read_byte(Sercom *sercom) +{ + /* Wait for Receive Complete flag */ + while(!sercom->USART.INTFLAG.bit.RXC); + /* Check for errors */ + if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF) + /* Set the error flag */ + uart_drv_error_flag = true; + /* Return the read data */ + return((uint8_t)sercom->USART.DATA.reg); +} + +void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length) +{ + /* Do the following for specified length */ + do { + /* Wait for Data Register Empty flag */ + while(!sercom->USART.INTFLAG.bit.DRE); + /* Send data from the buffer */ + sercom->USART.DATA.reg = (uint16_t)*ptr++; + } while (length--); +} + +void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length) +{ + /* Do the following for specified length */ + do { + /* Wait for Receive Complete flag */ + while(!sercom->USART.INTFLAG.bit.RXC); + /* Check for errors */ + if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF) + /* Set the error flag */ + uart_drv_error_flag = true; + /* Store the read data to the buffer */ + *ptr++ = (uint8_t)sercom->USART.DATA.reg; + } while (length--); +} diff --git a/bootloaders/feather/board_driver_serial.h b/bootloaders/feather/board_driver_serial.h new file mode 100644 index 000000000..c752d977d --- /dev/null +++ b/bootloaders/feather/board_driver_serial.h @@ -0,0 +1,90 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef UART_DRIVER_H +#define UART_DRIVER_H + +#include +#include +#include + +#define PINMUX_UNUSED 0xFFFFFFFF +#define GCLK_ID_SERCOM0_CORE 0x14 + +/* SERCOM UART available pad settings */ +enum uart_pad_settings { + UART_RX_PAD0_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(1), + UART_RX_PAD1_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(1), + UART_RX_PAD2_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(2), + UART_RX_PAD3_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(3), + UART_RX_PAD1_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(1), + UART_RX_PAD3_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1), +}; + +/** + * \brief Initializes the UART + * + * \param Pointer to SERCOM instance + * \param Baud value corresponding to the desired baudrate + * \param SERCOM pad settings + */ +void uart_basic_init(Sercom *sercom, uint16_t baud_val, enum uart_pad_settings pad_conf); + +/** + * \brief Disables UART interface + * + * \param Pointer to SERCOM instance + */ +void uart_disable(Sercom *sercom); + +/** + * \brief Sends a single byte through UART interface + * + * \param Pointer to SERCOM instance + * \param Data to send + */ +void uart_write_byte(Sercom *sercom, uint8_t data); + +/** + * \brief Reads a single character from UART interface + * + * \param Pointer to SERCOM instance + * \return Data byte read + */ +uint8_t uart_read_byte(Sercom *sercom); + +/** + * \brief Sends buffer on UART interface + * + * \param Pointer to SERCOM instance + * \param Pointer to data to send + * \param Number of bytes to send + */ +void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length); + +/** + * \brief Reads data on UART interface + * + * \param Pointer to SERCOM instance + * \param Pointer to store read data + * \param Number of bytes to read + */ +void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length); + +#endif diff --git a/bootloaders/feather/board_driver_usb.c b/bootloaders/feather/board_driver_usb.c new file mode 100644 index 000000000..ca1e62a95 --- /dev/null +++ b/bootloaders/feather/board_driver_usb.c @@ -0,0 +1,402 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include "board_driver_usb.h" +#include "sam_ba_usb.h" +#include "sam_ba_cdc.h" + +#define NVM_USB_PAD_TRANSN_POS (45) +#define NVM_USB_PAD_TRANSN_SIZE (5) +#define NVM_USB_PAD_TRANSP_POS (50) +#define NVM_USB_PAD_TRANSP_SIZE (5) +#define NVM_USB_PAD_TRIM_POS (55) +#define NVM_USB_PAD_TRIM_SIZE (3) + +__attribute__((__aligned__(4))) UsbDeviceDescriptor usb_endpoint_table[MAX_EP]; // Initialized to zero in USB_Init +__attribute__((__aligned__(4))) uint8_t udd_ep_out_cache_buffer[2][64]; //1 for CTRL, 1 for BULK +__attribute__((__aligned__(4))) uint8_t udd_ep_in_cache_buffer[2][64]; //1 for CTRL, 1 for BULK + +static volatile bool read_job = false; + +/*---------------------------------------------------------------------------- + * \brief + */ +P_USB_CDC USB_Open(P_USB_CDC pCdc, Usb *pUsb) +{ + pCdc->pUsb = pUsb; + pCdc->currentConfiguration = 0; + pCdc->currentConnection = 0; + pCdc->IsConfigured = USB_IsConfigured; +// pCdc->Write = USB_Write; +// pCdc->Read = USB_Read; + + pCdc->pUsb->HOST.CTRLA.bit.ENABLE = true; + + return pCdc; +} + +/*---------------------------------------------------------------------------- + * \brief Initializes USB + */ +void USB_Init(void) +{ + uint32_t pad_transn, pad_transp, pad_trim; + + /* Enable USB clock */ + PM->APBBMASK.reg |= PM_APBBMASK_USB; + + /* Set up the USB DP/DN pins */ + PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1; + PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u))); + PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg |= MUX_PA24G_USB_DM << (4 * (PIN_PA24G_USB_DM & 0x01u)); + PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1; + PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u))); + PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u)); + + /* ---------------------------------------------------------------------------------------------- + * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference) + */ + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( 6 ) | // Generic Clock Multiplexer 6 + GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source + GCLK_CLKCTRL_CLKEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* Reset */ + USB->DEVICE.CTRLA.bit.SWRST = 1; + while (USB->DEVICE.SYNCBUSY.bit.SWRST) + { + /* Sync wait */ + } + + /* Load Pad Calibration */ + pad_transn =( *((uint32_t *)(NVMCTRL_OTP4) + + (NVM_USB_PAD_TRANSN_POS / 32)) + >> (NVM_USB_PAD_TRANSN_POS % 32)) + & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); + + if (pad_transn == 0x1F) + { + pad_transn = 5; + } + + USB->HOST.PADCAL.bit.TRANSN = pad_transn; + + pad_transp =( *((uint32_t *)(NVMCTRL_OTP4) + + (NVM_USB_PAD_TRANSP_POS / 32)) + >> (NVM_USB_PAD_TRANSP_POS % 32)) + & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); + + if (pad_transp == 0x1F) + { + pad_transp = 29; + } + + USB->HOST.PADCAL.bit.TRANSP = pad_transp; + pad_trim =( *((uint32_t *)(NVMCTRL_OTP4) + + (NVM_USB_PAD_TRIM_POS / 32)) + >> (NVM_USB_PAD_TRIM_POS % 32)) + & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); + + if (pad_trim == 0x7) + { + pad_trim = 3; + } + + USB->HOST.PADCAL.bit.TRIM = pad_trim; + + /* Set the configuration */ + /* Set mode to Device mode */ + USB->HOST.CTRLA.bit.MODE = 0; + /* Enable Run in Standby */ + USB->HOST.CTRLA.bit.RUNSTDBY = true; + /* Set the descriptor address */ + USB->HOST.DESCADD.reg = (uint32_t)(&usb_endpoint_table[0]); + /* Set speed configuration to Full speed */ + USB->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; + /* Attach to the USB host */ + USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; + + /* Initialize endpoint table RAM location to a known value 0 */ + memset((uint8_t *)(&usb_endpoint_table[0]), 0, sizeof(usb_endpoint_table)); +} + +uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num) +{ + uint32_t data_address; + uint8_t buf_index; + + /* Set buffer index */ + buf_index = (ep_num == 0) ? 0 : 1; + + /* Check for requirement for multi-packet or auto zlp */ + if (length >= (1 << (usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.SIZE + 3))) + { + /* Update the EP data address */ + data_address = (uint32_t) pData; + /* Enable auto zlp */ + usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = true; + } + else + { + /* Copy to local buffer */ + memcpy(udd_ep_in_cache_buffer[buf_index], pData, length); + /* Update the EP data address */ + data_address = (uint32_t) &udd_ep_in_cache_buffer[buf_index]; + } + + /* Set the buffer address for ep data */ + usb_endpoint_table[ep_num].DeviceDescBank[1].ADDR.reg = data_address; + /* Set the byte count as zero */ + usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = length; + /* Set the multi packet size as zero for multi-packet transfers where length > ep size */ + usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; + /* Clear the transfer complete flag */ + +#ifdef __SAMR21G18A__ + pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT1 = true; +#else + pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT |= (1<<1); +#endif + + /* Set the bank as ready */ + pUsb->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.bit.BK1RDY = true; + + /* Wait for transfer to complete */ +#ifdef __SAMR21G18A__ + while ( (pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT1) == 0 ); +#else + while ( (pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT & (1<<1)) == 0 ); +#endif + + return length; +} + +/*---------------------------------------------------------------------------- + * \brief Read available data from Endpoint OUT + */ +uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length) +{ + uint32_t packetSize = 0; + + if (!read_job) + { + /* Set the buffer address for ep data */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[USB_EP_OUT-1]; + /* Set the byte count as zero */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + /* Set the byte count as zero */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; + /* Start the reception by clearing the bank 0 ready bit */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true; + /* set the user flag */ + read_job = true; + } + + /* Check for Transfer Complete 0 flag */ +#ifdef __SAMR21G18A__ + if ( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 ) +#else + if ( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0) ) +#endif + { + /* Set packet size */ + packetSize = SAM_BA_MIN(usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT, length); + /* Copy read data to user buffer */ + memcpy(pData, udd_ep_out_cache_buffer[USB_EP_OUT-1], packetSize); + /* Clear the Transfer Complete 0 flag */ +#ifdef __SAMR21G18A__ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 = true; +#else + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT |= (1 << 0); +#endif + /* Clear the user flag */ + read_job = false; + } + + return packetSize; +} + +uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length) +{ + if (read_job) + { + /* Stop the reception by setting the bank 0 ready bit */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.bit.BK0RDY = true; + /* Clear the user flag */ + read_job = false; + } + + /* Set the buffer address for ep data */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = ((uint32_t)pData); + /* Set the byte count as zero */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + /* Set the multi packet size as zero for multi-packet transfers where length > ep size */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = length; + /* Clear the bank 0 ready flag */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true; + /* Wait for transfer to complete */ + +#ifdef __SAMR21G18A__ + while (!( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 )); + /* Clear Transfer complete 0 flag */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 = true; +#else + while (!( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0) )); + /* Clear Transfer complete 0 flag */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT |= (1 << 0); +#endif + + return length; +} + +/*---------------------------------------------------------------------------- + * \brief Test if the device is configured and handle enumeration + */ +uint8_t USB_IsConfigured(P_USB_CDC pCdc) +{ + Usb *pUsb = pCdc->pUsb; + + /* Check for End of Reset flag */ + if (pUsb->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_EORST) + { + /* Clear the flag */ + pUsb->DEVICE.INTFLAG.bit.EORST = true; + /* Set Device address as 0 */ + pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | 0; + /* Configure endpoint 0 */ + /* Configure Endpoint 0 for Control IN and Control OUT */ + pUsb->DEVICE.DeviceEndpoint[0].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1); + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; + /* Configure control OUT Packet size to 64 bytes */ + usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3; + /* Configure control IN Packet size to 64 bytes */ + usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3; + /* Configure the data buffer address for control OUT */ + usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[0]; + /* Configure the data buffer address for control IN */ + usb_endpoint_table[0].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[0]; + /* Set Multipacket size to 8 for control OUT and byte count to 0*/ + usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8; + usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + + // Reset current configuration value to 0 + pCdc->currentConfiguration = 0; + } + else + { + if (pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_RXSTP) + { + sam_ba_usb_CDC_Enumerate(pCdc); + } + } + + return pCdc->currentConfiguration; +} + +/*---------------------------------------------------------------------------- + * \brief Stall the control endpoint + */ +void USB_SendStall(Usb *pUsb, bool direction_in) +{ + /* Check the direction */ + if (direction_in) + { + /* Set STALL request on IN direction */ +#ifdef __SAMR21G18A__ + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; +#else + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ = (1<<1); +#endif + } + else + { + /* Set STALL request on OUT direction */ +#ifdef __SAMR21G18A__ + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; +#else + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ = (1<<0); +#endif + } +} + +/*---------------------------------------------------------------------------- + * \brief Send zero length packet through the control endpoint + */ +void USB_SendZlp(Usb *pUsb) +{ + /* Set the byte count as zero */ + usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = 0; + /* Clear the transfer complete flag */ +#ifdef __SAMR21G18A__ + pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT1 = true; +#else + pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT |= (1 << 1); +#endif + /* Set the bank as ready */ + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.BK1RDY = true; + /* Wait for transfer to complete */ +#ifdef __SAMR21G18A__ + while (!( pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT1 )); +#else + while (!( pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT & (1<<1) )); +#endif +} + +/*---------------------------------------------------------------------------- + * \brief Set USB device address obtained from host + */ +void USB_SetAddress(Usb *pUsb, uint16_t wValue) +{ + pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | wValue; +} + +/*---------------------------------------------------------------------------- + * \brief Configure USB device + */ +void USB_Configure(Usb *pUsb) +{ + /* Configure BULK OUT endpoint for CDC Data interface*/ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(3); + /* Set maximum packet size as 64 bytes */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3; + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; + /* Configure the data buffer */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[1]; + + /* Configure BULK IN endpoint for CDC Data interface */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(3); + /* Set maximum packet size as 64 bytes */ + usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3; + pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; + /* Configure the data buffer */ + usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[1]; + + /* Configure INTERRUPT IN endpoint for CDC COMM interface*/ + pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(4); + /* Set maximum packet size as 64 bytes */ + usb_endpoint_table[USB_EP_COMM].DeviceDescBank[1].PCKSIZE.bit.SIZE = 0; + pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; +} diff --git a/bootloaders/feather/board_driver_usb.h b/bootloaders/feather/board_driver_usb.h new file mode 100644 index 000000000..4e71b8c1a --- /dev/null +++ b/bootloaders/feather/board_driver_usb.h @@ -0,0 +1,45 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _BOARD_DRIVER_USB_H_ +#define _BOARD_DRIVER_USB_H_ + +#include "sam_ba_cdc.h" + +extern UsbDeviceDescriptor usb_endpoint_table[MAX_EP]; +extern uint8_t udd_ep_out_cache_buffer[2][64]; //1 for CTRL, 1 for BULK +extern uint8_t udd_ep_in_cache_buffer[2][64]; //1 for CTRL, 1 for BULK + +P_USB_CDC USB_Open(P_USB_CDC pCdc, Usb *pUsb); + +void USB_Init(void); + +uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num); +uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length); +uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length); + +uint8_t USB_IsConfigured(P_USB_CDC pCdc); + +void USB_SendStall(Usb *pUsb, bool direction_in); +void USB_SendZlp(Usb *pUsb); + +void USB_SetAddress(Usb *pUsb, uint16_t wValue); +void USB_Configure(Usb *pUsb); + +#endif // _BOARD_DRIVER_USB_H_ diff --git a/bootloaders/feather/board_init.c b/bootloaders/feather/board_init.c new file mode 100644 index 000000000..c08aedaae --- /dev/null +++ b/bootloaders/feather/board_init.c @@ -0,0 +1,210 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include "board_definitions.h" + +/** + * \brief system_init() configures the needed clocks and according Flash Read Wait States. + * At reset: + * - OSC8M clock source is enabled with a divider by 8 (1MHz). + * - Generic Clock Generator 0 (GCLKMAIN) is using OSC8M as source. + * We need to: + * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator), will be used as DFLL48M reference. + * 2) Put XOSC32K as source of Generic Clock Generator 1 + * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) + * 4) Enable DFLL48M clock + * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + * 6) Modify PRESCaler value of OSCM to have 8MHz + * 7) Put OSC8M as source for Generic Clock Generator 3 + */ +// Constants for Clock generators +#define GENERIC_CLOCK_GENERATOR_MAIN (0u) +#define GENERIC_CLOCK_GENERATOR_XOSC32K (1u) +#define GENERIC_CLOCK_GENERATOR_OSCULP32K (2u) /* Initialized at reset for WDT */ +#define GENERIC_CLOCK_GENERATOR_OSC8M (3u) +// Constants for Clock multiplexers +#define GENERIC_CLOCK_MULTIPLEXER_DFLL48M (0u) + +void board_init(void) +{ + /* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */ + NVMCTRL->CTRLB.bit.RWS = NVMCTRL_CTRLB_RWS_HALF_Val; + + /* Turn on the digital interface clock */ + PM->APBAMASK.reg |= PM_APBAMASK_GCLK; + + /* ---------------------------------------------------------------------------------------------- + * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator) + */ + SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP( 0x6u ) | /* cf table 15.10 of product datasheet in chapter 15.8.6 */ + SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K; + SYSCTRL->XOSC32K.bit.ENABLE = 1; /* separate call, as described in chapter 15.6.3 */ + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY) == 0 ) + { + /* Wait for oscillator stabilization */ + } + + /* Software reset the module to ensure it is re-initialized correctly */ + /* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete. + * CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1 + */ + GCLK->CTRL.reg = GCLK_CTRL_SWRST; + + while ( (GCLK->CTRL.reg & GCLK_CTRL_SWRST) && (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) ) + { + /* Wait for reset to complete */ + } + + /* ---------------------------------------------------------------------------------------------- + * 2) Put XOSC32K as source of Generic Clock Generator 1 + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ); // Generic Clock Generator 1 + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* Write Generic Clock Generator 1 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) | // Generic Clock Generator 1 + GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator +// GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_GENEN; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) + */ + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GENERIC_CLOCK_MULTIPLEXER_DFLL48M ) | // Generic Clock Multiplexer 0 + GCLK_CLKCTRL_GEN_GCLK1 | // Generic Clock Generator 1 is source + GCLK_CLKCTRL_CLKEN; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 4) Enable DFLL48M clock + */ + + /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */ + + /* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */ + SYSCTRL->DFLLCTRL.bit.ONDEMAND = 0; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value + SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value + SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK/VARIANT_MAINOSC) ); // External 32KHz is the reference + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* Write full configuration to DFLL control register */ + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */ + SYSCTRL_DFLLCTRL_WAITLOCK | + SYSCTRL_DFLLCTRL_QLDIS; /* Disable Quick lock */ + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* Enable the DFLL */ + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) == 0 || + (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF) == 0 ) + { + /* Wait for locks flags */ + } + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_MAIN ); // Generic Clock Generator 0 + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* Write Generic Clock Generator 0 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0 + GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz +// GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_IDC | // Set 50/50 duty cycle + GCLK_GENCTRL_GENEN; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + +#if 0 + /* ---------------------------------------------------------------------------------------------- + * 6) Modify PRESCaler value of OSC8M to have 8MHz + */ + SYSCTRL->OSC8M.bit.PRESC = SYSCTRL_OSC8M_PRESC_1_Val; + SYSCTRL->OSC8M.bit.ONDEMAND = 0; + + /* ---------------------------------------------------------------------------------------------- + * 7) Put OSC8M as source for Generic Clock Generator 3 + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ); // Generic Clock Generator 3 + + /* Write Generic Clock Generator 3 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3 + GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset) +// GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_GENEN; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } +#endif //0 + + /* + * Now that all system clocks are configured, we can set CPU and APBx BUS clocks. + * These values are normally the ones present after Reset. + */ + PM->CPUSEL.reg = PM_CPUSEL_CPUDIV_DIV1; + PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val; + PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val; + PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val; +} diff --git a/bootloaders/feather/board_startup.c b/bootloaders/feather/board_startup.c new file mode 100644 index 000000000..aaa5a019f --- /dev/null +++ b/bootloaders/feather/board_startup.c @@ -0,0 +1,147 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include + +struct ConstVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; +}; + +/* Symbols exported from linker script */ +extern uint32_t __etext ; +extern uint32_t __data_start__ ; +extern uint32_t __data_end__ ; +extern uint32_t __bss_start__ ; +extern uint32_t __bss_end__ ; +extern uint32_t __StackTop; + +extern int main(void); +extern void __libc_init_array(void); + +/* Exception Table */ +__attribute__ ((section(".isr_vector"))) +const struct ConstVectors exception_table = +{ + /* Configure Initial Stack Pointer, using linker-generated symbols */ + .pvStack = (void*) (&__StackTop), + + .pfnReset_Handler = (void*) Reset_Handler, + .pfnNMI_Handler = (void*) NMI_Handler, + .pfnHardFault_Handler = (void*) HardFault_Handler, + .pfnReservedM12 = (void*) (0UL), /* Reserved */ + .pfnReservedM11 = (void*) (0UL), /* Reserved */ + .pfnReservedM10 = (void*) (0UL), /* Reserved */ + .pfnReservedM9 = (void*) (0UL), /* Reserved */ + .pfnReservedM8 = (void*) (0UL), /* Reserved */ + .pfnReservedM7 = (void*) (0UL), /* Reserved */ + .pfnReservedM6 = (void*) (0UL), /* Reserved */ + .pfnSVC_Handler = (void*) SVC_Handler, + .pfnReservedM4 = (void*) (0UL), /* Reserved */ + .pfnReservedM3 = (void*) (0UL), /* Reserved */ + .pfnPendSV_Handler = (void*) PendSV_Handler, + .pfnSysTick_Handler = (void*) SysTick_Handler, +}; + +/** + * \brief This is the code that gets called on processor reset. + * Initializes the device and call the main() routine. + */ +void Reset_Handler( void ) +{ + uint32_t *pSrc, *pDest; + + /* Initialize the initialized data section */ + pSrc = &__etext; + pDest = &__data_start__; + + if ( (&__data_start__ != &__data_end__) && (pSrc != pDest) ) + { + for (; pDest < &__data_end__ ; pDest++, pSrc++ ) + { + *pDest = *pSrc ; + } + } + + /* Clear the zero section */ + if ( &__bss_start__ != &__bss_end__ ) + { + for ( pDest = &__bss_start__ ; pDest < &__bss_end__ ; pDest++ ) + { + *pDest = 0ul ; + } + } + +// board_init(); // will be done in main() after app check + + /* Initialize the C library */ +// __libc_init_array(); + + main(); + + while (1); +} + +void NMI_Handler(void) +{ + __BKPT(14); + while (1); +} + +void HardFault_Handler(void) +{ + __BKPT(13); + while (1); +} + +void SVC_Handler(void) +{ + __BKPT(5); + while (1); +} + +void PendSV_Handler(void) +{ + __BKPT(2); + while (1); +} + +void SysTick_Handler(void) +{ + __BKPT(1); + while (1); +} diff --git a/bootloaders/feather/bootloader_samd21x18.ld b/bootloaders/feather/bootloader_samd21x18.ld new file mode 100644 index 000000000..2a8b056d3 --- /dev/null +++ b/bootloaders/feather/bootloader_samd21x18.ld @@ -0,0 +1,221 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000-0x0004 /* 4 bytes used by bootloader to keep data between resets */ +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __sketch_vectors_ptr + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + . = ORIGIN(FLASH); + + .vectors : + { + KEEP(*(.isr_vector)) + } > FLASH + + .text : + { + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + PROVIDE(__sketch_vectors_ptr = ORIGIN(FLASH) + LENGTH(FLASH)); + + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/bootloaders/feather/main.c b/bootloaders/feather/main.c new file mode 100644 index 000000000..b490596b4 --- /dev/null +++ b/bootloaders/feather/main.c @@ -0,0 +1,247 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include +#include "sam_ba_monitor.h" +#include "sam_ba_serial.h" +#include "board_definitions.h" +#include "board_driver_led.h" +#include "sam_ba_usb.h" +#include "sam_ba_cdc.h" + +extern uint32_t __sketch_vectors_ptr; // Exported value from linker script +extern void board_init(void); + +#if (defined DEBUG) && (DEBUG == 1) +volatile uint32_t* pulSketch_Start_Address; +#endif + +static volatile bool main_b_cdc_enable = false; + +/** + * \brief Check the application startup condition + * + */ +static void check_start_application(void) +{ + LED_init(); + LED_off(); + +#if defined(BOOT_DOUBLE_TAP_ADDRESS) + #define DOUBLE_TAP_MAGIC 0x07738135 + if (PM->RCAUSE.bit.POR) + { + /* On power-on initialize double-tap */ + BOOT_DOUBLE_TAP_DATA = 0; + } + else + { + if (BOOT_DOUBLE_TAP_DATA == DOUBLE_TAP_MAGIC) + { + /* Second tap, stay in bootloader */ + BOOT_DOUBLE_TAP_DATA = 0; + return; + } + + /* First tap */ + BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC; + + /* Wait 0.5sec to see if the user tap reset again. + * The loop value is based on SAMD21 default 1MHz clock @ reset. + */ + for (uint32_t i=0; i<125000; i++) /* 500ms */ + /* force compiler to not optimize this... */ + __asm__ __volatile__(""); + + /* Timeout happened, continue boot... */ + BOOT_DOUBLE_TAP_DATA = 0; + } +#endif + +#if (!defined DEBUG) || ((defined DEBUG) && (DEBUG == 0)) +uint32_t* pulSketch_Start_Address; +#endif + + /* + * Test sketch stack pointer @ &__sketch_vectors_ptr + * Stay in SAM-BA if value @ (&__sketch_vectors_ptr) == 0xFFFFFFFF (Erased flash cell value) + */ + if (__sketch_vectors_ptr == 0xFFFFFFFF) + { + /* Stay in bootloader */ + return; + } + + /* + * Load the sketch Reset Handler address + * __sketch_vectors_ptr is exported from linker script and point on first 32b word of sketch vector table + * First 32b word is sketch stack + * Second 32b word is sketch entry point: Reset_Handler() + */ + pulSketch_Start_Address = &__sketch_vectors_ptr ; + pulSketch_Start_Address++ ; + + /* + * Test vector table address of sketch @ &__sketch_vectors_ptr + * Stay in SAM-BA if this function is not aligned enough, ie not valid + */ + if ( ((uint32_t)(&__sketch_vectors_ptr) & ~SCB_VTOR_TBLOFF_Msk) != 0x00) + { + /* Stay in bootloader */ + return; + } + +/* +#if defined(BOOT_LOAD_PIN) + volatile PortGroup *boot_port = (volatile PortGroup *)(&(PORT->Group[BOOT_LOAD_PIN / 32])); + volatile bool boot_en; + + // Enable the input mode in Boot GPIO Pin + boot_port->DIRCLR.reg = BOOT_PIN_MASK; + boot_port->PINCFG[BOOT_LOAD_PIN & 0x1F].reg = PORT_PINCFG_INEN | PORT_PINCFG_PULLEN; + boot_port->OUTSET.reg = BOOT_PIN_MASK; + // Read the BOOT_LOAD_PIN status + boot_en = (boot_port->IN.reg) & BOOT_PIN_MASK; + + // Check the bootloader enable condition + if (!boot_en) + { + // Stay in bootloader + return; + } +#endif +*/ + + LED_on(); + + /* Rebase the Stack Pointer */ + __set_MSP( (uint32_t)(__sketch_vectors_ptr) ); + + /* Rebase the vector table base address */ + SCB->VTOR = ((uint32_t)(&__sketch_vectors_ptr) & SCB_VTOR_TBLOFF_Msk); + + /* Jump to application Reset Handler in the application */ + asm("bx %0"::"r"(*pulSketch_Start_Address)); +} + +#if DEBUG_ENABLE +# define DEBUG_PIN_HIGH port_pin_set_output_level(BOOT_LED, 1) +# define DEBUG_PIN_LOW port_pin_set_output_level(BOOT_LED, 0) +#else +# define DEBUG_PIN_HIGH do{}while(0) +# define DEBUG_PIN_LOW do{}while(0) +#endif + +/** + * \brief SAMD21 SAM-BA Main loop. + * \return Unused (ANSI-C compatibility). + */ +int main(void) +{ +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + P_USB_CDC pCdc; +#endif + DEBUG_PIN_HIGH; + + /* Jump in application if condition is satisfied */ + check_start_application(); + + /* We have determined we should stay in the monitor. */ + /* System initialization */ + board_init(); + __enable_irq(); + +#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + /* UART is enabled in all cases */ + serial_open(); +#endif + +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + pCdc = usb_init(); +#endif + + DEBUG_PIN_LOW; + + LED_on(); + + /* Wait for a complete enum on usb or a '#' char on serial line */ + while (1) + { + pulse_led(3); // while we're waiting, blink the D13 + +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + if (pCdc->IsConfigured(pCdc) != 0) + { + main_b_cdc_enable = true; + } + + /* Check if a USB enumeration has succeeded and if comm port has been opened */ + if (main_b_cdc_enable) + { + sam_ba_monitor_init(SAM_BA_INTERFACE_USBCDC); + /* SAM-BA on USB loop */ + while( 1 ) + { + sam_ba_monitor_run(); + } + } +#endif + +#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + /* Check if a '#' has been received */ + if (!main_b_cdc_enable && serial_sharp_received()) + { + sam_ba_monitor_init(SAM_BA_INTERFACE_USART); + /* SAM-BA on Serial loop */ + while(1) + { + sam_ba_monitor_run(); + } + } +#endif + } +} + + +// We'll have the D13 LED slowly pulse on and off with bitbang PWM +// for a nice 'hey we're in bootload mode' indication! -ada +static uint16_t pulse_tick=0; +#define BOOT_PULSE_MAX 1000 +static int8_t pulse_dir=1; +static int16_t pulse_pwm; +void pulse_led(int8_t speed) { + // blink D13 + pulse_tick++; + if (pulse_tick==BOOT_PULSE_MAX) { + pulse_tick = 0; + pulse_pwm += pulse_dir * speed; + if (pulse_pwm > 255) { + pulse_pwm = 255; + pulse_dir = -1; + } + if (pulse_pwm < 0) { + pulse_pwm = 0; + pulse_dir = +1; + } + LED_on(); + } + if (pulse_tick==pulse_pwm) + LED_off(); +} diff --git a/bootloaders/feather/sam_ba_cdc.c b/bootloaders/feather/sam_ba_cdc.c new file mode 100644 index 000000000..23001cc7f --- /dev/null +++ b/bootloaders/feather/sam_ba_cdc.c @@ -0,0 +1,102 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include "sam_ba_cdc.h" +#include "board_driver_usb.h" + +usb_cdc_line_coding_t line_coding= +{ + 115200, // baudrate + 0, // 1 Stop Bit + 0, // None Parity + 8 // 8 Data bits +}; + +#define pCdc (&sam_ba_cdc) + +int cdc_putc(/*P_USB_CDC pCdc,*/ int value) +{ + /* Send single byte on USB CDC */ + USB_Write(pCdc->pUsb, (const char *)&value, 1, USB_EP_IN); + + return 1; +} + +int cdc_getc(/*P_USB_CDC pCdc*/void) +{ + uint8_t rx_char; + + /* Read singly byte on USB CDC */ + USB_Read(pCdc->pUsb, (char *)&rx_char, 1); + + return (int)rx_char; +} + +bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/void) +{ + /* Check whether the device is configured */ + if ( !USB_IsConfigured(pCdc) ) + return 0; + + /* Return transfer complete 0 flag status */ +#ifdef __SAMR21G18A__ + return (pCdc->pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0); +#else + return (pCdc->pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0)); +#endif +} + +uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length) +{ + /* Send the specified number of bytes on USB CDC */ + USB_Write(pCdc->pUsb, (const char *)data, length, USB_EP_IN); + return length; +} + +uint32_t cdc_read_buf(/*P_USB_CDC pCdc,*/ void* data, uint32_t length) +{ + /* Check whether the device is configured */ + if ( !USB_IsConfigured(pCdc) ) + return 0; + + /* Read from USB CDC */ + return USB_Read(pCdc->pUsb, (char *)data, length); +} + +uint32_t cdc_read_buf_xmd(/*P_USB_CDC pCdc,*/ void* data, uint32_t length) +{ + /* Check whether the device is configured */ + if ( !USB_IsConfigured(pCdc) ) + return 0; + + /* Blocking read till specified number of bytes is received */ + // XXX: USB_Read_blocking is not reliable + // return USB_Read_blocking(pCdc, (char *)data, length); + + char *dst = (char *)data; + uint32_t remaining = length; + while (remaining) + { + uint32_t readed = USB_Read(pCdc->pUsb, (char *)dst, remaining); + remaining -= readed; + dst += readed; + } + + return length; +} diff --git a/bootloaders/feather/sam_ba_cdc.h b/bootloaders/feather/sam_ba_cdc.h new file mode 100644 index 000000000..49b7643cf --- /dev/null +++ b/bootloaders/feather/sam_ba_cdc.h @@ -0,0 +1,91 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _SAM_BA_USB_CDC_H_ +#define _SAM_BA_USB_CDC_H_ + +#include +#include "sam_ba_usb.h" + +typedef struct +{ + uint32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; + +/* CDC Class Specific Request Code */ +#define GET_LINE_CODING 0x21A1 +#define SET_LINE_CODING 0x2021 +#define SET_CONTROL_LINE_STATE 0x2221 + +extern usb_cdc_line_coding_t line_coding; + + +/** + * \brief Sends a single byte through USB CDC + * + * \param Data to send + * \return number of data sent + */ +int cdc_putc(/*P_USB_CDC pCdc,*/ int value); + +/** + * \brief Reads a single byte through USB CDC + * + * \return Data read through USB + */ +int cdc_getc(/*P_USB_CDC pCdc*/); + +/** + * \brief Checks if a character has been received on USB CDC + * + * \return \c 1 if a byte is ready to be read. + */ +bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/); + +/** + * \brief Sends buffer on USB CDC + * + * \param data pointer + * \param number of data to send + * \return number of data sent + */ +uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length); + +/** + * \brief Gets data on USB CDC + * + * \param data pointer + * \param number of data to read + * \return number of data read + */ +uint32_t cdc_read_buf(/*P_USB_CDC pCdc,*/ void* data, uint32_t length); + +/** + * \brief Gets specified number of bytes on USB CDC + * + * \param data pointer + * \param number of data to read + * \return number of data read + */ +uint32_t cdc_read_buf_xmd(/*P_USB_CDC pCdc,*/ void* data, uint32_t length); + +#endif // _SAM_BA_USB_CDC_H_ diff --git a/bootloaders/feather/sam_ba_monitor.c b/bootloaders/feather/sam_ba_monitor.c new file mode 100644 index 000000000..ddf7b9773 --- /dev/null +++ b/bootloaders/feather/sam_ba_monitor.c @@ -0,0 +1,474 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include "sam.h" +#include +#include "sam_ba_monitor.h" +#include "sam_ba_serial.h" +#include "board_driver_serial.h" +#include "board_driver_usb.h" +#include "sam_ba_usb.h" +#include "sam_ba_cdc.h" + +const char RomBOOT_Version[] = SAM_BA_VERSION; +const char RomBOOT_ExtendedCapabilities[] = "[Arduino:XYZ]"; + +/* Provides one common interface to handle both USART and USB-CDC */ +typedef struct +{ + /* send one byte of data */ + int (*put_c)(int value); + /* Get one byte */ + int (*get_c)(void); + /* Receive buffer not empty */ + bool (*is_rx_ready)(void); + /* Send given data (polling) */ + uint32_t (*putdata)(void const* data, uint32_t length); + /* Get data from comm. device */ + uint32_t (*getdata)(void* data, uint32_t length); + /* Send given data (polling) using xmodem (if necessary) */ + uint32_t (*putdata_xmd)(void const* data, uint32_t length); + /* Get data from comm. device using xmodem (if necessary) */ + uint32_t (*getdata_xmd)(void* data, uint32_t length); +} t_monitor_if; + +#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES +/* Initialize structures with function pointers from supported interfaces */ +const t_monitor_if uart_if = +{ + .put_c = serial_putc, + .get_c = serial_getc, + .is_rx_ready = serial_is_rx_ready, + .putdata = serial_putdata, + .getdata = serial_getdata, + .putdata_xmd = serial_putdata_xmd, + .getdata_xmd = serial_getdata_xmd +}; +#endif + +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES +//Please note that USB doesn't use Xmodem protocol, since USB already includes flow control and data verification +//Data are simply forwarded without further coding. +const t_monitor_if usbcdc_if = +{ + .put_c = cdc_putc, + .get_c = cdc_getc, + .is_rx_ready = cdc_is_rx_ready, + .putdata = cdc_write_buf, + .getdata = cdc_read_buf, + .putdata_xmd = cdc_write_buf, + .getdata_xmd = cdc_read_buf_xmd +}; +#endif + +/* The pointer to the interface object use by the monitor */ +t_monitor_if * ptr_monitor_if; + +/* b_terminal_mode mode (ascii) or hex mode */ +volatile bool b_terminal_mode = false; +volatile bool b_sam_ba_interface_usart = false; + +void sam_ba_monitor_init(uint8_t com_interface) +{ +#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + //Selects the requested interface for future actions + if (com_interface == SAM_BA_INTERFACE_USART) + { + ptr_monitor_if = (t_monitor_if*) &uart_if; + b_sam_ba_interface_usart = true; + } +#endif +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + if (com_interface == SAM_BA_INTERFACE_USBCDC) + { + ptr_monitor_if = (t_monitor_if*) &usbcdc_if; + } +#endif +} + +/** + * \brief This function allows data rx by USART + * + * \param *data Data pointer + * \param length Length of the data + */ +void sam_ba_putdata_term(uint8_t* data, uint32_t length) +{ + uint8_t temp, buf[12], *data_ascii; + uint32_t i, int_value; + + if (b_terminal_mode) + { + if (length == 4) + int_value = *(uint32_t *) data; + else if (length == 2) + int_value = *(uint16_t *) data; + else + int_value = *(uint8_t *) data; + + data_ascii = buf + 2; + data_ascii += length * 2 - 1; + + for (i = 0; i < length * 2; i++) + { + temp = (uint8_t) (int_value & 0xf); + + if (temp <= 0x9) + *data_ascii = temp | 0x30; + else + *data_ascii = temp + 0x37; + + int_value >>= 4; + data_ascii--; + } + buf[0] = '0'; + buf[1] = 'x'; + buf[length * 2 + 2] = '\n'; + buf[length * 2 + 3] = '\r'; + ptr_monitor_if->putdata(buf, length * 2 + 4); + } + else + ptr_monitor_if->putdata(data, length); + return; +} + +volatile uint32_t sp; +void call_applet(uint32_t address) +{ + uint32_t app_start_address; + + __disable_irq(); + + sp = __get_MSP(); + + /* Rebase the Stack Pointer */ + __set_MSP(*(uint32_t *) address); + + /* Load the Reset Handler address of the application */ + app_start_address = *(uint32_t *)(address + 4); + + /* Jump to application Reset Handler in the application */ + asm("bx %0"::"r"(app_start_address)); +} + +uint32_t current_number; +uint32_t i, length; +uint8_t command, *ptr_data, *ptr, data[SIZEBUFMAX]; +uint8_t j; +uint32_t u32tmp; + +uint32_t PAGE_SIZE, PAGES, MAX_FLASH; + +// Prints a 32-bit integer in hex. +static void put_uint32(uint32_t n) +{ + char buff[8]; + int i; + for (i=0; i<8; i++) + { + int d = n & 0XF; + n = (n >> 4); + + buff[7-i] = d > 9 ? 'A' + d - 10 : '0' + d; + } + ptr_monitor_if->putdata(buff, 8); +} + +static void sam_ba_monitor_loop(void) +{ + pulse_led(3); + + length = ptr_monitor_if->getdata(data, SIZEBUFMAX); + ptr = data; + + for (i = 0; i < length; i++, ptr++) + { + if (*ptr == 0xff) continue; + + if (*ptr == '#') + { + if (b_terminal_mode) + { + ptr_monitor_if->putdata("\n\r", 2); + } + if (command == 'S') + { + //Check if some data are remaining in the "data" buffer + if(length>i) + { + //Move current indexes to next avail data (currently ptr points to "#") + ptr++; + i++; + + //We need to add first the remaining data of the current buffer already read from usb + //read a maximum of "current_number" bytes + if ((length-i) < current_number) + { + u32tmp=(length-i); + } + else + { + u32tmp=current_number; + } + + memcpy(ptr_data, ptr, u32tmp); + i += u32tmp; + ptr += u32tmp; + j = u32tmp; + } + //update i with the data read from the buffer + i--; + ptr--; + //Do we expect more data ? + if(jgetdata_xmd(ptr_data, current_number-j); + + __asm("nop"); + } + else if (command == 'R') + { + ptr_monitor_if->putdata_xmd(ptr_data, current_number); + } + else if (command == 'O') + { + *ptr_data = (char) current_number; + } + else if (command == 'H') + { + *((uint16_t *) ptr_data) = (uint16_t) current_number; + } + else if (command == 'W') + { + *((int *) ptr_data) = current_number; + } + else if (command == 'o') + { + sam_ba_putdata_term(ptr_data, 1); + } + else if (command == 'h') + { + current_number = *((uint16_t *) ptr_data); + sam_ba_putdata_term((uint8_t*) ¤t_number, 2); + } + else if (command == 'w') + { + current_number = *((uint32_t *) ptr_data); + sam_ba_putdata_term((uint8_t*) ¤t_number, 4); + } + else if (command == 'G') + { + call_applet(current_number); + /* Rebase the Stack Pointer */ + __set_MSP(sp); + __enable_irq(); + if (b_sam_ba_interface_usart) { + ptr_monitor_if->put_c(0x6); + } + } + else if (command == 'T') + { + b_terminal_mode = 1; + ptr_monitor_if->putdata("\n\r", 2); + } + else if (command == 'N') + { + if (b_terminal_mode == 0) + { + ptr_monitor_if->putdata("\n\r", 2); + } + b_terminal_mode = 0; + } + else if (command == 'V') + { + ptr_monitor_if->putdata("v", 1); + ptr_monitor_if->putdata((uint8_t *) RomBOOT_Version, strlen(RomBOOT_Version)); + ptr_monitor_if->putdata(" ", 1); + ptr_monitor_if->putdata((uint8_t *) RomBOOT_ExtendedCapabilities, strlen(RomBOOT_ExtendedCapabilities)); + ptr_monitor_if->putdata(" ", 1); + ptr = (uint8_t*) &(__DATE__); + i = 0; + while (*ptr++ != '\0') + i++; + ptr_monitor_if->putdata((uint8_t *) &(__DATE__), i); + ptr_monitor_if->putdata(" ", 1); + i = 0; + ptr = (uint8_t*) &(__TIME__); + while (*ptr++ != '\0') + i++; + ptr_monitor_if->putdata((uint8_t *) &(__TIME__), i); + ptr_monitor_if->putdata("\n\r", 2); + } + else if (command == 'X') + { + // Syntax: X[ADDR]# + // Erase the flash memory starting from ADDR to the end of flash. + + // Note: the flash memory is erased in ROWS, that is in block of 4 pages. + // Even if the starting address is the last byte of a ROW the entire + // ROW is erased anyway. + + uint32_t dst_addr = current_number; // starting address + + while (dst_addr < MAX_FLASH) + { + // Execute "ER" Erase Row + NVMCTRL->ADDR.reg = dst_addr / 2; + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER; + while (NVMCTRL->INTFLAG.bit.READY == 0) + ; + dst_addr += PAGE_SIZE * 4; // Skip a ROW + } + + // Notify command completed + ptr_monitor_if->putdata("X\n\r", 3); + } + else if (command == 'Y') + { + // This command writes the content of a buffer in SRAM into flash memory. + + // Syntax: Y[ADDR],0# + // Set the starting address of the SRAM buffer. + + // Syntax: Y[ROM_ADDR],[SIZE]# + // Write the first SIZE bytes from the SRAM buffer (previously set) into + // flash memory starting from address ROM_ADDR + + static uint32_t *src_buff_addr = NULL; + + if (current_number == 0) + { + // Set buffer address + src_buff_addr = (uint32_t*)ptr_data; + } + else + { + // Write to flash + uint32_t size = current_number/4; + uint32_t *src_addr = src_buff_addr; + uint32_t *dst_addr = (uint32_t*)ptr_data; + + // Set automatic page write + NVMCTRL->CTRLB.bit.MANW = 0; + + // Do writes in pages + while (size) + { + // Execute "PBC" Page Buffer Clear + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC; + while (NVMCTRL->INTFLAG.bit.READY == 0) + ; + + // Fill page buffer + uint32_t i; + for (i=0; i<(PAGE_SIZE/4) && iADDR.reg = ((uint32_t)dst_addr) / 2; + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP; + while (NVMCTRL->INTFLAG.bit.READY == 0) + ; + + // Advance to next page + dst_addr += i; + src_addr += i; + size -= i; + } + } + + // Notify command completed + ptr_monitor_if->putdata("Y\n\r", 3); + } + else if (command == 'Z') + { + // This command calculate CRC for a given area of memory. + // It's useful to quickly check if a transfer has been done + // successfully. + + // Syntax: Z[START_ADDR],[SIZE]# + // Returns: Z[CRC]# + + uint8_t *data = (uint8_t *)ptr_data; + uint32_t size = current_number; + uint16_t crc = 0; + uint32_t i = 0; + for (i=0; iputdata("Z", 1); + put_uint32(crc); + ptr_monitor_if->putdata("#\n\r", 3); + } + + command = 'z'; + current_number = 0; + + if (b_terminal_mode) + { + ptr_monitor_if->putdata(">", 1); + } + } + else + { + if (('0' <= *ptr) && (*ptr <= '9')) + { + current_number = (current_number << 4) | (*ptr - '0'); + } + else if (('A' <= *ptr) && (*ptr <= 'F')) + { + current_number = (current_number << 4) | (*ptr - 'A' + 0xa); + } + else if (('a' <= *ptr) && (*ptr <= 'f')) + { + current_number = (current_number << 4) | (*ptr - 'a' + 0xa); + } + else if (*ptr == ',') + { + ptr_data = (uint8_t *) current_number; + current_number = 0; + } + else + { + command = *ptr; + current_number = 0; + } + } + } +} + +/** + * \brief This function starts the SAM-BA monitor. + */ +void sam_ba_monitor_run(void) +{ + uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 }; + PAGE_SIZE = pageSizes[NVMCTRL->PARAM.bit.PSZ]; + PAGES = NVMCTRL->PARAM.bit.NVMP; + MAX_FLASH = PAGE_SIZE * PAGES; + + ptr_data = NULL; + command = 'z'; + while (1) + { + sam_ba_monitor_loop(); + } +} diff --git a/bootloaders/feather/sam_ba_monitor.h b/bootloaders/feather/sam_ba_monitor.h new file mode 100644 index 000000000..e72582bcf --- /dev/null +++ b/bootloaders/feather/sam_ba_monitor.h @@ -0,0 +1,66 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _MONITOR_SAM_BA_H_ +#define _MONITOR_SAM_BA_H_ + +#define SAM_BA_VERSION "2.0" + +/* Enable the interfaces to save code size */ +#define SAM_BA_BOTH_INTERFACES 0 +#define SAM_BA_UART_ONLY 1 +#define SAM_BA_USBCDC_ONLY 2 + +#ifndef SAM_BA_INTERFACE +#define SAM_BA_INTERFACE SAM_BA_BOTH_INTERFACES +#endif + +/* Selects USB as the communication interface of the monitor */ +#define SAM_BA_INTERFACE_USBCDC 0 +/* Selects USART as the communication interface of the monitor */ +#define SAM_BA_INTERFACE_USART 1 + +/* Selects USB as the communication interface of the monitor */ +#define SIZEBUFMAX 64 + +/** + * \brief Initialize the monitor + * + */ +void sam_ba_monitor_init(uint8_t com_interface); + +/** + * \brief Main function of the SAM-BA Monitor + * + */ +void sam_ba_monitor_run(void); + +/** + * \brief + * + */ +void sam_ba_putdata_term(uint8_t* data, uint32_t length); + +/** + * \brief + * + */ +void call_applet(uint32_t address); + +#endif // _MONITOR_SAM_BA_H_ diff --git a/bootloaders/feather/sam_ba_serial.c b/bootloaders/feather/sam_ba_serial.c new file mode 100644 index 000000000..09607ecf6 --- /dev/null +++ b/bootloaders/feather/sam_ba_serial.c @@ -0,0 +1,534 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include "board_definitions.h" +#include "sam_ba_serial.h" +#include "board_driver_serial.h" + +/* Local reference to current Usart instance in use with this driver */ +//struct usart_module usart_sam_ba; + +/* Variable to let the main task select the appropriate communication interface */ +volatile uint8_t b_sharp_received; + +/* RX and TX Buffers + rw pointers for each buffer */ +volatile uint8_t buffer_rx_usart[USART_BUFFER_SIZE]; + +volatile uint8_t idx_rx_read; +volatile uint8_t idx_rx_write; + +volatile uint8_t buffer_tx_usart[USART_BUFFER_SIZE]; + +volatile uint8_t idx_tx_read; +volatile uint8_t idx_tx_write; + +/* Test for timeout in AT91F_GetChar */ +uint8_t error_timeout; +uint16_t size_of_data; +uint8_t mode_of_transfer; + +#define BOOT_USART_PAD(n) BOOT_USART_PAD##n + +/** + * \brief Open the given USART + */ +void serial_open(void) +{ + uint32_t port; + uint32_t pin; + + /* Configure the port pins for SERCOM_USART */ + if (BOOT_USART_PAD0 != PINMUX_UNUSED) + { + /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ + port = (BOOT_USART_PAD0 & 0x200000) >> 21; + pin = (BOOT_USART_PAD0 >> 16); + PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; + PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); + PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD0 & 0xFF) << (4 * (pin & 0x01u)); + } + + if (BOOT_USART_PAD1 != PINMUX_UNUSED) + { + /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ + port = (BOOT_USART_PAD1 & 0x200000) >> 21; + pin = BOOT_USART_PAD1 >> 16; + PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; + PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); + PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD1 & 0xFF) << (4 * (pin & 0x01u)); + } + + if (BOOT_USART_PAD2 != PINMUX_UNUSED) + { + /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ + port = (BOOT_USART_PAD2 & 0x200000) >> 21; + pin = BOOT_USART_PAD2 >> 16; + PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; + PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); + PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD2 & 0xFF) << (4 * (pin & 0x01u)); + } + + if (BOOT_USART_PAD3 != PINMUX_UNUSED) + { + /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ + port = (BOOT_USART_PAD3 & 0x200000) >> 21; + pin = BOOT_USART_PAD3 >> 16; + PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; + PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); + PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD3 & 0xFF) << (4 * (pin & 0x01u)); + } + + /* Enable clock for BOOT_USART_MODULE */ + PM->APBCMASK.reg |= BOOT_USART_BUS_CLOCK_INDEX ; + + /* Set GCLK_GEN0 as source for GCLK_ID_SERCOMx_CORE */ + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( BOOT_USART_PER_CLOCK_INDEX ) | // Generic Clock 0 (SERCOMx) + GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source + GCLK_CLKCTRL_CLKEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* Baud rate 115200 - clock 48MHz -> BAUD value-63018 */ + uart_basic_init(BOOT_USART_MODULE, 63018, BOOT_USART_PAD_SETTINGS); + + //Initialize flag + b_sharp_received = false; + idx_rx_read = 0; + idx_rx_write = 0; + idx_tx_read = 0; + idx_tx_write = 0; + + error_timeout = 0; +} + +/** + * \brief Close communication line + */ +void serial_close(void) +{ + uart_disable(BOOT_USART_MODULE); +} + +/** + * \brief Puts a byte on usart line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int serial_putc(int value) +{ + uart_write_byte(BOOT_USART_MODULE, (uint8_t)value); + return 1; +} + +int serial_getc(void) +{ + uint16_t retval; + //Wait until input buffer is filled + while(!(serial_is_rx_ready())); + retval = (uint16_t)uart_read_byte(BOOT_USART_MODULE); + //usart_read_wait(&usart_sam_ba, &retval); + return (int)retval; + +} + +int serial_sharp_received(void) +{ + if (serial_is_rx_ready()) + { + if (serial_getc() == SHARP_CHARACTER) + return (true); + } + return (false); +} + +bool serial_is_rx_ready(void) +{ + return (BOOT_USART_MODULE->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_RXC); +} + +int serial_readc(void) +{ + int retval; + retval = buffer_rx_usart[idx_rx_read]; + idx_rx_read = (idx_rx_read + 1) & (USART_BUFFER_SIZE - 1); + return (retval); +} + +//Send given data (polling) +uint32_t serial_putdata(void const* data, uint32_t length) +{ + uint32_t i; + uint8_t* ptrdata; + ptrdata = (uint8_t*) data; + for (i = 0; i < length; i++) + { + serial_putc(*ptrdata); + ptrdata++; + } + return (i); +} + +//Get data from comm. device +uint32_t serial_getdata(void* data, uint32_t length) +{ + uint8_t* ptrdata; + ptrdata = (uint8_t*) data; + *ptrdata = serial_getc(); + return (1); +} + +static const uint16_t crc16Table[256]= +{ + 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, + 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, + 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, + 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, + 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, + 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, + 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, + 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, + 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, + 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, + 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, + 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, + 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, + 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, + 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, + 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, + 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, + 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, + 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, + 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, + 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, + 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, + 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, + 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, + 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, + 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, + 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, + 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, + 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, + 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, + 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, + 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 +}; + +//*---------------------------------------------------------------------------- +//* \brief Compute the CRC +//*---------------------------------------------------------------------------- +unsigned short serial_add_crc(char ptr, unsigned short crc) +{ + return (crc << 8) ^ crc16Table[((crc >> 8) ^ ptr) & 0xff]; +} + +//*---------------------------------------------------------------------------- +//* \brief +//*---------------------------------------------------------------------------- +static uint16_t getbytes(uint8_t *ptr_data, uint16_t length) +{ + uint16_t crc = 0; + uint16_t cpt; + uint8_t c; + + for (cpt = 0; cpt < length; ++cpt) + { + c = serial_getc(); + if (error_timeout) + return 1; + crc = serial_add_crc(c, crc); + //crc = (crc << 8) ^ xcrc16tab[(crc>>8) ^ c]; + if (size_of_data || mode_of_transfer) + { + *ptr_data++ = c; + if (length == PKTLEN_128) + size_of_data--; + } + } + + return crc; +} + +//*---------------------------------------------------------------------------- +//* \brief Used by Xup to send packets. +//*---------------------------------------------------------------------------- +static int putPacket(uint8_t *tmppkt, uint8_t sno) +{ + uint32_t i; + uint16_t chksm; + uint8_t data; + + chksm = 0; + + serial_putc(SOH); + + serial_putc(sno); + serial_putc((uint8_t) ~(sno)); + + for (i = 0; i < PKTLEN_128; i++) + { + if (size_of_data || mode_of_transfer) + { + data = *tmppkt++; + size_of_data--; + } + else + data = 0x00; + + serial_putc(data); + + //chksm = (chksm<<8) ^ xcrc16tab[(chksm>>8)^data]; + chksm = serial_add_crc(data, chksm); + } + + /* An "endian independent way to extract the CRC bytes. */ + serial_putc((uint8_t) (chksm >> 8)); + serial_putc((uint8_t) chksm); + + return (serial_getc()); /* Wait for ack */ +} + +//*---------------------------------------------------------------------------- +//* \brief Called when a transfer from target to host is being made (considered +//* an upload). +//*---------------------------------------------------------------------------- +//Send given data (polling) using xmodem (if necessary) +uint32_t serial_putdata_xmd(void const* data, uint32_t length) +{ + uint8_t c, sno = 1; + uint8_t done; + uint8_t * ptr_data = (uint8_t *) data; + error_timeout = 0; + if (!length) + mode_of_transfer = 1; + else + { + size_of_data = length; + mode_of_transfer = 0; + } + + if (length & (PKTLEN_128 - 1)) + { + length += PKTLEN_128; + length &= ~(PKTLEN_128 - 1); + } + + /* Startup synchronization... */ + /* Wait to receive a NAK or 'C' from receiver. */ + done = 0; + while (!done) { + c = (uint8_t) serial_getc(); + if (error_timeout) + { // Test for timeout in serial_getc + error_timeout = 0; + c = (uint8_t) serial_getc(); + if (error_timeout) + { + error_timeout = 0; + return (0); + } + } + switch (c) + { + case NAK: + done = 1; + // ("CSM"); + break; + case 'C': + done = 1; + // ("CRC"); + break; + case 'q': /* ELS addition, not part of XMODEM spec. */ + return (0); + default: + break; + } + } + + done = 0; + sno = 1; + while (!done) + { + c = (uint8_t) putPacket((uint8_t *) ptr_data, sno); + if (error_timeout) + { // Test for timeout in serial_getc + error_timeout = 0; + return (0); + } + switch (c) + { + case ACK: + ++sno; + length -= PKTLEN_128; + ptr_data += PKTLEN_128; + // ("A"); + break; + + case NAK: + // ("N"); + break; + + case CAN: + case EOT: + default: + done = 0; + break; + } + + if (!length) + { + serial_putc(EOT); + serial_getc(); /* Flush the ACK */ + break; + } + // ("!"); + } + + mode_of_transfer = 0; + // ("Xup_done."); + return (1); + // return(0); +} + +/*---------------------------------------------------------------------------- + * \brief Used by serial_getdata_xmd to retrieve packets. + */ +static uint8_t getPacket(uint8_t *ptr_data, uint8_t sno) +{ + uint8_t seq[2]; + uint16_t crc, xcrc; + + getbytes(seq, 2); + xcrc = getbytes(ptr_data, PKTLEN_128); + if (error_timeout) + return (false); + + /* An "endian independent way to combine the CRC bytes. */ + crc = (uint16_t) serial_getc() << 8; + crc += (uint16_t) serial_getc(); + + if (error_timeout == 1) + return (false); + + if ((crc != xcrc) || (seq[0] != sno) || (seq[1] != (uint8_t) (~sno))) + { + serial_putc(CAN); + return (false); + } + + serial_putc(ACK); + return (true); +} + +//*---------------------------------------------------------------------------- +//* \brief Called when a transfer from host to target is being made (considered +//* an download). +//*---------------------------------------------------------------------------- +//Get data from comm. device using xmodem (if necessary) +uint32_t serial_getdata_xmd(void* data, uint32_t length) +{ + uint32_t timeout; + char c; + uint8_t * ptr_data = (uint8_t *) data; + uint32_t b_run, nbr_of_timeout = 100; + uint8_t sno = 0x01; + uint32_t data_transfered = 0; + + //Copied from legacy source code ... might need some tweaking + uint32_t loops_per_second = CPU_FREQUENCY/60; + + error_timeout = 0; + + if (length == 0) + mode_of_transfer = 1; + else + { + size_of_data = length; + mode_of_transfer = 0; + } + + /* Startup synchronization... */ + /* Continuously send NAK or 'C' until sender responds. */ + // ("Xdown"); + while (1) + { + serial_putc('C'); + timeout = loops_per_second; + while (!(serial_is_rx_ready()) && timeout) + timeout--; + if (timeout) + break; + + if (!(--nbr_of_timeout)) + return (0); +// return -1; + } + + b_run = true; + // ("Got response"); + while (b_run != false) + { + c = (char) serial_getc(); + if (error_timeout) + { // Test for timeout in serial_getc + error_timeout = 0; + return (0); +// return (-1); + } + switch (c) + { + case SOH: /* 128-byte incoming packet */ + // ("O"); + b_run = getPacket(ptr_data, sno); + if (error_timeout) + { // Test for timeout in serial_getc + error_timeout = 0; + return (0); + // return (-1); + } + if (b_run == true) + { + ++sno; + ptr_data += PKTLEN_128; + data_transfered += PKTLEN_128; + } + break; + case EOT: // ("E"); + serial_putc(ACK); + b_run = false; + break; + case CAN: // ("C"); + case ESC: /* "X" User-invoked abort */ + default: + b_run = false; + break; + } + // ("!"); + } + mode_of_transfer = 0; + return (true); +// return(b_run); +} + diff --git a/bootloaders/feather/sam_ba_serial.h b/bootloaders/feather/sam_ba_serial.h new file mode 100644 index 000000000..cb69f459e --- /dev/null +++ b/bootloaders/feather/sam_ba_serial.h @@ -0,0 +1,143 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _SAM_BA_SERIAL_H_ +#define _SAM_BA_SERIAL_H_ + +#include +#include + + +/* USART buffer size (must be a power of two) */ +#define USART_BUFFER_SIZE (128) + +/* Define the default time-out value for USART. */ +#define USART_DEFAULT_TIMEOUT (1000) + +/* Xmodem related defines */ +/* CRC16 polynomial */ +#define CRC16POLY (0x1021) + +#define SHARP_CHARACTER '#' + +/* X/Ymodem protocol: */ +#define SOH (0x01) +//#define STX (0x02) +#define EOT (0x04) +#define ACK (0x06) +#define NAK (0x15) +#define CAN (0x18) +#define ESC (0x1b) + +#define PKTLEN_128 (128) + + +/** + * \brief Open the given USART + */ +void serial_open(void); + +/** + * \brief Stops the USART + */ +void serial_close(void); + +/** + * \brief Puts a byte on usart line + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int serial_putc(int value); + +/** + * \brief Waits and gets a value on usart line + * + * \return value read on usart line + */ +int serial_getc(void); + +/** + * \brief Returns true if the SAM-BA Uart received the sharp char + * + * \return Returns true if the SAM-BA Uart received the sharp char + */ +int serial_sharp_received(void); + +/** + * \brief This function checks if a character has been received on the usart line + * + * \return \c 1 if a byte is ready to be read. + */ +bool serial_is_rx_ready(void); + +/** + * \brief Gets a value on usart line + * + * \return value read on usart line + */ +int serial_readc(void); + +/** + * \brief Send buffer on usart line + * + * \param data pointer + * \param number of data to send + * \return number of data sent + */ +uint32_t serial_putdata(void const* data, uint32_t length); //Send given data (polling) + +/** + * \brief Gets data from usart line + * + * \param data pointer + * \param number of data to get + * \return value read on usart line + */ +uint32_t serial_getdata(void* data, uint32_t length); //Get data from comm. device + +/** + * \brief Send buffer on usart line using Xmodem protocol + * + * \param data pointer + * \param number of data to send + * \return number of data sent + */ +uint32_t serial_putdata_xmd(void const* data, uint32_t length); //Send given data (polling) using xmodem (if necessary) + +/** + * \brief Gets data from usart line using Xmodem protocol + * + * \param data pointer + * \param number of data to get + * \return value read on usart line + */ +uint32_t serial_getdata_xmd(void* data, uint32_t length); //Get data from comm. device using xmodem (if necessary) + +/** + * \brief Compute the CRC + * + * \param Char to add to CRC + * \param Previous CRC + * \return The new computed CRC + */ +unsigned short serial_add_crc(char c, unsigned short crc); + +#endif // _SAM_BA_SERIAL_H_ diff --git a/bootloaders/feather/sam_ba_usb.c b/bootloaders/feather/sam_ba_usb.c new file mode 100644 index 000000000..71caa4ba4 --- /dev/null +++ b/bootloaders/feather/sam_ba_usb.c @@ -0,0 +1,488 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include +#include "sam_ba_usb.h" +#include "board_driver_usb.h" +#include "sam_ba_cdc.h" + +/* This data array will be copied into SRAM as its length is inferior to 64 bytes, + * and so can stay in flash. + */ +static __attribute__((__aligned__(4))) +const char devDescriptor[] = +{ + /* Device descriptor */ + 0x12, // bLength + 0x01, // bDescriptorType + 0x00, // bcdUSB L + 0x02, // bcdUSB H + 0x02, // bDeviceClass: CDC class code + 0x00, // bDeviceSubclass: CDC class sub code + 0x00, // bDeviceProtocol: CDC Device protocol + 0x40, // bMaxPacketSize0 + USB_VID_LOW, // idVendor L + USB_VID_HIGH, // idVendor H + USB_PID_LOW, // idProduct L + USB_PID_HIGH, // idProduct H + 0x00, // bcdDevice L, here matching SAM-BA version + 0x02, // bcdDevice H +#if 0 // TODO: pending validation + STRING_INDEX_MANUFACTURER, // iManufacturer + STRING_INDEX_PRODUCT, // iProduct +#else + 0x00, // iManufacturer + 0x00, // iProduct +#endif // 0 + 0x00, // SerialNumber, should be based on product unique ID + 0x01 // bNumConfigs +}; + +/* This data array will be consumed directly by USB_Write() and must be in SRAM. + * We cannot send data from product internal flash. + */ +static __attribute__((__aligned__(4))) +char cfgDescriptor[] = +{ + /* ============== CONFIGURATION 1 =========== */ + /* Configuration 1 descriptor */ + 0x09, // CbLength + 0x02, // CbDescriptorType + 0x43, // CwTotalLength 2 EP + Control + 0x00, + 0x02, // CbNumInterfaces + 0x01, // CbConfigurationValue + 0x00, // CiConfiguration + 0x80, // CbmAttributes Bus powered without remote wakeup: 0x80, Self powered without remote wakeup: 0xc0 + 0x32, // CMaxPower, report using 100mA, enough for a bootloader + + /* Communication Class Interface Descriptor Requirement */ + 0x09, // bLength + 0x04, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x01, // bNumEndpoints + 0x02, // bInterfaceClass + 0x02, // bInterfaceSubclass + 0x00, // bInterfaceProtocol + 0x00, // iInterface + + /* Header Functional Descriptor */ + 0x05, // bFunction Length + 0x24, // bDescriptor type: CS_INTERFACE + 0x00, // bDescriptor subtype: Header Func Desc + 0x10, // bcdCDC:1.1 + 0x01, + + /* ACM Functional Descriptor */ + 0x04, // bFunctionLength + 0x24, // bDescriptor Type: CS_INTERFACE + 0x02, // bDescriptor Subtype: ACM Func Desc + 0x00, // bmCapabilities + + /* Union Functional Descriptor */ + 0x05, // bFunctionLength + 0x24, // bDescriptorType: CS_INTERFACE + 0x06, // bDescriptor Subtype: Union Func Desc + 0x00, // bMasterInterface: Communication Class Interface + 0x01, // bSlaveInterface0: Data Class Interface + + /* Call Management Functional Descriptor */ + 0x05, // bFunctionLength + 0x24, // bDescriptor Type: CS_INTERFACE + 0x01, // bDescriptor Subtype: Call Management Func Desc + 0x00, // bmCapabilities: D1 + D0 + 0x01, // bDataInterface: Data Class Interface 1 + + /* Endpoint 1 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x83, // bEndpointAddress, Endpoint 03 - IN + 0x03, // bmAttributes INT + 0x08, // wMaxPacketSize + 0x00, + 0xFF, // bInterval + + /* Data Class Interface Descriptor Requirement */ + 0x09, // bLength + 0x04, // bDescriptorType + 0x01, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0x0A, // bInterfaceClass + 0x00, // bInterfaceSubclass + 0x00, // bInterfaceProtocol + 0x00, // iInterface + + /* First alternate setting */ + /* Endpoint 1 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x81, // bEndpointAddress, Endpoint 01 - IN + 0x02, // bmAttributes BULK + USB_EP_IN_SIZE, // wMaxPacketSize + 0x00, + 0x00, // bInterval + + /* Endpoint 2 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x02, // bEndpointAddress, Endpoint 02 - OUT + 0x02, // bmAttributes BULK + USB_EP_OUT_SIZE, // wMaxPacketSize + 0x00, + 0x00 // bInterval +}; + +#ifndef STRING_MANUFACTURER +# define STRING_MANUFACTURER "Arduino LLC" +#endif + +#ifndef STRING_PRODUCT +# define STRING_PRODUCT "Arduino Zero" +#endif + +USB_CDC sam_ba_cdc; + +/*---------------------------------------------------------------------------- + * \brief This function is a callback invoked when a SETUP packet is received + */ +void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) +{ + Usb *pUsb = pCdc->pUsb; + static volatile uint8_t bmRequestType, bRequest, dir; + static volatile uint16_t wValue, wIndex, wLength, wStatus; + + /* Clear the Received Setup flag */ + pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP = true; + + /* Read the USB request parameters */ + bmRequestType = udd_ep_out_cache_buffer[0][0]; + bRequest = udd_ep_out_cache_buffer[0][1]; + wValue = (udd_ep_out_cache_buffer[0][2] & 0xFF); + wValue |= (udd_ep_out_cache_buffer[0][3] << 8); + wIndex = (udd_ep_out_cache_buffer[0][4] & 0xFF); + wIndex |= (udd_ep_out_cache_buffer[0][5] << 8); + wLength = (udd_ep_out_cache_buffer[0][6] & 0xFF); + wLength |= (udd_ep_out_cache_buffer[0][7] << 8); + + /* Clear the Bank 0 ready flag on Control OUT */ + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + + /* Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 */ + switch ((bRequest << 8) | bmRequestType) + { + case STD_GET_DESCRIPTOR: + if (wValue>>8 == STD_GET_DESCRIPTOR_DEVICE) + { + /* Return Device Descriptor */ + USB_Write(pCdc->pUsb, devDescriptor, SAM_BA_MIN(sizeof(devDescriptor), wLength), USB_EP_CTRL); + } + else + { + if (wValue>>8 == STD_GET_DESCRIPTOR_CONFIGURATION) + { + /* Return Configuration Descriptor */ + USB_Write(pCdc->pUsb, cfgDescriptor, SAM_BA_MIN(sizeof(cfgDescriptor), wLength), USB_EP_CTRL); + } + else + { +#if 0 // TODO: pending validation + if (wValue>>8 == STD_GET_DESCRIPTOR_STRING) + { + switch ( wValue & 0xff ) + { + case STRING_INDEX_LANGUAGES: + uint16_t STRING_LANGUAGE[2] = { (STD_GET_DESCRIPTOR_STRING<<8) | 4, 0x0409 }; + + USB_Write(pCdc->pUsb, (const char*)STRING_LANGUAGE, SAM_BA_MIN(sizeof(STRING_LANGUAGE), wLength), USB_EP_CTRL); + break; + + case STRING_INDEX_MANUFACTURER: + USB_SendString(pCdc->pUsb, STRING_MANUFACTURER, strlen(STRING_MANUFACTURER), wLength ); + break; + + case STRING_INDEX_PRODUCT: + USB_SendString(pCdc->pUsb, STRING_PRODUCT, strlen(STRING_PRODUCT), wLength ); + break; + default: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + } + } + else +#endif // 0 + { + /* Stall the request */ + USB_SendStall(pUsb, true); + } + } + } + break; + + case STD_SET_ADDRESS: + /* Send ZLP */ + USB_SendZlp(pUsb); + /* Set device address to the newly received address from host */ + USB_SetAddress(pCdc->pUsb, wValue); + break; + + case STD_SET_CONFIGURATION: + /* Store configuration */ + pCdc->currentConfiguration = (uint8_t)wValue; + + /* Send ZLP */ + USB_SendZlp(pUsb); + + /* Configure the 3 needed endpoints */ + USB_Configure(pUsb); + break; + + case STD_GET_CONFIGURATION: + /* Return current configuration value */ + USB_Write(pCdc->pUsb, (char *) &(pCdc->currentConfiguration), sizeof(pCdc->currentConfiguration), USB_EP_CTRL); + break; + + case STD_GET_STATUS_ZERO: + wStatus = 0; + USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); + break; + + case STD_GET_STATUS_INTERFACE: + wStatus = 0; + USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); + break; + + case STD_GET_STATUS_ENDPOINT: + wStatus = 0; + dir = wIndex & 80; + wIndex &= 0x0F; + if (wIndex <= 3) + { + if (dir) + { +#ifdef __SAMR21G18A__ + wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) ? 1 : 0; +#else + wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<1)) ? 1 : 0; +#endif + } + else + { +#ifdef __SAMR21G18A__ + wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) ? 1 : 0; +#else + wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<0)) ? 1 : 0; +#endif + } + /* Return current status of endpoint */ + USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); + } + else + { + /* Stall the request */ + USB_SendStall(pUsb, true); + } + break; + + case STD_SET_FEATURE_ZERO: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + + case STD_SET_FEATURE_INTERFACE: + /* Send ZLP */ + USB_SendZlp(pUsb); + break; + + case STD_SET_FEATURE_ENDPOINT: + dir = wIndex & 0x80; + wIndex &= 0x0F; + if ((wValue == 0) && wIndex && (wIndex <= 3)) + { + /* Set STALL request for the endpoint */ + if (dir) + { +#ifdef __SAMR21G18A__ + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; +#else + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.bit.STALLRQ = (1<<1); +#endif + } + else + { +#ifdef __SAMR21G18A__ + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; +#else + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.bit.STALLRQ = (1<<0); +#endif + } + + /* Send ZLP */ + USB_SendZlp(pUsb); + } + else + { + /* Stall the request */ + USB_SendStall(pUsb, true); + } + break; + + case STD_SET_INTERFACE: + case STD_CLEAR_FEATURE_ZERO: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + + case STD_CLEAR_FEATURE_INTERFACE: + /* Send ZLP */ + USB_SendZlp(pUsb); + break; + + case STD_CLEAR_FEATURE_ENDPOINT: + dir = wIndex & 0x80; + wIndex &= 0x0F; + + if ((wValue == 0) && wIndex && (wIndex <= 3)) + { + if (dir) + { +#ifdef __SAMR21G18A__ + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ1) + { + // Remove stall request + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL1) + { + pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL1 = 1; +#else + + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<1)) + { + // Remove stall request + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.bit.STALLRQ = (1<<1); + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL & (1<<1)) + { + pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL = (1<<1); +#endif + // The Stall has occurred, then reset data toggle + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN; + } + } + } + else + { +#ifdef __SAMR21G18A__ + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ0) + { + // Remove stall request + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL0) + { + pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL0 = 1; +#else + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<0)) + { + // Remove stall request + //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.bit.STALLRQ = (1<<0); + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL & (1<<0)) + { + pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL = (1<<0); +#endif + // The Stall has occurred, then reset data toggle + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT; + } + } + } + /* Send ZLP */ + USB_SendZlp(pUsb); + } + else + { + USB_SendStall(pUsb, true); + } + break; + + // handle CDC class requests + case SET_LINE_CODING: + /* Send ZLP */ + USB_SendZlp(pUsb); + break; + + case GET_LINE_CODING: + /* Send current line coding */ + USB_Write(pCdc->pUsb, (char *) &line_coding, SAM_BA_MIN(sizeof(usb_cdc_line_coding_t), wLength), USB_EP_CTRL); + break; + + case SET_CONTROL_LINE_STATE: + /* Store the current connection */ + pCdc->currentConnection = wValue; + /* Send ZLP */ + USB_SendZlp(pUsb); + break; + + default: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + } +} + +/*---------------------------------------------------------------------------- + * \brief + */ +P_USB_CDC usb_init(void) +{ + sam_ba_cdc.pUsb = USB; + + /* Initialize USB */ + USB_Init(); + /* Get the default CDC structure settings */ + USB_Open(&sam_ba_cdc, sam_ba_cdc.pUsb); + + return &sam_ba_cdc; +} + +#if 0 // TODO: pending validation +/*---------------------------------------------------------------------------- + * \brief Send a USB descriptor string. + * + * The input string is plain ASCII but is sent out as UTF-16 with the correct 2-byte prefix. + */ +uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t length, uint8_t maxLength) +{ + uint8_t string_descriptor[255]; // Max USB-allowed string length + uint16_t* unicode_string=(uint16_t*)(string_descriptor+2); // point on 3 bytes of descriptor + + int resulting_length = 1; + + for ( ; *ascii_string && (length>=0) && (resulting_length<(maxLength>>1)) ; ascii_string++, length--, resulting_length++ ) + { + *unicode_string++ = (uint16_t)(*ascii_string); + } + + string_descriptor[0] = (resulting_length<<1); + string_descriptor[1] = STD_GET_DESCRIPTOR_STRING; + + return USB_Write(pUsb, (const char*)unicode_string, resulting_length, USB_EP_CTRL); +} +#endif // 0 diff --git a/bootloaders/feather/sam_ba_usb.h b/bootloaders/feather/sam_ba_usb.h new file mode 100644 index 000000000..42c0d608f --- /dev/null +++ b/bootloaders/feather/sam_ba_usb.h @@ -0,0 +1,107 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef CDC_ENUMERATE_H +#define CDC_ENUMERATE_H + +#include +#include + +#define USB_EP_CTRL (0u) +#define USB_EP_OUT (2u) +#define USB_EP_OUT_SIZE (0x40u) +#define USB_EP_IN (1u) +#define USB_EP_IN_SIZE (0x40u) +#define USB_EP_COMM (3u) +#define MAX_EP (4u) + +/* USB standard request code */ +#define STD_GET_STATUS_ZERO (0x0080u) +#define STD_GET_STATUS_INTERFACE (0x0081u) +#define STD_GET_STATUS_ENDPOINT (0x0082u) + +#define STD_CLEAR_FEATURE_ZERO (0x0100u) +#define STD_CLEAR_FEATURE_INTERFACE (0x0101u) +#define STD_CLEAR_FEATURE_ENDPOINT (0x0102u) + +#define STD_SET_FEATURE_ZERO (0x0300u) +#define STD_SET_FEATURE_INTERFACE (0x0301u) +#define STD_SET_FEATURE_ENDPOINT (0x0302u) + +#define STD_SET_ADDRESS (0x0500u) +#define STD_GET_DESCRIPTOR (0x0680u) +#define STD_SET_DESCRIPTOR (0x0700u) +#define STD_GET_CONFIGURATION (0x0880u) +#define STD_SET_CONFIGURATION (0x0900u) +#define STD_GET_INTERFACE (0x0A81u) +#define STD_SET_INTERFACE (0x0B01u) +#define STD_SYNCH_FRAME (0x0C82u) + +#define STD_GET_DESCRIPTOR_DEVICE (1u) +#define STD_GET_DESCRIPTOR_CONFIGURATION (2u) +#define STD_GET_DESCRIPTOR_STRING (3u) +#define STD_GET_DESCRIPTOR_INTERFACE (4u) +#define STD_GET_DESCRIPTOR_ENDPOINT (5u) +#define STD_GET_DESCRIPTOR_DEVICE_QUALIFIER (6u) +#define STD_GET_DESCRIPTOR_OTHER_SPEED_CONFIGURATION (7u) +#define STD_GET_DESCRIPTOR_INTERFACE_POWER1 (8u) + +#define FEATURE_ENDPOINT_HALT (0u) +#define FEATURE_DEVICE_REMOTE_WAKEUP (1u) +#define FEATURE_TEST_MODE (2u) + +#if 0 // TODO: pending validation +#define STRING_INDEX_LANGUAGES (0x00u) +#define STRING_INDEX_MANUFACTURER (0x01u) +#define STRING_INDEX_PRODUCT (0x02u) +#endif // 0 + +#define SAM_BA_MIN(a, b) (((a) < (b)) ? (a) : (b)) + + +typedef struct _USB_CDC +{ + // Private members + Usb *pUsb; + uint8_t currentConfiguration; + uint8_t currentConnection; + // Public Methods: + uint8_t (*IsConfigured)(struct _USB_CDC *pCdc); +// uint32_t (*Write) (Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num); +// uint32_t (*Read) (Usb *pUsb, char *pData, uint32_t length); +} USB_CDC, *P_USB_CDC; + +/** + * \brief Initializes the USB module + * + * \return Pointer to the USB CDC structure + */ +P_USB_CDC usb_init(void); + +void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc); + +#if 0 // TODO: pending validation +uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t length, uint8_t maxLength); +#endif // 0 + +extern USB_CDC sam_ba_cdc; + + + +#endif // CDC_ENUMERATE_H diff --git a/bootloaders/feather/samd21_sam_ba.atsln b/bootloaders/feather/samd21_sam_ba.atsln new file mode 100644 index 000000000..cf1043181 --- /dev/null +++ b/bootloaders/feather/samd21_sam_ba.atsln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "samd21_sam_ba", "samd21_sam_ba.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Release|ARM = Release|ARM + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.ActiveCfg = Debug|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.Build.0 = Debug|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.ActiveCfg = Release|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.Build.0 = Release|ARM + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/bootloaders/feather/samd21_sam_ba.bin b/bootloaders/feather/samd21_sam_ba.bin new file mode 100644 index 000000000..331adde78 Binary files /dev/null and b/bootloaders/feather/samd21_sam_ba.bin differ diff --git a/bootloaders/feather/samd21_sam_ba.cproj b/bootloaders/feather/samd21_sam_ba.cproj new file mode 100644 index 000000000..70ee7e93a --- /dev/null +++ b/bootloaders/feather/samd21_sam_ba.cproj @@ -0,0 +1,218 @@ + + + + 2.0 + 7.0 + com.Atmel.ARMGCC.C + dce6c7e3-ee26-4d79-826b-08594b9ad897 + ATSAMD21G18A + none + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + samd21_sam_ba + samd21_sam_ba + samd21_sam_ba + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + + + + + + + + + + + + + + com.atmel.avrdbg.tool.atmelice + J41800001895 + 0x10010000 + SWD + + + + 2000000 + + SWD + + com.atmel.avrdbg.tool.atmelice + J41800001895 + Atmel-ICE + + 2000000 + + + + + SWD + + com.atmel.avrdbg.tool.edbg + ATML2320040200000259 + EDBG + + + + + + True + True + True + True + True + + + NDEBUG + + + Optimize for size (-Os) + True + True + + + libm + + + True + -Tsamd21j18a_flash.ld + + + + + + + True + True + True + True + True + + + DEBUG + + + Optimize (-O1) + True + Maximum (-g3) + True + + + libm + + + True + -Tsamd21j18a_flash.ld + Default (-g) + Default (-Wa,-g) + + + True + + DEBUG=1 all + clean + Makefile + + + + compile + board_definitions.h + + + compile + board_driver_led.c + + + compile + board_driver_led.h + + + compile + board_driver_serial.c + + + compile + board_driver_serial.h + + + compile + board_driver_usb.c + + + compile + board_driver_usb.h + + + compile + board_init.c + + + compile + board_startup.c + + + compile + main.c + + + compile + sam_ba_cdc.c + + + compile + sam_ba_cdc.h + + + compile + sam_ba_monitor.c + + + compile + sam_ba_monitor.h + + + compile + sam_ba_serial.c + + + compile + sam_ba_serial.h + + + compile + sam_ba_usb.c + + + compile + sam_ba_usb.h + + + + + compile + Makefile + + + compile + README.md + + + compile + bootloader_samd21x18.ld + + + + \ No newline at end of file diff --git a/bootloaders/feather/samd21_sam_ba.elf b/bootloaders/feather/samd21_sam_ba.elf new file mode 100644 index 000000000..edee94811 Binary files /dev/null and b/bootloaders/feather/samd21_sam_ba.elf differ diff --git a/bootloaders/feather/samd21_sam_ba.hex b/bootloaders/feather/samd21_sam_ba.hex new file mode 100644 index 000000000..5ae649d9d --- /dev/null +++ b/bootloaders/feather/samd21_sam_ba.hex @@ -0,0 +1,386 @@ +:10000000FC7F0020E9050000D5050000D9050000AF +:1000100000000000000000000000000000000000E0 +:10002000000000000000000000000000DD050000EE +:100030000000000000000000E1050000E5050000F0 +:1000400010B5064C2378002B07D1054B002B02D0AE +:10005000044800E000BF0123237010BD5C000020B5 +:10006000000000009817000008B5084B002B03D0D3 +:100070000748084900E000BF07480368002B03D089 +:10008000064B002B00D0984708BDC046000000007A +:1000900098170000600000205800002000000000B9 +:1000A00010B5C3699C07FCD403680224A343036012 +:1000B000C46901231C42FBD1046823430360036825 +:1000C000DC07FCD4C46901231C42FBD1C469DC40B9 +:1000D0001C42F7D1084B1A430260C3695A07FCD48B +:1000E000C0239B0243608181C3699C07FCD40368E1 +:1000F00002221343036010BD04000040037EDA07B0 +:10010000FCD5018570470000027E01235107FBD515 +:10011000428B1A4207D1428BDA401A4203D1428BFA +:1001200092081A4202D0034B01221A70008DC0B20D +:100130007047C0467800002070B50368041C988B97 +:100140001A1C0821FF32084228D0988B174D014312 +:10015000802099839872112353704021144B917120 +:1001600050715E68C0202E40800506435E605E6967 +:100170003540284358610F4818600F4818615D6882 +:100180000E4828408025AD02284358605868800BEF +:100190008003586000235171237105E0137ADA0659 +:1001A00002D5201C00F0EEFA207970BDFFFFFF8F12 +:1001B000940100209400002014010020FF3F00F073 +:1001C000002303714371044B016083600B780222AA +:1001D00013430B707047C0463901000038B5364BE9 +:1001E0002021DA6901200A43DA61344B06241A78A7 +:1001F00002431A70324B0F22197891431970197803 +:10020000214319702F490C782043087019780A404F +:100210001A701A7860210A431A702B4B2B4A5A80A5 +:100220005A7852B2002AFBDB294B01211A780A4383 +:100230001A709A78D107FCD426480268510B1F2205 +:100240001140914200D1052111408C011D8D2249A0 +:100250002940214319850468A10C0A401F2A00D1B6 +:100260001D221C8D1F210A408C4322431A850268DF +:100270000721D20D0A408A4200D103220A40188D7C +:100280001103164A02400A431A8519787F220A4050 +:100290001A701A78042112480A431A7058621A898F +:1002A0000C218A431A811A8901218A431A8100216B +:1002B000802201F006F938BD000400405844004196 +:1002C0003C44004159440041000C004006400000FD +:1002D00000500041246080003FF8FFFFFF8FFFFFC8 +:1002E00094010020F7B5141C234A5F0101971D1CDF +:1002F000D319061C5869271C4000400F03301033E7 +:10030000C74006D00F1C8022596812060A435A6063 +:1003100009E02F1C7B1E9F41184BBF01FF18381CA2 +:10032000221C01F0C5F801991348083542181761DD +:10033000131C5269A104920B890C92030A435A615F +:1003400059690F4A02200A405A616B01F318D979A2 +:10035000032211400143D8799043021C0A43DA7109 +:100360005979802252420A435A716B01F318DB79A2 +:100370009A07FAD5201CFEBD94010020140100202C +:10038000FF3F00F0F8B51E4E041C3378151C002BFF +:1003900012D11C4B1C4A1A645A6C920B92035A6479 +:1003A000586C1A4A02405A64A2235B00E25C402067 +:1003B0000243E254012333704827FF37E25D0123F3 +:1003C00013401AD00F4B5A6C9204920CAA4202D2DC +:1003D0005D6CAD04AD0C081C2A1C0B4901F068F8DB +:1003E000E25D03231A4001210A43E15D99430B1C9E +:1003F0001343E3550023337000E01D1C281CF8BD97 +:100400007900002094010020D4000020FF3F00F07C +:10041000FF30827930239A43131C2022002900D117 +:1004200010221343837170470C4BFF305A6902212D +:10043000920B92035A61027A03231A400A43017A0B +:1004400099430B1C13430372827980235B4213434D +:100450008371037A9A07FCD57047C0469401002047 +:1004600080235B421943C9B28172704770B5A023E3 +:1004700003225B00C254134B134A5C6CC02114402E +:1004800089050C4346255C64FF35402444550F4DD7 +:1004900030261D6490256D0046555D6B154029433F +:1004A000922559636D0080214155094D1D63B0258A +:1004B0006D0044555C6F22405A67B2235B00C15403 +:1004C00070BDC04694010020FFFFFF8FD4000020C4 +:1004D0005401002030B5364A1E2351680820994344 +:1004E00002231943516033498A6902438A613248C1 +:1004F000324A9082908A03439382D3689807FCD54E +:100500002F4B012018701878C40704D52C48407868 +:1005100040B20028F7DB01209860587840B20028EC +:10052000FBDB284C26484460587840B20028FBDBAF +:1005300082242348E4014480587840B20028FBDB41 +:10054000908C8024A0439084D068C506FCD51E4CB6 +:100550001A48C462D4681948E506FBD5848C1B4D43 +:100560002C438484D4681548E506FBD5848C022589 +:100570002C438484D0680406FCD51048C068450626 +:10058000F8D5D068C406FCD500229A605A7852B2D9 +:10059000002AFBDB0E480A4A50605A7852B2002A01 +:1005A000FBDB00230B724B728B72CB7230BDC046EB +:1005B00000400041000400400C060000000800401C +:1005C000000C004001050100B805FF7D040A000091 +:1005D000000703000EBEFEE70DBEFEE705BEFEE708 +:1005E00002BEFEE701BEFEE70E4A0F4838B5824262 +:1005F00004D10E4A0E4B93420ED10AE00D4C9442A8 +:10060000F7D00023D1188842F3D9E55804330D60A0 +:10061000F8E700F04DF804E09342FAD2002102C35B +:10062000FAE7FEE7000000205C000020A0030020A5 +:100630005C0000209C170000194A10B51188FA24AC +:10064000013189B2174BA400A14201D011801CE0F6 +:1006500000211180144900240C5760431C880019A4 +:1006600080B204B2FF2C01DC188002E0FF20188069 +:1006700008700024185F002803DA00201880012089 +:1006800008708020094980028861128800215B5E21 +:100690009A4203D18022054B92025A6110BDC04696 +:1006A0007A0000207C00002000000020004400416F +:1006B00038B580222B4B92029A605A612A4A1C1C40 +:1006C000117801221140294B002200290AD1186813 +:1006D000274A904201D1196018E01A60254A013A70 +:1006E000002AFCD11A60244B1A68191C501C0DD02A +:1006F000D8B200280AD180208002A06182F3088845 +:10070000FF2293431D4A93604B681847FFF7E2FEB0 +:1007100062B600F0FBFC00F0CFF980239B02051CC1 +:10072000A3610320FFF788FFAB68281C9847144B90 +:10073000002801D001221A701A78002A05D0002062 +:1007400000F036FA00F092FAFCE71B78002BE8D1B3 +:1007500000F050FD0028E4D0012000F029FA00F05C +:1007600085FAFCE70044004138040040FC7F00208B +:100770003581730748E801000020000000ED00E02B +:100780007E000020F8B50468051C201CFF30037AA9 +:10079000B64A10210B430372B54F1378B5493B702D +:1007A0005378B54E0B7093783380D1783388090233 +:1007B0000B4333801179B14B198051791F8809029D +:1007C0000F431F809779AE490F80D2790F881202AC +:1007D0003A430A8040224271A648A54F02783878F1 +:1007E000A84F12020243181CBA4200D199E01EDC45 +:1007F000802149008A4200D158E107DC812A6AD071 +:10080000822A6ED0802A00D050E164E081235B0010 +:100810009A4200D1AFE000DA23E1C0239B009A4264 +:1008200000D143E1984B9A4200D11AE13EE1902376 +:100830001B019A4242D015DCD023DB009A4222D021 +:1008400088231B019A4242D0A023DB009A4200D0A9 +:100850002CE1201CFFF7E8FD3188286889B2FFF7FA +:10086000FFFD27E1894B9A4200D1FAE000DC1DE14F +:10087000874B9A4200D1E8E0864B9A4200D015E1BE +:1008800033886B71EDE033881B0A012B08D10B888C +:1008900012222868934201D80A8892B27E49DCE08D +:1008A00033881B0A022B00D000E10B884322286802 +:1008B000934201D80A8892B27849CEE03388201C4E +:1008C0002B71FFF7B1FD201CFFF7D0FDF2E0291CD2 +:1008D00001C90122C1E0724900230B80286802226D +:1008E000BCE06F4900220A801888502210406D4AEF +:1008F00010701E880F20304018801888032800D9F7 +:10090000D4E012781B8808335B01E418A379002A2D +:1009100001D09B0600E0DB06DB0F0B80286802227B +:100920009BE019887F2291435E4AC9B211701888F2 +:100930000F21014019803188002900D0B6E01988C4 +:10094000002900D1B2E01988032900D9AEE012785D +:100950001B8808335B01E318002A05D05A7930213F +:100960008A4320210A4304E05A7930218A43102027 +:1009700002435A7175E002887F239A43494BD2B2F1 +:100980001A7001880F220A4002803288002A00D0A3 +:100990008CE00288002A00D188E00288032A00D96E +:1009A00084E01B78002B27D0038808335B01E31811 +:1009B0009B79990655D50388302108335B01E318EC +:1009C0001A798A4320210A431A71038808335B018C +:1009D000E318DB795A0644D50388602108335B01AC +:1009E000E318DA798A4340210A43DA710388022244 +:1009F00008335B01E31826E0038808335B01E31842 +:100A00009B79DF062DD50388302108335B01E3187D +:100A10001A798A4310210A431A71038808335B014B +:100A2000E318DB7999061CD50388602108335B0144 +:100A3000E318DA798A4320210A43DA710388012214 +:100A400008335B01E3181A710BE00B880822286851 +:100A5000934201D80A8892B213490023FFF742FC5F +:100A600028E0201CFFF7E0FC24E0C04694000020B2 +:100A7000890000207F0000208000002084000020EA +:100A80008600002002030000010300002120000076 +:100A9000A121000021220000EC140000040000202D +:100AA000820000208800002048000020201C012136 +:100AB000FFF7AEFCF8BDC04610B5054B054C2360F2 +:100AC000FFF78CFB201C2168FFF77AFB201C10BD70 +:100AD000005000411402002007B5054B012201908F +:100AE00001A91868131CFFF7FDFB01200EBDC046CD +:100AF0001402002013B5054B6C4607341868211CFE +:100B00000122FFF73FFC207816BDC04614020020EA +:100B100010B5074C201CFFF70FFB031C002083427D +:100B200005D022684823FF33D05C0123184010BD54 +:100B30001402002010B5054A0C1C031C191C106877 +:100B40000123221CFFF7CEFB201C10BD1402002045 +:100B500070B5084C061C201C0D1CFFF7EDFA002395 +:100B6000984205D02068311C2A1CFFF70BFC031C9F +:100B7000181C70BD14020020F8B50C4C051C201C7C +:100B80000E1CFFF7D9FA0023271C341C98420AD008 +:100B9000002C07D0291C221C3868FFF7F3FB241A0D +:100BA0002D18F5E7331C181CF8BDC04614020020B0 +:100BB000012805D1054B064A1A60064B187004E05F +:100BC000002802D1044A014B1A60704784020020B9 +:100BD00020150000910000206C15000030B51A4B64 +:100BE00085B01B78002B29D0042901D1026804E0CC +:100BF000022901D1028800E00278490004A84318C4 +:100C00000B3B5C1AA3420BD00F201040092802D8DE +:100C10003025284300E0373018701209013BF1E716 +:100C200001A830230370782343700A2243189A7076 +:100C30000D22DA70054B04311B6801E0034B1B6881 +:100C4000DB68984705B030BD90000020840200208A +:100C500072B6EFF30883044A1360036883F30888CD +:100C6000436818477047C04688020020F0B58FB02F +:100C700006A9CE4A0B1C31CA31C351CA51C360CA3E +:100C800060C3CB4CCB48A3687A255B035B0F9B000A +:100C90005B58C9490360A26892B253430A60C749CE +:100CA000C74A0B6000231360C64B1D700320FFF77B +:100CB000C3FCC54BC54D1B68281C1B6940219847C8 +:100CC000C34B00221860C34B1D60C34BC24DC04FC5 +:100CD0001A60286839688842E8D2BE4B1B681A78C7 +:100CE000FF2A00D1F6E1232A00D0CDE1BB4E3378B4 +:100CF000002B05D0B44BBA481B680221DB6898472B +:100D0000B04B1B78532B38D13B682A6893421ED9CD +:100D1000B04801322A609A1AB24B01681B6801314F +:100D20000160B14E9A4201D2326000E03360A448C3 +:100D300032680068029000F0BBFB336829685A18DB +:100D40002A60A44A1668F1181160A84A13702B682B +:100D5000013B2B609F4B1A68013A1A60A34BA14AD2 +:100D60001B7811688B4206D2974A95481268006832 +:100D7000C91A92699047C04675E1522B07D1904A33 +:100D8000914B10681B68974A5B6911686AE14F2BA9 +:100D900005D18B4B934A1B6812681A7063E1482B8C +:100DA00005D1874B8F4A1B6812681A805BE1572B6D +:100DB00005D1834B8B4A1B6812681A6053E16F2B75 +:100DC00003D17F4B0121186807E0682B08D17C4BC9 +:100DD00084481B6802211B880360FFF7FFFE42E185 +:100DE000772B06D1764B7F481B6804211B68036074 +:100DF000F3E7472B13D17B4B1868FFF729FF7C4B98 +:100E00001B6883F3088862B67A4B1B78002B00D1ED +:100E100029E16D4B06201B681B68984723E1542B82 +:100E200004D101233370684B1B685CE04E2B0BD15F +:100E30003378002B05D1644B69481B680221DB68BD +:100E40009847002333700EE1562B50D15E4D01219F +:100E50002B686948DB6898472B680321DB68674883 +:100E60009847674E2B68301CDB68012198472B6838 +:100E70000D21DB68634898472B68301CDB68012133 +:100E80009847544F604B544E3B60002333603A1CEC +:100E9000311C1368581C10601B780393002B03D07F +:100EA0000B6801330B60F4E72B683168DB68564848 +:100EB00098472B685248DB680121984703983060B7 +:100EC00052483860434A1368591C11601A78424BE3 +:100ED000002A03D01A6801321A60F3E72A681968F9 +:100EE000D36898472B68DB683D480221BAE03D4A49 +:100EF000582B15D12F4E314D366813682A68B10032 +:100F0000934208D25808E06141482080207DC507FF +:100F1000FCD55B18F4E72C4B3E481B68DB68A0E06F +:100F2000592B33D11268264B3B49002A02D11B684A +:100F30000B6026E00868196863688025AB43920857 +:100F40006360002A1DD0354B2380237DDE07FCD54E +:100F50000023184D2D680095AD08AB4202D3304DEB +:100F6000258006E09342FAD09D00465901334E5148 +:100F7000EFE7257DEE07FCD59D0049194019D21AEF +:100F8000DFE7114B27481B68DB686AE05A2B6AD100 +:100F90000B4B17681D680026EF19BD4244D0287816 +:100FA000311C00F049F90135061CF6E70015000078 +:100FB000004000413C0200203402002030020020AA +:100FC000800200202C020020840200204002002029 +:100FD0002402002028020020380200209000002077 +:100FE000601500008C0200209002002020020020EA +:100FF00088020020910000203C15000065150000CB +:101000003E15000088150000401500004C1500003A +:1010100002A5FFFF551500008C00002044A5FFFF2E +:1010200004A5FFFF591500002E4D2F482B68012104 +:10103000DB68984707230F223240111C36093031F4 +:10104000092A00DD07311020C0186A468154013B8F +:10105000F1D22B6804A8DB68082198472B68234845 +:10106000DB6803219847224D7A232B70214B002205 +:101070001A60214B1B7893422CD01A4B01211B681C +:101080001E48DB68984725E0111C3039C8B2194B5F +:10109000092804D81E683201114319601AE0111C96 +:1010A0004139052903D81868373A010106E0111CB7 +:1010B0006139052904D81D68573A29010A4308E017 +:1010C0002C2A03D10E4A1E68166001E008490A70F6 +:1010D00000221A600B4B1A6801321A600A4B1A6818 +:1010E0000132F3E5840200205D1500005F15000069 +:1010F0002C0200208C0200209000002063150000CC +:1011000080020020380200202802002010B51C4B6D +:1011100001201A78022402431A701A4B0F22197800 +:101120009143197019782143197017490C7820439D +:10113000087019780A401A701A7820210A431A7028 +:10114000124B04211A6A0A431A62114B114A5A803F +:101150005A7852B2002AFBDBC4220F480F4992038F +:10116000FEF79EFF0E4A002313700E4A13700E4ABC +:1011700013700E4A13700E4A13700E4A137010BD8E +:101180004A440041354400414B44004100040040C2 +:10119000000C004014400000000800422AF6000045 +:1011A000940200201B0300209502002098020020DA +:1011B0001C0300201903002008B5C1B20248FEF745 +:1011C0009DFF012008BDC04600080042024B187E6A +:1011D0004007C00F7047C0460008004208B5FFF73F +:1011E000F5FF0028FBD00248FEF78EFF08BDC04681 +:1011F0000008004208B5FFF7E9FF0023984205D038 +:10120000FFF7ECFF031C233B5A425341181C08BD57 +:1012100070B5041C0D1C4618B44204D02078FFF7AA +:10122000CBFF0134F8E7281C70BD10B5041CFFF794 +:10123000D5FF2070012010BD0B0A5840034B400021 +:10124000C05A0902484080B27047C0469615000057 +:10125000F7B50024051C0F1C261CBC4220D0FFF74C +:10126000BDFF114BC0B21B780190002B1AD1311C6D +:10127000FFF7E2FF0D4B061C1A88002A04D10C4A26 +:1012800011782A1C002907D001996A1C2970802F27 +:1012900002D11988013919800134A4B2151CDCE788 +:1012A000301C00E00120FEBD190300209602002042 +:1012B0001A030020F0B53E4E85B0002203900C1CAE +:1012C00032703C4B914201D1012201E03A490C803D +:1012D0001A707F231C4201D080349C43FFF77EFFAD +:1012E0003378C0B2002B07D000253570FFF776FFAA +:1012F0003378C0B2AB4236D1432803D0712853D0E3 +:101300001528EBD1012300930120FFF755FF00982A +:10131000FFF752FF00998025C843C0B2FFF74CFF8A +:10132000039B00270293244A1388002B1DD12149D7 +:1013300001930978002918D10198FFF73DFF391C66 +:101340000198FFF779FF013D071C002DEBD1000A42 +:10135000C0B2FFF731FFF8B2FFF72EFFFFF73EFFF5 +:101360003378002B0AD035701FE00299013B0978D1 +:101370001380029B019101330293DDE7C0B206287E +:1013800007D1009B03990133DBB280310093803C8D +:101390000391002CB8D10420FFF70EFFFFF71EFFCA +:1013A000044B01251C7000E00025281C05B0F0BD91 +:1013B000190300201A03002096020020F0B5384CD3 +:1013C00087B0002301902370994201D1012301E0ED +:1013D000344A1180344A642613704320FFF7ECFE30 +:1013E000324FFFF7F3FE002803D1002F03D0013F57 +:1013F000F7E7002F03D1013E002EEED14DE001258D +:10140000FFF7ECFE2378002B38D1C0B20290012800 +:1014100005D004283DD10620FFF7CEFE39E005AE09 +:101420000221301CFFF714FF01988021FFF710FF05 +:1014300023780390002B18D1FFF7D0FE0702FFF7A7 +:10144000CDFEBFB223783F18BFB2012B0DD0039B56 +:101450009F4207D13378AB4204D1EB437278DBB2C1 +:101460009A4204D01820FFF7A7FE002303E00620CD +:10147000FFF7A2FE029B2278002A02D000262670E7 +:101480000BE0012B05D1019A6B1C8032DDB2019279 +:10149000B6E7054A002313700126301C07B0F0BDE3 +:1014A00019030020960200201A03002000350C00CA +:1014B00010B50023934203D0CC5CC4540133F9E748 +:1014C00010BD031C8218934202D019700133FAE751 +:1014D00070470000F8B5C046F8BC08BC9E4670478F +:1014E000F8B5C046F8BC08BC9E4670471201000221 +:1014F000020000409A230B000002000000010000DF +:101500000800000010000000200000004000000063 +:101510008000000000010000000200000004000044 +:10152000B9110000DD110000CD1100001112000002 +:101530002B120000B5120000BD1300007600200041 +:101540004D617220203520323031360032313A324E +:10155000383A333400580A0D00590A0D005A002356 +:101560000A0D003E00322E3000000000D90A0000B3 +:10157000F50A0000110B0000350B0000510B0000B4 +:10158000350B0000790B00005B41726475696E6F6A +:101590003A58595A5D0000002110422063308440BF +:1015A000A550C660E770088129914AA16BB18CC132 +:1015B000ADD1CEE1EFF13112100273325222B552A9 +:1015C0009442F772D662399318837BB35AA3BDD382 +:1015D0009CC3FFF3DEE36224433420040114E66479 +:1015E000C774A44485546AA54BB528850995EEE5D2 +:1015F000CFF5ACC58DD55336722611163006D77689 +:10160000F6669556B4465BB77AA719973887DFF721 +:10161000FEE79DD7BCC7C448E5588668A778400850 +:10162000611802282338CCC9EDD98EE9AFF9488971 +:1016300069990AA92BB9F55AD44AB77A966A711AE8 +:10164000500A333A122AFDDBDCCBBFFB9EEB799BC1 +:10165000588B3BBB1AABA66C877CE44CC55C222C38 +:10166000033C600C411CAEED8FFDECCDCDDD2AAD11 +:101670000BBD688D499D977EB66ED55EF44E133EC8 +:10168000322E511E700E9FFFBEEFDDDFFCCF1BBF61 +:101690003AAF599F788F8891A981CAB1EBA10CD13B +:1016A0002DC14EF16FE18010A100C230E320045043 +:1016B000254046706760B9839893FBA3DAB33DC3B6 +:1016C0001CD37FE35EF3B1029012F322D232354293 +:1016D000145277625672EAB5CBA5A89589856EF546 +:1016E0004FE52CD50DC5E234C324A01481046674E3 +:1016F000476424540544DBA7FAB79987B8975FE796 +:101700007EF71DC73CD7D326F2369106B016576632 +:101710007676154634564CD96DC90EF92FE9C8991D +:10172000E9898AB9ABA94458654806782768C01882 +:10173000E1088238A3287DCB5CDB3FEB1EFBF98BF5 +:10174000D89BBBAB9ABB754A545A376A167AF10AD2 +:10175000D01AB32A923A2EFD0FED6CDD4DCDAABD05 +:101760008BADE89DC98D267C076C645C454CA23C22 +:10177000832CE01CC10C1FEF3EFF5DCF7CDF9BAFD5 +:10178000BABFD98FF89F176E367E554E745E932E72 +:0C179000B23ED10EF01E00000000000070 +:10179C00010000000902430002010080320904002C +:1017AC0000010202000005240010010424020005BF +:1017BC00240600010524010001070583030800FF2E +:1017CC0009040100020A0000000705810240000024 +:1017DC00070502024000000000C2010000000800E2 +:0C17EC0069000000410000000000000047 +:04000003000005E90B +:00000001FF diff --git a/bootloaders/feather/samr21_sam_ba.bin b/bootloaders/feather/samr21_sam_ba.bin new file mode 100644 index 000000000..aeed6a66d Binary files /dev/null and b/bootloaders/feather/samr21_sam_ba.bin differ diff --git a/bootloaders/feather/samr21_sam_ba.hex b/bootloaders/feather/samr21_sam_ba.hex new file mode 100644 index 000000000..cfead74fb --- /dev/null +++ b/bootloaders/feather/samr21_sam_ba.hex @@ -0,0 +1,380 @@ +:10000000FC7F0020BD050000A9050000AD05000033 +:1000100000000000000000000000000000000000E0 +:10002000000000000000000000000000B10500001A +:100030000000000000000000B5050000B905000048 +:1000400010B5064C2378002B07D1054B002B02D0AE +:10005000044800E000BF0123237010BD5C000020B5 +:10006000000000003C17000008B5084B002B03D02F +:100070000748084900E000BF07480368002B03D089 +:10008000064B002B00D0984708BDC046000000007A +:100090003C17000060000020580000200000000015 +:1000A00010B5C3699C07FCD403680224A343036012 +:1000B000C46901231C42FBD1046823430360036825 +:1000C000DC07FCD4C46901231C42FBD1C469DC40B9 +:1000D0001C42F7D1084B1A430260C3695A07FCD48B +:1000E000C0239B0243608181C3699C07FCD40368E1 +:1000F00002221343036010BD04000040037EDA07B0 +:10010000FCD5018570470000027E01235107FBD515 +:10011000428B1A4207D1428BDA401A4203D1428BFA +:1001200092081A4202D0034B01221A70008DC0B20D +:100130007047C0467800002070B50368041C988B97 +:100140001A1C0821FF32084228D0988B174D014312 +:10015000802099839872112353704021144B917120 +:1001600050715E68C0202E40800506435E605E6967 +:100170003540284358610F4818600F4818615D6882 +:100180000E4828408025AD02284358605868800BEF +:100190008003586000235171237105E0137ADA0659 +:1001A00002D5201C00F0D8FA207970BDFFFFFF8F28 +:1001B000940100209400002014010020FF3F00F073 +:1001C000002303714371044B016083600B780222AA +:1001D00013430B707047C0463901000038B5364BE9 +:1001E0002021DA6901200A43DA61344B06241A78A7 +:1001F00002431A70324B0F22197891431970197803 +:10020000214319702F490C782043087019780A404F +:100210001A701A7860210A431A702B4B2B4A5A80A5 +:100220005A7852B2002AFBDB294B01211A780A4383 +:100230001A709A78D107FCD426480268510B1F2205 +:100240001140914200D1052111408C011D8D2249A0 +:100250002940214319850468A10C0A401F2A00D1B6 +:100260001D221C8D1F210A408C4322431A850268DF +:100270000721D20D0A408A4200D103220A40188D7C +:100280001103164A02400A431A8519787F220A4050 +:100290001A701A78042112480A431A7058621A898F +:1002A0000C218A431A811A8901218A431A8100216B +:1002B000802201F0D8F838BD0004004058440041C5 +:1002C0003C44004159440041000C004006400000FD +:1002D00000500041246080003FF8FFFFFF8FFFFFC8 +:1002E00094010020F7B5141C204A5F0101971D1CE2 +:1002F000D319061C5869271C4000400F03301033E7 +:10030000C74006D00F1C8022596812060A435A6063 +:1003100009E02F1C7B1E9F41154BBF01FF18381CA5 +:10032000221C01F097F8019910480835421817610E +:10033000131C5269A104920B890C92030A435A615F +:1003400059690C4A0A405A616B01F318DA790221A3 +:100350000A43DA715979802252420A435A716B0179 +:10036000F318DB799A07FAD5201CFEBD9401002012 +:1003700014010020FF3F00F0F8B51B4E051C337838 +:10038000141C002B12D1194B194A1A645A6C920B87 +:1003900092035A64586C174A02405A64A2235B00C5 +:1003A000EA5C40200243EA54012333704827FF37B8 +:1003B000EA5D0123134014D00C4B5A6C9204920C4A +:1003C000A24202D25C6CA404A40C081C221C0849A2 +:1003D00001F040F8EB5D01221343EB55002333702D +:1003E00000E01C1C201CF8BD7900002094010020B6 +:1003F000D4000020FF3F00F0FF302023002900D16F +:100400001023837170470000094BFF305A69920B2B +:1004100092035A61037A0222134303728279802382 +:100420005B4213438371037A9A07FCD57047C04639 +:100430009401002080235B421943C9B28172704746 +:1004400070B5A02303225B00C254134B134A5C6CAB +:10045000C021144089050C4346255C64FF354024C7 +:1004600044550F4D30261D6490256D0046555D6B3B +:1004700015402943922559636D0080214155094D4E +:100480001D63B0256D0044555C6F22405A67B2234E +:100490005B00C15470BDC04694010020FFFFFF8F78 +:1004A000D40000205401002030B5364A1E23516884 +:1004B0000820994302231943516033498A69024352 +:1004C0008A613248324A9082908A03439382D36889 +:1004D0009807FCD52F4B012018701878C40704D555 +:1004E0002C48407840B20028F7DB0120986058780B +:1004F00040B20028FBDB284C26484460587840B2C4 +:100500000028FBDB82242348E4014480587840B271 +:100510000028FBDB908C8024A0439084D068C50623 +:10052000FCD51E4C1A48C462D4681948E506FBD5B0 +:10053000848C1B4D2C438484D4681548E506FBD578 +:10054000848C02252C438484D0680406FCD5104892 +:10055000C0684506F8D5D068C406FCD500229A606C +:100560005A7852B2002AFBDB0E480A4A50605A7889 +:1005700052B2002AFBDB00230B724B728B72CB72E0 +:1005800030BDC04600400041000400400C060000A1 +:1005900000080040000C004001050100B805FF7D87 +:1005A000040A0000000703000EBEFEE70DBEFEE7D2 +:1005B00005BEFEE702BEFEE701BEFEE70E4A0F489B +:1005C00038B5824204D10E4A0E4B93420ED10AE056 +:1005D0000D4C9442F7D00023D1188842F3D9E55846 +:1005E00004330D60F8E700F04DF804E09342FAD2CE +:1005F000002102C3FAE7FEE7000000205C000020B3 +:10060000A00300205C00002040170000194A10B52C +:100610001188FA24013189B2174BA400A14201D0FC +:1006200011801CE000211180144900240C57604304 +:100630001C88001980B204B2FF2C01DC188002E093 +:10064000FF20188008700024185F002803DA0020BB +:100650001880012008708020094980028861128872 +:1006600000215B5E9A4203D18022054B92025A61BF +:1006700010BDC0467A0000207C0000200000002051 +:100680000044004138B580222B4B92029A605A6197 +:100690002A4A1C1C117801221140294B00220029F2 +:1006A0000AD11868274A904201D1196018E01A60EF +:1006B000254A013A002AFCD11A60244B1A68191CF9 +:1006C000501C0DD0D8B200280AD180208002A06131 +:1006D00082F30888FF2293431D4A93604B681847B2 +:1006E000FFF7E2FE62B600F0E3FC00F0B7F980230A +:1006F0009B02051CA3610320FFF788FFAB68281C41 +:100700009847144B002801D001221A701A78002A49 +:1007100005D0002000F01EFA00F07AFAFCE71B7802 +:10072000002BE8D100F038FD0028E4D0012000F0D3 +:1007300011FA00F06DFAFCE7004400413804004073 +:10074000FC7F00203581730748E80100002000008D +:1007500000ED00E07E000020F8B50468051C201CB8 +:10076000FF30037AAD4A10210B430372AC4F13786C +:10077000AC493B705378AC4E0B7093783380D17892 +:10078000338809020B4333801179A84B19805179C2 +:100790001F8809020F431F809779A5490F80D279DE +:1007A0000F8812023A430A80402242719D489C4FB2 +:1007B000027838789F4F12020243181CBA4200D1C7 +:1007C00099E01EDC802149008A4200D121E107DC4A +:1007D000812A6AD0822A6ED0802A00D019E164E092 +:1007E00081235B009A4200D1A8E000DA0DE1C0232A +:1007F0009B009A4200D10CE18F4B9A4200D104E158 +:1008000007E190231B019A4242D015DCD023DB0084 +:100810009A4222D088231B019A4242D0A023DB00B7 +:100820009A4200D0F5E0201CFFF7EEFD31882868E1 +:1008300089B2FFF7FFFDF0E0804B9A4200D1E4E07F +:1008400000DCE6E07E4B9A4200D1D2E07D4B9A423A +:1008500000D0DEE033886B71D7E033881B0A012BB0 +:1008600008D10B8812222868934201D80A8892B2D4 +:100870007549C6E033881B0A022B00D0C9E00B88FB +:1008800043222868934201D80A8892B26F49B8E09F +:100890003388201C2B71FFF7B7FD201CFFF7D0FD1C +:1008A000BBE0291C01C90122ABE0694900230B8090 +:1008B00028680222A6E0664900220A801888502291 +:1008C0001040644A10701E880F203040188018882D +:1008D000032800D99DE012781B8808335B01E418D7 +:1008E000A379002A01D09B0600E0DB06DB0F0B801A +:1008F0002868022285E019887F229143554AC9B2AF +:10090000117018880F21014019803188002900D00A +:100910007FE01988002900D17BE01988032900D9DC +:1009200077E012781B8808335B01E318002A02D0B5 +:1009300020225A7169E01020587166E002887F23F6 +:100940009A43444BD2B21A7001880F220A400280A7 +:100950003288002A5DD10288002A5AD00288032AF0 +:1009600057D81B78002B21D0038808335B01E3188C +:100970009B79990649D50388202208335B01E31847 +:100980001A71038808335B01E318DB795A063CD5FA +:100990000388402108335B01E318DA790A43DA71EE +:1009A0000388022208335B01E31820E00388083340 +:1009B0005B01E3189B79DF0627D5038810220833F3 +:1009C0005B01E3181A71038808335B01E318DB79D4 +:1009D00099061AD50388202108335B01E318DA79D8 +:1009E0000A43DA710388012208335B01E3181A71A4 +:1009F0000BE00B8808222868934201D80A8892B23B +:100A000015490023FFF76EFC07E0201CFFF7FCFCF4 +:100A100003E0201C0121FFF7EFFCF8BD940000204B +:100A2000890000207F000020800000208600002038 +:100A300084000020020300000103000021200000C8 +:100A4000A1210000212200009014000004000020D9 +:100A500082000020880000204800002010B5054BCF +:100A6000054C2360FFF7BAFB201C2168FFF7A8FBA9 +:100A7000201C10BD005000411402002007B5054B9A +:100A80000122019001A91868131CFFF72BFC01201B +:100A90000EBDC0461402002013B5054B6C4607344A +:100AA0001868211C0122FFF767FC207816BDC0469C +:100AB0001402002010B5074C201CFFF73DFB031C5F +:100AC0000020834205D022684823FF33D05C0123F5 +:100AD000184010BD1402002010B5054A0C1C031C60 +:100AE000191C10680123221CFFF7FCFB201C10BD01 +:100AF0001402002070B5084C061C201C0D1CFFF7CA +:100B00001BFB0023984205D02068311C2A1CFFF7EC +:100B100033FC031C181C70BD14020020F8B50C4CEB +:100B2000051C201C0E1CFFF707FB0023271C341C90 +:100B300098420AD0002C07D0291C221C3868FFF7E5 +:100B40001BFC241A2D18F5E7331C181CF8BDC046F1 +:100B500014020020012805D1054B064A1A60064BF5 +:100B6000187004E0002802D1044A014B1A60704753 +:100B700084020020C4140000910000201015000021 +:100B800030B51A4B85B01B78002B29D0042901D130 +:100B9000026804E0022901D1028800E002784900DD +:100BA00004A843180B3B5C1AA3420BD00F20104043 +:100BB000092802D83025284300E037301870120980 +:100BC000013BF1E701A830230370782343700A2228 +:100BD00043189A700D22DA70054B04311B6801E04E +:100BE000034B1B68DB68984705B030BD90000020C0 +:100BF0008402002072B6EFF30883044A136003688E +:100C000083F30888436818477047C046880200206D +:100C1000F0B58FB006A9CE4A0B1C31CA31C351CAF8 +:100C200051C360CA60C3CB4CCB48A3687A255B0331 +:100C30005B0F9B005B58C9490360A26892B25343A3 +:100C40000A60C749C74A0B6000231360C64B1D707A +:100C50000320FFF7DBFCC54BC54D1B68281C1B6937 +:100C600040219847C34B00221860C34B1D60C34B03 +:100C7000C24DC04F1A60286839688842E8D2BE4B1E +:100C80001B681A78FF2A00D1F6E1232A00D0CDE1B3 +:100C9000BB4E3378002B05D0B44BBA481B680221F9 +:100CA000DB689847B04B1B78532B38D13B682A68D8 +:100CB00093421ED9B04801322A609A1AB24B016899 +:100CC0001B6801310160B14E9A4201D2326000E0EE +:100CD0003360A44832680068029000F0BBFB3368C0 +:100CE00029685A182A60A44A1668F1181160A84A9F +:100CF00013702B68013B2B609F4B1A68013A1A60F6 +:100D0000A34BA14A1B7811688B4206D2974A95489B +:100D100012680068C91A92699047C04675E1522B63 +:100D200007D1904A914B10681B68974A5B6911681C +:100D30006AE14F2B05D18B4B934A1B6812681A70DE +:100D400063E1482B05D1874B8F4A1B6812681A80D4 +:100D50005BE1572B05D1834B8B4A1B6812681A60E5 +:100D600053E16F2B03D17F4B0121186807E0682BFB +:100D700008D17C4B84481B6802211B880360FFF765 +:100D8000FFFE42E1772B06D1764B7F481B6804219A +:100D90001B680360F3E7472B13D17B4B1868FFF701 +:100DA00029FF7C4B1B6883F3088862B67A4B1B785B +:100DB000002B00D129E16D4B06201B681B6898476A +:100DC00023E1542B04D101233370684B1B685CE092 +:100DD0004E2B0BD13378002B05D1644B69481B682F +:100DE0000221DB689847002333700EE1562B50D167 +:100DF0005E4D01212B686948DB6898472B68032109 +:100E0000DB6867489847674E2B68301CDB68012118 +:100E100098472B680D21DB68634898472B68301C86 +:100E2000DB6801219847544F604B544E3B600023D0 +:100E300033603A1C311C1368581C10601B780393F4 +:100E4000002B03D00B6801330B60F4E72B6831688B +:100E5000DB68564898472B685248DB680121984761 +:100E60000398306052483860434A1368591C116037 +:100E70001A78424B002A03D01A6801321A60F3E74D +:100E80002A681968D36898472B68DB683D480221B7 +:100E9000BAE03D4A582B15D12F4E314D36681368B4 +:100EA0002A68B100934208D25808E0614148208086 +:100EB000207DC507FCD55B18F4E72C4B3E481B682A +:100EC000DB68A0E0592B33D11268264B3B49002A3E +:100ED00002D11B680B6026E00868196863688025EA +:100EE000AB4392086360002A1DD0354B2380237DDD +:100EF000DE07FCD50023184D2D680095AD08AB42E8 +:100F000002D3304D258006E09342FAD09D00465929 +:100F100001334E51EFE7257DEE07FCD59D004919C1 +:100F20004019D21ADFE7114B27481B68DB686AE0DB +:100F30005A2B6AD10B4B17681D680026EF19BD426A +:100F400044D02878311C00F049F90135061CF6E739 +:100F5000A4140000004000413C02002034020020A4 +:100F600030020020800200202C0200208402002099 +:100F70004002002024020020280200203802002025 +:100F800090000020041500008C0200209002002038 +:100F9000200200208802002091000020E0140000C0 +:100FA00009150000E21400002C150000E4140000F4 +:100FB000F014000002A5FFFFF91400008C000020CF +:100FC00044A5FFFF04A5FFFFFD1400002E4D2F4890 +:100FD0002B680121DB68984707230F223240111C40 +:100FE00036093031092A00DD07311020C0186A4661 +:100FF0008154013BF1D22B6804A8DB680821984793 +:101000002B682348DB6803219847224D7A232B70F5 +:10101000214B00221A60214B1B7893422CD01A4B93 +:1010200001211B681E48DB68984725E0111C3039F8 +:10103000C8B2194B092804D81E683201114319603F +:101040001AE0111C4139052903D81868373A010103 +:1010500006E0111C6139052904D81D68573A290199 +:101060000A4308E02C2A03D10E4A1E68166001E0EC +:1010700008490A7000221A600B4B1A6801321A6084 +:101080000A4B1A680132F3E58402002001150000C2 +:10109000031500002C0200208C020020900000208C +:1010A00007150000800200203802002028020020DE +:1010B00010B51C4B01201A78022402431A701A4BF7 +:1010C0000F22197891431970197821431970174923 +:1010D0000C782043087019780A401A701A78202179 +:1010E0000A431A70124B04211A6A0A431A62114BFE +:1010F000114A5A805A7852B2002AFBDBC4220F48A8 +:101100000F499203FEF7CCFF0E4A002313700E4ADC +:1011100013700E4A13700E4A13700E4A13700E4A63 +:10112000137010BD4A440041354400414B44004116 +:1011300000040040000C0040144000000008004281 +:101140002AF60000940200201B03002095020020D4 +:10115000980200201C0300201903002008B5C1B22A +:101160000248FEF7CBFF012008BDC0460008004240 +:10117000024B187E4007C00F7047C046000800426F +:1011800008B5FFF7F5FF0028FBD00248FEF7BCFFCB +:1011900008BDC0460008004208B5FFF7E9FF00237C +:1011A000984205D0FFF7ECFF031C233B5A42534102 +:1011B000181C08BD70B5041C0D1C4618B44204D0A0 +:1011C0002078FFF7CBFF0134F8E7281C70BD10B57D +:1011D000041CFFF7D5FF2070012010BD0B0A5840FA +:1011E000034B4000C05A0902484080B27047C046D5 +:1011F0003A150000F7B50024051C0F1C261CBC4244 +:1012000020D0FFF7BDFF114BC0B21B780190002B1F +:101210001AD1311CFFF7E2FF0D4B061C1A88002A79 +:1012200004D10C4A11782A1C002907D001996A1CA4 +:101230002970802F02D11988013919800134A4B294 +:10124000151CDCE7301C00E00120FEBD1903002066 +:10125000960200201A030020F0B53E4E85B0002211 +:1012600003900C1C32703C4B914201D1012201E0F1 +:101270003A490C801A707F231C4201D080349C4371 +:10128000FFF77EFF3378C0B2002B07D00025357002 +:10129000FFF776FF3378C0B2AB4236D1432803D094 +:1012A000712853D01528EBD1012300930120FFF7BB +:1012B00055FF0098FFF752FF00998025C843C0B240 +:1012C000FFF74CFF039B00270293244A1388002B4F +:1012D0001DD1214901930978002918D10198FFF700 +:1012E0003DFF391C0198FFF779FF013D071C002DD8 +:1012F000EBD1000AC0B2FFF731FFF8B2FFF72EFFC3 +:10130000FFF73EFF3378002B0AD035701FE00299BB +:10131000013B09781380029B019101330293DDE7C1 +:10132000C0B2062807D1009B03990133DBB280319C +:101330000093803C0391002CB8D10420FFF70EFFEE +:10134000FFF71EFF044B01251C7000E00025281C40 +:1013500005B0F0BD190300201A03002096020020FA +:10136000F0B5384C87B0002301902370994201D129 +:10137000012301E0344A1180344A6426137043206B +:10138000FFF7ECFE324FFFF7F3FE002803D1002FEA +:1013900003D0013FF7E7002F03D1013E002EEED12D +:1013A0004DE00125FFF7ECFE2378002B38D1C0B2C9 +:1013B0000290012805D004283DD10620FFF7CEFE7B +:1013C00039E005AE0221301CFFF714FF019880219F +:1013D000FFF710FF23780390002B18D1FFF7D0FE02 +:1013E0000702FFF7CDFEBFB223783F18BFB2012B33 +:1013F0000DD0039B9F4207D13378AB4204D1EB431E +:101400007278DBB29A4204D01820FFF7A7FE0023BF +:1014100003E00620FFF7A2FE029B2278002A02D0FA +:10142000002626700BE0012B05D1019A6B1C80323F +:10143000DDB20192B6E7054A002313700126301C85 +:1014400007B0F0BD19030020960200201A03002007 +:1014500000350C0010B50023934203D0CC5CC4547B +:101460000133F9E710BD031C8218934202D01970B2 +:101470000133FAE770470000F8B5C046F8BC08BC75 +:101480009E467047F8B5C046F8BC08BC9E467047FB +:1014900012010002020000409A2314000002000022 +:1014A0000001000008000000100000002000000003 +:1014B0004000000080000000000100000002000069 +:1014C000000400005D110000811100007111000096 +:1014D000B5110000CF110000591200006113000087 +:1014E00076002000417072203137203230313600D2 +:1014F00032323A34393A313900580A0D00590A0D5E +:10150000005A00230A0D003E00322E300000000079 +:101510007D0A0000990A0000B50A0000D90A0000FF +:10152000F50A0000D90A00001D0B00005B4172643F +:1015300075696E6F3A58595A5D00000021104220BB +:1015400063308440A550C660E770088129914AA1A4 +:101550006BB18CC1ADD1CEE1EFF13112100273321B +:101560005222B5529442F772D662399318837BB3F4 +:101570005AA3BDD39CC3FFF3DEE3622443342004AB +:101580000114E664C774A44485546AA54BB5288544 +:101590000995EEE5CFF5ACC58DD5533672261116FB +:1015A0003006D776F6669556B4465BB77AA7199794 +:1015B0003887DFF7FEE79DD7BCC7C448E558866883 +:1015C000A7784008611802282338CCC9EDD98EE9E4 +:1015D000AFF9488969990AA92BB9F55AD44AB77A5B +:1015E000966A711A500A333A122AFDDBDCCBBFFB34 +:1015F0009EEB799B588B3BBB1AABA66C877CE44C6B +:10160000C55C222C033C600C411CAEED8FFDECCD83 +:10161000CDDD2AAD0BBD688D499D977EB66ED55E3A +:10162000F44E133E322E511E700E9FFFBEEFDDDFD3 +:10163000FCCF1BBF3AAF599F788F8891A981CAB15F +:10164000EBA10CD12DC14EF16FE18010A100C23091 +:10165000E3200450254046706760B9839893FBA34C +:10166000DAB33DC31CD37FE35EF3B1029012F322E1 +:10167000D2323542145277625672EAB5CBA5A8959C +:1016800089856EF54FE52CD50DC5E234C324A01431 +:1016900081046674476424540544DBA7FAB799872C +:1016A000B8975FE77EF71DC73CD7D326F236910681 +:1016B000B01657667676154634564CD96DC90EF974 +:1016C0002FE9C899E9898AB9ABA9445865480678D1 +:1016D0002768C018E1088238A3287DCB5CDB3FEB8C +:1016E0001EFBF98BD89BBBAB9ABB754A545A376A21 +:1016F000167AF10AD01AB32A923A2EFD0FED6CDD5C +:101700004DCDAABD8BADE89DC98D267C076C645C70 +:10171000454CA23C832CE01CC10C1FEF3EFF5DCF6B +:101720007CDF9BAFBABFD98FF89F176E367E554EC0 +:10173000745E932EB23ED10EF01E00000000000039 +:101740000100000009024300020100803209040088 +:10175000000102020000052400100104240200051B +:10176000240600010524010001070583030800FF8A +:1017700009040100020A0000000705810240000080 +:10178000070502024000000000C20100000008003E +:0C179000690000004100000000000000A3 +:04000003000005BD37 +:00000001FF diff --git a/bootloaders/featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin b/bootloaders/featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..4f2a40960 Binary files /dev/null and b/bootloaders/featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.elf b/bootloaders/featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..0b5e89dca Binary files /dev/null and b/bootloaders/featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/featherM0/update-bootloader-feather_m0-v2.0.0-adafruit.5.uf2 b/bootloaders/featherM0/update-bootloader-feather_m0-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..fe0538459 Binary files /dev/null and b/bootloaders/featherM0/update-bootloader-feather_m0-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin b/bootloaders/featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..a7ad465a4 Binary files /dev/null and b/bootloaders/featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.elf b/bootloaders/featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..0d79d8f5e Binary files /dev/null and b/bootloaders/featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/featherM4/update-bootloader-feather_m4-v2.0.0-adafruit.5.uf2 b/bootloaders/featherM4/update-bootloader-feather_m4-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..dd1bbe2a8 Binary files /dev/null and b/bootloaders/featherM4/update-bootloader-feather_m4-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.bin b/bootloaders/gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..6832a558b Binary files /dev/null and b/bootloaders/gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.elf b/bootloaders/gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..c6b954da8 Binary files /dev/null and b/bootloaders/gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/gemmaM0/update-bootloader-gemma_m0-v2.0.0-adafruit.5.uf2 b/bootloaders/gemmaM0/update-bootloader-gemma_m0-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..538922beb Binary files /dev/null and b/bootloaders/gemmaM0/update-bootloader-gemma_m0-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/grand_central_m4/bootloader-grandcentral_m4.bin b/bootloaders/grand_central_m4/bootloader-grandcentral_m4.bin new file mode 100644 index 000000000..f341a2d60 Binary files /dev/null and b/bootloaders/grand_central_m4/bootloader-grandcentral_m4.bin differ diff --git a/bootloaders/hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.bin b/bootloaders/hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.bin new file mode 100644 index 000000000..608f912d7 Binary files /dev/null and b/bootloaders/hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.bin differ diff --git a/bootloaders/hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.elf b/bootloaders/hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.elf new file mode 100644 index 000000000..2a3e19c87 Binary files /dev/null and b/bootloaders/hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.elf differ diff --git a/bootloaders/hallowingM0/update-bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.uf2 b/bootloaders/hallowingM0/update-bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.uf2 new file mode 100644 index 000000000..bb4afab70 Binary files /dev/null and b/bootloaders/hallowingM0/update-bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.uf2 differ diff --git a/bootloaders/itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.bin b/bootloaders/itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..21c1fd5bb Binary files /dev/null and b/bootloaders/itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.elf b/bootloaders/itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..5ffb6001e Binary files /dev/null and b/bootloaders/itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/itsybitsyM0/update-bootloader-itsybitsy_m0-v2.0.0-adafruit.5.uf2 b/bootloaders/itsybitsyM0/update-bootloader-itsybitsy_m0-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..e156e3988 Binary files /dev/null and b/bootloaders/itsybitsyM0/update-bootloader-itsybitsy_m0-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.bin b/bootloaders/itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..2fe0d2c53 Binary files /dev/null and b/bootloaders/itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.elf b/bootloaders/itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..127247953 Binary files /dev/null and b/bootloaders/itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/itsybitsyM4/update-bootloader-itsybitsy_m4-v2.0.0-adafruit.5.uf2 b/bootloaders/itsybitsyM4/update-bootloader-itsybitsy_m4-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..0517c393c Binary files /dev/null and b/bootloaders/itsybitsyM4/update-bootloader-itsybitsy_m4-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/matrixportalM4/bootloader-matrixportal_m4.bin b/bootloaders/matrixportalM4/bootloader-matrixportal_m4.bin new file mode 100644 index 000000000..9a2223ee8 Binary files /dev/null and b/bootloaders/matrixportalM4/bootloader-matrixportal_m4.bin differ diff --git a/bootloaders/metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.bin b/bootloaders/metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..7997b2ab4 Binary files /dev/null and b/bootloaders/metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.elf b/bootloaders/metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..489b32163 Binary files /dev/null and b/bootloaders/metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/metroM0/update-bootloader-metro_m0-v2.0.0-adafruit.5.uf2 b/bootloaders/metroM0/update-bootloader-metro_m0-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..1ef14126b Binary files /dev/null and b/bootloaders/metroM0/update-bootloader-metro_m0-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/metroM4/METRO_M4_sam_ba.bin b/bootloaders/metroM4/METRO_M4_sam_ba.bin new file mode 100644 index 000000000..4ee5cdd83 Binary files /dev/null and b/bootloaders/metroM4/METRO_M4_sam_ba.bin differ diff --git a/bootloaders/metroM4/METRO_M4_sam_ba.elf b/bootloaders/metroM4/METRO_M4_sam_ba.elf new file mode 100644 index 000000000..6d93a4fba Binary files /dev/null and b/bootloaders/metroM4/METRO_M4_sam_ba.elf differ diff --git a/bootloaders/metroM4/METRO_M4_sam_ba.hex b/bootloaders/metroM4/METRO_M4_sam_ba.hex new file mode 100644 index 000000000..79a4ed0ca --- /dev/null +++ b/bootloaders/metroM4/METRO_M4_sam_ba.hex @@ -0,0 +1,457 @@ +:10000000FCFF022055060000390600003D060000F6 +:1000100041060000450600004906000000000000FF +:100020000000000000000000000000004D0600007D +:10003000000000000000000051060000E50700007D +:1000400010B5054C237833B9044B13B10448AFF312 +:1000500000800123237010BD5C0000200000000020 +:10006000041C000008B5064B1BB106480649AFF357 +:1000700000800648036813B1054B03B1984708BDDB +:1000800000000000041C0000600000205800002058 +:10009000000000001A4B1B7813F0FF0F0AD1194B18 +:1000A0001A78194909780A44D2B21A704FF400122A +:1000B000164BDA61124B1A780132D2B21A70114B18 +:1000C0001B78DBB2F02B04D80E4B1B78DBB2092B6C +:1000D0000AD80D4B1A785242D2B21A70094A1178D6 +:1000E0001B780B44DBB21370054B1A78054B1B7859 +:1000F000D2B29A4203D14FF40012044BDA61704736 +:100100007800002001000020000000200080004155 +:1001100010B4C36913F0020FFBD104686FF34104FC +:100120000460C36913F0010FFBD1046844F00104BB +:100130000460036813F0010FFBD1C36913F0010FD2 +:10014000FBD1C36913F0020FF7D142F0804343F0B3 +:1001500004030360C36913F0040FFBD14FF4403371 +:1001600043608181C36913F0020FFBD1036843F040 +:10017000020303605DF8044B704700BF037E13F079 +:10018000010FFBD081627047037E13F0040FFBD098 +:10019000438B13F0010F07D1438B13F0020F03D1F0 +:1001A000438B13F0040F02D00122024B1A70806AB5 +:1001B000C0B270477900002070B5044603689A8B7E +:1001C00002F0080292B232B308259D8380229A720F +:1001D000112183F80011402183F8051183F80421CF +:1001E000114A5068032666F31E705060506966F32A +:1001F0001E7050610D4810600D481061506865F325 +:100200009B30506050686FF30D00506083F804110C +:100210000023237106E093F8073113F0100F01D08B +:1002200000F022FB207970BD940100209400002092 +:10023000140100200160002303714371054B8360AA +:100240000B7843F002030B700268937813F0020FEF +:10025000FBD17047B901000008B5444A936943F0E7 +:1002600001039361424B93F8581041F0010183F868 +:10027000581093F83C1001F0F00183F83C1093F80B +:100280003C1041F0070183F83C1093F8591041F0FD +:10029000010183F8591093F83C1001F00F0183F825 +:1002A0003C1093F83C1041F0700183F83C10402161 +:1002B000304BC3F8A810936943F00103936102F532 +:1002C000A052536813F0040FFBD14FF082431A7809 +:1002D00042F001021A701A46937813F0010FFBD115 +:1002E000254B1968C1F34412C1F3822311F01F0199 +:1002F00003D01F2908BF092100E009211AB11F2AD4 +:1003000008BF192200E019221BB1072B08BF0623E2 +:1003100000E0062302F01F0242EA81111B0303F4EE +:10032000E04319434FF082431985DA7842F0030223 +:10033000DA70DA7842F00C02DA701A786FF3C712CA +:100340001A701A7842F004021A700C4858621A891E +:100350006FF383021A811A8922F001021204120C2F +:100360001A810021802201F0C6FA08BD0008004071 +:1003700000800041001C00408400800094010020A7 +:100380002DE9F041064615461C461F46214B03EB5E +:10039000441310335B68C3F302730333012202FA80 +:1003A00003F3AB4207D81B4A02EB4412536943F0F4 +:1003B000004353610CE014F1000818BF4FF001082E +:1003C000154B03EB881840462A4601F08BFA41464C +:1003D000104A02EB441202F110031161526965F3F5 +:1003E0000D025A605A686FF39B325A60083406EB6C +:1003F00044140223E371637943F08003637107F1CE +:10040000080106EB4111CB7913F0020FFBD028460F +:10041000BDE8F081940100201401002038B50546A4 +:1004200014461B4B1B7813F0FF0F13D1194B1A4ABC +:100430001A645A6C6FF30D025A645A6C6FF39B3254 +:100440005A6490F8443143F0400380F8443101226B +:100450000F4B1A7095F8473113F0010F15D00D4B63 +:100460005B6CC3F30D03A34203D20A4B5C6CC4F371 +:100470000D0408460849224601F034FA012385F8A4 +:1004800047310022024B1A7000E00024204638BD9C +:100490007A00002094010020D400002031B190F8AF +:1004A000053143F0200380F80531704790F805319D +:1004B00043F0100380F80531704700BF094B5A69BB +:1004C0006FF30D025A61022380F8073190F805316D +:1004D00043F0800380F8053190F8073113F0020FE4 +:1004E000FAD070479401002061F07F01C9B2817297 +:1004F000704700BF10B4032280F84021104B596CA4 +:1005000062F31E715964402180F845110D4C1C6442 +:10051000302480F820415C6B62F31E745C6380229F +:1005200080F82421084C1C6380F86011596F6FF328 +:100530001E71596780F864215DF8044B704700BF55 +:1005400094010020D400002054010020344B1A886C +:1005500092B21A8042F20E02324B9A821A46D36845 +:1005600013F0010FFBD02F4B1A7C6FF302021A74A9 +:1005700003F500631A7842F001021A701A465368B4 +:1005800013F0010FFBD140F20512274BDA621A4635 +:10059000536813F0200FFBD14FF48272224B1A6282 +:1005A000A3F5406300221A77204A9A621A4692F80D +:1005B0002C3013F0100FFAD100221D4B83F82020AD +:1005C0001A4692F82C3013F0040FFAD1184B1A7F08 +:1005D00042F002021A771A4692F82C3013F0020FFA +:1005E000FAD1134B5A6A5A621A4692F82C3013F019 +:1005F000080FFAD198220E4B83F820201A4613696F +:1006000013F4807FFBD040F60632074B1A621A467D +:10061000536813F0040FFBD10122064B5A71704747 +:100620000040004100140040001C00400000010494 +:1006300000100040000800400EBEFEE70DBEFEE7C1 +:100640000DBEFEE70DBEFEE70DBEFEE705BEFEE7F2 +:1006500002BEFEE710B5174B174A9A4215D0134653 +:10066000164A9A4211D0134B134A9A420DD2131DC7 +:10067000134CE41A24F003040434002310460F49F9 +:100680005A581A500433A342FAD10E4B0E4A9A42DA +:100690000CD00BD2131D0D49C91A21F003011944C6 +:1006A000043B002243F8042B8B42FBD100F010F8EE +:1006B000FEE700BF5C00002000000020081C0000D6 +:1006C0005F000020A40300205C000020A70300209E +:1006D00070B5394B1B68B3F1FF3F2DD0374A384B0B +:1006E0001A60043A12F07F0F26D1364B1B7813F0B4 +:1006F000010F03D00021344B196011E0324B19680F +:10070000324B994203D100222F4B1A6014E02F493B +:100710002D4B19602E4B013BFDD100212A4B196056 +:10072000254B1B6883F3088822F07F02294B9A60CF +:10073000234B1B681B681847FFF708FF62B600F0E1 +:10074000D1FE00F055F80546234B4FF400129A6095 +:100750004022C3F88820C3F898204FF000629A60C6 +:100760009A611E4B40F2E7325A60C021194A82F862 +:10077000231000229A6007221A60194C0126AB68E8 +:100780002846984700B12670237813F0FF0F05D054 +:10079000002000F02DFB00F0C5FBFCE7237813F0F0 +:1007A000FF0FECD100F016FF0028E8D0012000F088 +:1007B0001FFB00F0B7FBFCE7004000000440000016 +:1007C00014020020000C0040FCFF0220EF6916F02C +:1007D000808D5B0000ED00E00080004110E000E053 +:1007E0007B00002008B5FFF755FC00F077FB08BD43 +:1007F00010B5064C4FF082432360FFF72DFD2046D5 +:100800002168FFF717FD204610BD00BF1802002029 +:10081000F0B5C1B007460E461546084601F073F81C +:100820004000831C8DF8003003238DF801303378AD +:1008300073B16D08012D0DDD6C463146012224F89F +:10084000023F013211F8013F2BB1AA42F7DB02E06F +:10085000012200E001223846694652000023FFF7DA +:100860008FFD41B0F0BD00BFF0B583B0064604680F +:10087000102384F80731A04B1A78A04D2A705A78BB +:100880009F490A7098789F4A1080108880B2DF785C +:1008900040EA0720108018799B4A1080108880B2A7 +:1008A0005F7940EA072010809879984A1080108874 +:1008B00080B2DB7940EA03231380402384F80431BB +:1008C0000A782B7843EA022340F20232934200F086 +:1008D0002D811EDCB3F5807F00F0598109DC812B6E +:1008E00000F0C880822B00F0CD80802B40F0F0819A +:1008F000B8E0B3F5817F00F05381C0F24D81B3F5CC +:10090000407F00F0EF8040F20132934200F0EF8030 +:10091000DEE1B3F5106F00F093800BDCB3F5D06F20 +:100920001FD0B3F5086F00F09580B3F5A06F40F0CD +:10093000CF817BE042F22102934200F0AF8105DCDF +:1009400040F60132934200F02281C1E142F2A1124D +:10095000934200F0A78142F22122934200F0B1813C +:10096000B6E1684B1B88C3F30723012B0ED1306817 +:10097000664B1B889BB2122B9DBF644B1A8892B2A8 +:10098000122263490023FFF7FBFCA5E15D4B1B88A6 +:10099000C3F30723022B0ED130685C4B1B889BB23C +:1009A000432B9DBF594B1A8892B2432259490023C9 +:1009B000FFF7E6FC90E1534B1B88C3F30723032B9F +:1009C0002FD1504B1B88DBB2012B15D013B1022B5A +:1009D0001AD021E0504B1868019030684B4B1B88AF +:1009E0009BB2042B9DBF494B1A8892B2042201A9E5 +:1009F0000023FFF7C5FC6FE1444B1A883068474974 +:100A0000D2B2FFF705FF67E1404B1A8830684449CE +:100A1000D2B2FFF7FDFE5FE120460121FFF73EFD68 +:100A20005AE120460121FFF739FD55E12046FFF745 +:100A300045FD344B1988306889B2FFF755FD4BE10D +:100A4000304B1B8833712046FFF738FD2046FFF7F7 +:100A500051FD41E1314651F8040B01220023FFF71B +:100A60008FFC39E12F4900230B8030680222FFF709 +:100A700087FC31E12B4900230B8030680222FFF70D +:100A80007FFC29E10022274B1A801F4B198801F0B7 +:100A90005001254A11701A8802F00F021A801B8833 +:100AA0009BB2032B19D8204B1B7813F0FF0F164B6A +:100AB0001B889BB203F1080304EB4314A27914BF13 +:100AC000C2F34012C2F30012164B1A803068154967 +:100AD00002220023FFF754FCFEE020460121FFF72D +:100AE000DDFCF9E020460121FFF7D8FCF4E02046C8 +:100AF000FFF7E4FCF0E000BF94000020830000203A +:100B0000860000207C000020800000207E00002065 +:100B10004C190000040000203019000034190000B6 +:100B20004019000084000020820000206B4B1988CF +:100B300089B221F07F01C9B2694A11701A8802F0A6 +:100B40000F021A80674B1B889BB2DBB9634B1B8873 +:100B50009BB2BBB1614B1B889BB2032B12D8604B7D +:100B60001B7813F0FF0F5D4B1B889BB203F108034A +:100B700004EB431314BF202210225A712046FFF7C2 +:100B80009DFCA9E020460121FFF788FCA4E0204657 +:100B90000121FFF783FC9FE02046FFF78FFC9BE0DD +:100BA0004E4B198889B221F07F01C9B24C4A1170AD +:100BB0001A8802F00F021A804A4B1B889BB2002B46 +:100BC00067D1464B1B889BB2002B62D0434B1B88DE +:100BD0009BB2032B5DD8424B1B7813F0FF0F2AD03A +:100BE0003E4B1B889BB2083304EB43139B7913F0F5 +:100BF000200F4AD0394B1A8892B2083204EB4212C5 +:100C0000202111711B889BB2083304EB4313DB795D +:100C100013F0400F39D0314B1A8892B2083204EBEE +:100C200042124021D1711B889BB2083304EB43135D +:100C300002221A7129E0294B1B889BB2083304EB6E +:100C400043139B7913F0100F1FD0244B1A8892B2D4 +:100C5000083204EB4212102111711B889BB2083339 +:100C600004EB4313DB7913F0200F0ED01B4B1A88D3 +:100C700092B2083204EB42122021D1711B889BB240 +:100C8000083304EB431301221A712046FFF716FCC8 +:100C900022E020460121FFF701FC1DE02046FFF77E +:100CA0000DFC19E03068104B1B889BB2082B9DBFD0 +:100CB0000D4B1A8892B208220C490023FFF760FB03 +:100CC0000AE0084B1B8873712046FFF7F7FB03E02F +:100CD00020460121FFF7E2FB03B0F0BD80000020B9 +:100CE000820000207C0000207E00002048000020C0 +:100CF00000B583B002A941F8040D054B1868012224 +:100D00001346FFF73DFB012003B05DF804FB00BF75 +:100D10001802002000B583B0054B18680DF10701DB +:100D20000122FFF77BFB9DF8070003B05DF804FB91 +:100D30001802002008B50648FFF73EFA30B1044B10 +:100D40001B6893F8470100F0010008BD002008BDB2 +:100D50001802002010B503460C46044A10681946D4 +:100D600022460123FFF70CFB204610BD180200208D +:100D700038B505460C460648FFF71EFA30B1044B5D +:100D8000186829462246FFF749FB38BD002038BDC8 +:100D900018020020F8B505460F460B48FFF70CFA7D +:100DA00058B167B13C46084E306829462246FFF7E5 +:100DB00035FB0544241AF7D103E00020F8BD38467E +:100DC000F8BD3846F8BD00BF1802002008B5C3685A +:100DD0000846114698474FF00062034B5A6164225F +:100DE000024B1A8008BD00BF008000419000002027 +:100DF000012806D1054A064B1A600122054B1A70DC +:100E0000704710B9044A024B1A60704780190000FD +:100E10008802002092000020D819000070B584B02C +:100E200004460A46244B1B7813F0FF0F34D00429E4 +:100E300001D1036836E0022901D1038832E003784A +:100E40004E0004AC34440B3C86BB0CE003F00F05B1 +:100E5000092D94BF45F03005373565701B09013009 +:100E6000013CB042F2D330238DF8043078238DF862 +:100E700005300132520004AB13440A2103F80C1C64 +:100E800004AB1E440D2306F8093C0C4B186801A95D +:100E90000232FFF79BFF0CE0084B18682146FFF772 +:100EA00095FF06E0560004AC34440B3C013C0020A6 +:100EB000CCE704B070BD00BF8C0000208802002089 +:100EC00072B6EFF30882044B1A60036883F3088854 +:100ED00043681847704700BF8C0200200E4B1B88E8 +:100EE0009BB24BB10C4A1388013B9BB213801BB9D8 +:100EF0004FF00062094B9A61094B1B889BB24BB1C2 +:100F0000074A1388013B9BB213801BB94022034B55 +:100F1000C3F89820704700BF900000200080004177 +:100F20008E0000202DE9F0438BB002AC894D0FCD2F +:100F30000FC495E80F0084E80F00874A9368C3F355 +:100F400002430AA901EB830353F8203C83490B6059 +:100F5000926892B282490A6002FB03F381490B60F6 +:100F60000022814B1A607A22804B1A707A4C7B4D9A +:100F70007F4B1B681B697F4840219847034630B16F +:100F800040217D4AC2F8941064217C4A11807C4A39 +:100F9000136078497B4A116000217B4A1160002B65 +:100FA000E6D0784B1B681B78FF2B00F06682232B62 +:100FB00040F00482754B1B7813F0FF0F05D06C4B8B +:100FC000186873490222FFF701FF684B1B78532B07 +:100FD00044D16B4B1B686C4A126893421FD9694815 +:100FE0000168013101600132674802609A1A694B59 +:100FF00018688242684B34BF1A601860664E5A4BBC +:101000001868326800F06EFC33685F4A1168194452 +:1010100011605C4A116819441160604A13705A4BA0 +:101020001A68013A1A60574B1A68013A1A605B4B0A +:101030001B78584A11688B420ED24D4A1268926949 +:1010400049480068C91A904730B140224A4BC3F85A +:1010500094206422494B1A8000BF9DE1522B0FD18E +:10106000434B1B685B69404A10684A4A11689847BD +:101070004FF00062404B5A616422494B1A808BE169 +:101080004F2B05D1384B1B68424A12681A7083E116 +:10109000482B05D1344B1B683E4A12681A807BE10D +:1010A000572B05D1304B1A683A4B1B68136073E11C +:1010B0006F2B05D12C4B18680121FFF7AFFE6BE1B8 +:1010C000682B08D13348284B1B681B88036002211A +:1010D000FFF7A4FE60E1772B08D1234B1B681B6848 +:1010E0002C4803600421FFF799FE55E1472B14D1EA +:1010F000284B1868FFF7E4FE2A4B1B6883F3088827 +:1011000062B6294B1B7813F0FF0F00F04581184B96 +:101110001B681B68062098473EE1542B09D1012229 +:101120001A4B1A70124B186819490222FFF74EFE2B +:1011300032E14E2B3AD1154B1B7813F0FF0F05D13E +:101140000B4B186812490222FFF740FE00220F4B9A +:101150001A7021E1601900000040004140020020A7 +:1011600038020020340200208402002030020020D7 +:101170008802002044020020008000418E000020F0 +:10118000280200202C0200203C0200208C000020BD +:10119000A0190000900200209402002024020020E8 +:1011A000900000208C02002092000020562B57D186 +:1011B000994E306899490122FFF708FE3068984936 +:1011C0000322FFF703FE974F306839460122FFF7ED +:1011D000FDFD306894490D22FFF7F8FD306839466F +:1011E0000122FFF7F3FD914B0021914A1160591C38 +:1011F000904A11601B78002B00F04D818C490B68E0 +:1012000001330B601368581C10601B78002BF6D15B +:10121000814F874E386885493268FFF7D7FD3868B7 +:1012200080490122FFF7D2FD00233360824A814BBF +:101230001A6041E10B6801330B601368581C1060A1 +:101240001B78002BF6D1744E30687C49784B1A68B5 +:10125000FFF7BCFD30687A490222FFF7B7FD9BE03B +:10126000582B1DD1774B1A68774B19688A4210D2D8 +:101270002E6836014AF20150638A13F0010FFBD049 +:101280006261A080638A13F0010FFBD032448A426E +:10129000F2D3614B18686D490322FFF797FD7BE09D +:1012A000592B44D1674B186820B9694B1A68694BB0 +:1012B0001A6035E0674B1F68654B1E6823889BB238 +:1012C000238080082CD04AF215584FF0000EF146CA +:1012D0004AF2035CA4F80480638A13F0010FFBD088 +:1012E0002B68032B0DD970B172464B46B958B150DB +:1012F00001332968B3EB910F06D204328342F5D152 +:1013000002E0734600E073466661A4F804C0628A96 +:1013100012F0010FFBD09A0016441744C01AD9D11D +:101320003D4B18684C490322FFF750FD34E05A2B1F +:1013300032D1474B1E68434B1B685BB106EB030879 +:10134000002716F8010B394600F068F907464645B4 +:10135000F7D100E00027304B186840490122FFF721 +:1013600035FD3A460DF107030DF1FF3002F00F0194 +:1013700012090929CCBF3731303103F801198342F2 +:10138000F4D1254E306869460822FFF71FFD30680A +:1013900033490322FFF71AFD7A22324B1A700022DA +:1013A000284B1A60304B1B7813F0FF0F65D01A4B97 +:1013B00018682E490122FFF709FD5EE0A3F1300213 +:1013C000D2B2092A06D81F4A303B116843EA0111FC +:1013D000116052E0A3F14102D2B2052A06D8194A9F +:1013E000373B116843EA0111116046E0A3F1610245 +:1013F000D2B2052A06D8134A573B116843EA0111B5 +:1014000011603AE02C2B33D10E4B1A6810490A6058 +:1014100000221A6031E000BF88020020A4190000F9 +:101420009C190000A8190000F4190000AC19000074 +:101430003C0200202C020020B9190000B81900005D +:10144000A01900009002002034020020C4190000FE +:101450008402002088000020C8190000CC19000078 +:10146000D0190000300200208C000020D4190000A8 +:10147000134A13700022134B1A60134A1368013386 +:101480001360124A116801311160114A12689342C7 +:10149000FFF487AD6CE50F4F0B4E38680E4932688C +:1014A000FFF794FC38680D490122FFF78FFC0023F9 +:1014B00033600B4A054B1A600349044ABAE600BF81 +:1014C00030020020900200203C0200202C0200206C +:1014D0002802002088020020AC190000A819000092 +:1014E000B919000008B5234B4022C3F89C204322C1 +:1014F000C3F88C20A3F5A0535A6942F480525A6174 +:101500001D4B93F84B2042F0010283F84B2093F8D7 +:10151000352002F00F0283F8352093F8352042F091 +:10152000200283F8352093F84A2042F0010283F824 +:101530004A2093F8352002F0F00283F8352093F822 +:10154000352042F0020283F835200C484FF22A6120 +:101550004FF44412FEF7DCFD0023094A1370094AD8 +:101560001370094A1370094A1370094A1370094A23 +:10157000137008BD001C0040008000410030004096 +:101580009802002022030020990200209C020020E3 +:10159000230300202003002008B5C1B20248FEF753 +:1015A000EDFD012008BD00BF00300040024B187E59 +:1015B000C0F38000704700BF0030004008B5FFF75F +:1015C000F5FF0028FBD00248FEF7DEFD08BD00BF96 +:1015D0000030004008B5FFF7E9FF30B1FFF7EEFF3C +:1015E000232814BF0020012008BD002008BD00BF33 +:1015F00070B504460E4631B1451814F8010BFFF7DB +:10160000CBFFAC42F9D1304670BD00BF10B50446E7 +:10161000FFF7D4FF2070012010BD00BF80EA112029 +:10162000034B33F8103083EA012080B2704700BFCB +:10163000041A00002DE9F84F0646884649B30024F5 +:101640002746DFF860A0DFF86090DFF860B0FFF7B2 +:10165000B5FFC5B29AF80030F3B928463946FFF70E +:10166000DDFF0746B9F8003013B99BF800305BB1D5 +:10167000731C3570B8F1800F02BFB9F8002002F179 +:10168000FF32A9F800201E460134A4B24445DED141 +:1016900005E00020BDE8F88F0120BDE8F88F38464E +:1016A000BDE8F88F200300209A02002021030020CB +:1016B0002DE9F04F83B001900022454B1A70009144 +:1016C00019B90122434B1A700DE0434B009A1A805E +:1016D0000022404B1A70009B13F07F0F03D0803321 +:1016E00023F07F0300933A4C0025FFF767FF237830 +:1016F0004BB12570FFF762FFC0B2237823B10024FD +:10170000334B1C705FE0C0B2432821D0712859D000 +:101710001528EAD11CE000222D4B1A7053E0C0B20C +:10172000062809D10BF1010B5FFA8BFB009A803A76 +:101730000092019B80330193009A7AB90420FFF74D +:101740002BFFFFF73BFF0022224B1A7001243AE0E7 +:101750004FF0010BDFF88080DFF878900120FFF771 +:101760001BFF5846FFF718FF6FEA0B00C0B2FFF7E8 +:1017700013FF019E80240027BA46B8F8003013B941 +:1017800099F800202AB13578013BA8F800300136DD +:1017900000E055462846FFF7FFFE28463946FFF78A +:1017A0003DFF0746013CE8D1C0F30720FFF7F4FEF8 +:1017B000F8B2FFF7F1FEFFF701FF054B1B78002B96 +:1017C000ADD0A8E70024204603B0BDE8F08F00BFED +:1017D00020030020210300209A0200202DE9F0437D +:1017E00083B0074600223B4B1A7019B901223A4BCD +:1017F0001A7004E0394A11800022374B1A706425B0 +:101800004FF04308364E4046FFF7C6FE344600E030 +:10181000013CFFF7CBFE10B9002CF9D100E014B960 +:10182000013DF0D151E001262A4C0225FFF7C6FE0A +:1018300022781AB10025274B1D7046E0C3B2012B58 +:1018400002D0042B34D036E001A82946FFF7F2FE7F +:1018500038468021FFF7EEFE8046237883BBFFF7F2 +:10186000ADFE00021FFA80F9FFF7A8FE484480B2DF +:101870002378012B24D0804509D19DF80430B34250 +:1018800005D1F3439DF80520DBB29A4203D018201E +:10189000FFF782FE14E00620FFF77EFE23781BB1DF +:1018A00000250C4B1D7010E00136F6B28037BDE705 +:1018B0000620FFF771FE0022074B1A70012504E095 +:1018C000044B1B78002BF6D0EAE7284603B0BDE8AE +:1018D000F08300BF20030020210300209A02002093 +:1018E00000350C0010B50023934203D0CC5CC454E7 +:1018F0000133F9E710BD02440346934202D003F8D6 +:10190000011BFAE77047034613F8012B002AFBD1AD +:10191000181A013870470000F8B500BFF8BC08BCC1 +:101920009E467047F8B500BFF8BC08BC9E4670479D +:101930000403090441726475696E6F204C4C4300C6 +:101940004D6574726F204D340000000012010002DA +:10195000020000409A232000000201020001000062 +:1019600008000000100000002000000040000000FF +:1019700080000000000100000002000000040000E0 +:1019800099150000BD150000AD150000F11500000F +:101990000D160000B1160000DD170000322E3000D9 +:1019A0000A0D000076000000200000004E6F762037 +:1019B000203620323031370031313A30393A33383D +:1019C00000000000580A0D00590A0D005A000000DE +:1019D000230A0D003E000000F10C0000150D000070 +:1019E000350D0000550D0000710D0000550D000073 +:1019F000950D00005B41726475696E6F3A58595AD3 +:101A00005D00000000002110422063308440A5509A +:101A1000C660E770088129914AA16BB18CC1ADD134 +:101A2000CEE1EFF13112100273325222B5529442DC +:101A3000F772D662399318837BB35AA3BDD39CC384 +:101A4000FFF3DEE36224433420040114E664C77428 +:101A5000A44485546AA54BB528850995EEE5CFF5D4 +:101A6000ACC58DD55336722611163006D776F6667C +:101A70009556B4465BB77AA719973887DFF7FEE724 +:101A80009DD7BCC7C448E5588668A7784008611848 +:101A900002282338CCC9EDD98EE9AFF94889699974 +:101AA0000AA92BB9F55AD44AB77A966A711A500A1C +:101AB000333A122AFDDBDCCBBFFB9EEB799B588BC4 +:101AC0003BBB1AABA66C877CE44CC55C222C033C68 +:101AD000600C411CAEED8FFDECCDCDDD2AAD0BBD14 +:101AE000688D499D977EB66ED55EF44E133E322EBC +:101AF000511E700E9FFFBEEFDDDFFCCF1BBF3AAF64 +:101B0000599F788F8891A981CAB1EBA10CD12DC1C1 +:101B10004EF16FE18010A100C230E3200450254057 +:101B200046706760B9839893FBA3DAB33DC31CD3B7 +:101B30007FE35EF3B1029012F322D23235421452A7 +:101B400077625672EAB5CBA5A89589856EF54FE503 +:101B50002CD50DC5E234C324A014810466744764F7 +:101B600024540544DBA7FAB79987B8975FE77EF757 +:101B70001DC73CD7D326F2369106B0165766767647 +:101B8000154634564CD96DC90EF92FE9C899E98923 +:101B90008AB9ABA94458654806782768C018E10897 +:101BA0008238A3287DCB5CDB3FEB1EFBF98BD89BF7 +:101BB000BBAB9ABB754A545A376A167AF10AD01AE7 +:101BC000B32A923A2EFD0FED6CDD4DCDAABD8BAD43 +:101BD000E89DC98D267C076C645C454CA23C832C37 +:101BE000E01CC10C1FEF3EFF5DCF7CDF9BAFBABF97 +:101BF000D98FF89F176E367E554E745E932EB23E87 +:081C0000D10EF01E00000000EF +:101C080001140000090243000201008032090400A7 +:101C1800000102020000052400100104240200054E +:101C2800240600010524010001070583030800FFBD +:101C380009040100020A00000007058102400000B3 +:101C4800070502024000000000C201000000080071 +:0C1C5800650000004100000000000000DA +:04000003000006559E +:00000001FF diff --git a/bootloaders/metroM4/Makefile b/bootloaders/metroM4/Makefile new file mode 100644 index 000000000..c84424084 --- /dev/null +++ b/bootloaders/metroM4/Makefile @@ -0,0 +1,165 @@ +# Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. +# Copyright (c) 2015 Arduino LLC. All right reserved. +# +# 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 + +# ----------------------------------------------------------------------------- +# Paths +ifeq ($(OS),Windows_NT) + # Are we using mingw/msys/msys2/cygwin? + ifeq ($(TERM),xterm) + T=$(shell cygpath -u $(LOCALAPPDATA)) + MODULE_PATH?=$(T)/Arduino15/packages/arduino + RM=rm + SEP=/ + else + MODULE_PATH?=$(LOCALAPPDATA)/Arduino15/packages/arduino + RM=rm + SEP=\\ + endif +else + UNAME_S := $(shell uname -s) + + ifeq ($(UNAME_S),Linux) + MODULE_PATH?=$(HOME)/.arduino15/packages/arduino + RM=rm + SEP=/ + endif + + ifeq ($(UNAME_S),Darwin) + MODULE_PATH?=$(HOME)/Library/Arduino15/packages/arduino/ + RM=rm + SEP=/ + endif +endif + +ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- +BUILD_PATH=build + +# ----------------------------------------------------------------------------- +# Tools +CC=$(ARM_GCC_PATH)gcc +OBJCOPY=$(ARM_GCC_PATH)objcopy +NM=$(ARM_GCC_PATH)nm +SIZE=$(ARM_GCC_PATH)size + +# ----------------------------------------------------------------------------- +# Compiler options +CFLAGS_EXTRA=-D$(BOARD_CHIP) -DBOARD_ID_$(BOARD_ID) +CFLAGS=-mthumb -mcpu=cortex-m4 -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -ffunction-sections -fdata-sections -nostdlib -nostartfiles --param max-inline-insns-single=500 +ifdef DEBUG + CFLAGS+=-g3 -O1 -DDEBUG=1 +else + CFLAGS+=-Os -DDEBUG=0 +endif + +ELF=$(BOARD_ID)_sam_ba.elf +BIN=$(BOARD_ID)_sam_ba.bin +HEX=$(BOARD_ID)_sam_ba.hex + + +INCLUDES=-I"$(MODULE_PATH)/tools/CMSIS/4.5.0/CMSIS/Include/" -I"$(MODULE_PATH)/tools/CMSIS-Atmel/1.1.0/CMSIS/Device/ATMEL/" + +# ----------------------------------------------------------------------------- +# Linker options +LDFLAGS=-mthumb -mcpu=cortex-m4 -Wall -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all +LDFLAGS+=-Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols --specs=nano.specs --specs=nosys.specs + +# ----------------------------------------------------------------------------- +# Source files and objects +SOURCES= \ + board_driver_led.c \ + board_driver_serial.c \ + board_driver_usb.c \ + board_init.c \ + board_startup.c \ + main.c \ + sam_ba_usb.c \ + sam_ba_cdc.c \ + sam_ba_monitor.c \ + sam_ba_serial.c + +OBJECTS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.o)) +DEPS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.d)) + +ifneq "test$(AVRSTUDIO_EXE_PATH)" "test" + AS_BUILD=copy_for_atmel_studio + AS_CLEAN=clean_for_atmel_studio +else + AS_BUILD= + AS_CLEAN= +endif + + +all: print_info $(SOURCES) $(BIN) $(HEX) $(AS_BUILD) + +$(ELF): Makefile $(BUILD_PATH) $(OBJECTS) + @echo ---------------------------------------------------------- + @echo Creating ELF binary + "$(CC)" -L. -L$(BUILD_PATH) $(LDFLAGS) -Os -Wl,--gc-sections -save-temps -Tbootloader_$(BOARD_ID).ld -Wl,-Map,"$(BUILD_PATH)/$(NAME).map" -o "$(BUILD_PATH)/$(ELF)" -Wl,--start-group $(OBJECTS) -lm -Wl,--end-group + "$(NM)" "$(BUILD_PATH)/$(ELF)" >"$(BUILD_PATH)/$(NAME)_symbols.txt" + "$(SIZE)" --format=sysv -t -x $(BUILD_PATH)/$(ELF) + +$(BIN): $(ELF) + @echo ---------------------------------------------------------- + @echo Creating flash binary + "$(OBJCOPY)" -O binary $(BUILD_PATH)/$< $@ + +$(HEX): $(ELF) + @echo ---------------------------------------------------------- + @echo Creating flash binary + "$(OBJCOPY)" -O ihex $(BUILD_PATH)/$< $@ + +$(BUILD_PATH)/%.o: %.c + @echo ---------------------------------------------------------- + @echo Compiling $< to $@ + "$(CC)" $(CFLAGS) $(CFLAGS_EXTRA) $(INCLUDES) $< -o $@ + @echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +$(BUILD_PATH): + @echo ---------------------------------------------------------- + @echo Creating build folder + -mkdir $(BUILD_PATH) + +print_info: + @echo ---------------------------------------------------------- + @echo Compiling bootloader using + @echo BASE PATH = $(MODULE_PATH) + @echo GCC PATH = $(ARM_GCC_PATH) +# @echo OS = $(OS) +# @echo SHELL = $(SHELL) +# @echo TERM = $(TERM) +# "$(CC)" -v +# env + +copy_for_atmel_studio: $(BIN) $(HEX) + @echo ---------------------------------------------------------- + @echo Atmel Studio detected, copying ELF to project root for debug + cp $(BUILD_PATH)/$(ELF) . + +clean_for_atmel_studio: + @echo ---------------------------------------------------------- + @echo Atmel Studio detected, cleaning ELF from project root + -$(RM) ./$(ELF) + +clean: $(AS_CLEAN) + @echo ---------------------------------------------------------- + @echo Cleaning project + -$(RM) $(BIN) + -$(RM) $(HEX) + -$(RM) $(BUILD_PATH)/*.* + -rmdir $(BUILD_PATH) + +.phony: print_info $(BUILD_PATH) diff --git a/bootloaders/metroM4/README.md b/bootloaders/metroM4/README.md new file mode 100644 index 000000000..98b045e12 --- /dev/null +++ b/bootloaders/metroM4/README.md @@ -0,0 +1,86 @@ +# Metro M4 Bootloader + +## 1- Prerequisites + +The project build is based on Makefile system. +Makefile is present at project root and try to handle multi-platform cases. + +Multi-plaform GCC is provided by ARM here: https://launchpad.net/gcc-arm-embedded/+download + +Atmel Studio contains both make and ARM GCC toolchain. You don't need to install them in this specific use case. + +### Windows + +* Native command line +Make binary can be obtained here: http://gnuwin32.sourceforge.net/packages/make.htm + +* Cygwin/MSys/MSys2/Babun/etc... +It is available natively in all distributions. + +* Atmel Studio +An Atmel Studio **7** Makefile-based project is present at project root, just open samd21_sam_ba.atsln file in AS7. + +### Linux + +Make is usually available by default. + +### OS X + +Make is available through XCode package. + + +## 2- Selecting available SAM-BA interfaces + +By default both USB and UART are made available, but this parameter can be modified in sam_ba_monitor.h, line 31: + +Set the define SAM_BA_INTERFACE to +* SAM_BA_UART_ONLY for only UART interface +* SAM_BA_USBCDC_ONLY for only USB CDC interface +* SAM_BA_BOTH_INTERFACES for enabling both the interfaces + +## 3- Behaviour + +This bootloader implements the double-tap on Reset button. +By quickly pressing this button two times, the board will reset and stay in bootloader, waiting for communication on either USB or USART. + +The USB port in use is the USB Native port, close to the Reset button. + +The USART in use is the one available on pins D0/D1, labelled respectively RX/TX. Communication parameters are a baudrate at 115200, 8bits of data, no parity and 1 stop bit (8N1). + +## 4- Description + +**Pinmap** + +The following pins are used by the program : +PA25 : input/output (USB DP) +PA24 : input/output (USB DM) + +PA23 : input (USART RX) +PA22 : output (USART TX) + +The application board shall avoid driving the PA25, PA24, PB23 and PB22 signals while the boot program is running (after a POR for example). + +**Clock system** + +CPU runs at 48MHz from Generic Clock Generator 0 on DFLL48M. + +Generic Clock Generator 1 is using external 32kHz oscillator and is the source of DFLL48M. + +USB and USART are using Generic Clock Generator 0 also. + +**Memory Mapping** + +Bootloader code will be located at 0x0 and executed before any applicative code. + +Applications compiled to be executed along with the bootloader will start at 0x2000 (see linker script bootloader_samdx1.ld). + +Before jumping to the application, the bootloader changes the VTOR register to use the interrupt vectors of the application @0x2000.<- not required as application code is taking care of this. + +## 5- How to build + +If not specified the makefile builds for **Metro M4**: + +``` +make +``` + diff --git a/bootloaders/metroM4/board_definitions.h b/bootloaders/metroM4/board_definitions.h new file mode 100644 index 000000000..e350d4864 --- /dev/null +++ b/bootloaders/metroM4/board_definitions.h @@ -0,0 +1,32 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#if defined(BOARD_ID_METRO_M4) + #include "board_definitions_metro_m4.h" +#elif defined(BOARD_ID_FEATHER_M4) + #include "board_definitions_feather_m4.h" +#else + #error You must define a BOARD_ID and add the corresponding definitions in board_definitions.h +#endif + +// Common definitions +// ------------------ + +#define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f)) + diff --git a/bootloaders/metroM4/board_definitions_feather_m4.h b/bootloaders/metroM4/board_definitions_feather_m4.h new file mode 100644 index 000000000..ae06f384c --- /dev/null +++ b/bootloaders/metroM4/board_definitions_feather_m4.h @@ -0,0 +1,82 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _BOARD_DEFINITIONS_H_ +#define _BOARD_DEFINITIONS_H_ + +/* + * USB device definitions + */ +#define STRING_PRODUCT "Feather M4" +#define USB_VID_HIGH 0x23 +#define USB_VID_LOW 0x9A +#define USB_PID_HIGH 0x00 +#define USB_PID_LOW 0x22 + +/* + * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by + * quickly tapping two times on the reset button. + * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not + * be touched from the loaded application. + */ +#define BOOT_DOUBLE_TAP_ADDRESS (HSRAM_ADDR + HSRAM_SIZE - 4) +#define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *)BOOT_DOUBLE_TAP_ADDRESS)) + +/* + * If BOOT_LOAD_PIN is defined the bootloader is started if the selected + * pin is tied LOW. + */ +//#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 +//#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 + +#define GPIO(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu)) + +#define BOOK_USART_MASK APBAMASK +#define BOOT_USART_MODULE SERCOM0 +#define BOOT_USART_BUS_CLOCK_INDEX MCLK_APBAMASK_SERCOM0 +#define BOOT_GCLK_ID_CORE SERCOM0_GCLK_ID_CORE +#define BOOT_GCLK_ID_SLOW SERCOM0_GCLK_ID_SLOW +#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 +#define BOOT_USART_PAD3 PINMUX_UNUSED +#define BOOT_USART_PAD2 PINMUX_UNUSED + +#define BOOT_USART_PAD1 PINMUX_PA10C_SERCOM0_PAD2 +#define BOOT_USART_PAD0 PINMUX_PA11C_SERCOM0_PAD3 + +/* Master clock frequency */ +#define CPU_FREQUENCY (48000000ul) +#define VARIANT_MCK CPU_FREQUENCY + +/* Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/* Calibration values for DFLL48 pll */ +#define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) +#define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) + +#define BOARD_LED_PORT (0) +#define BOARD_LED_PIN (17) + +#define BOARD_LEDRX_PORT (1) +#define BOARD_LEDRX_PIN (3) + +#define BOARD_LEDTX_PORT (0) +#define BOARD_LEDTX_PIN (27) + +#endif // _BOARD_DEFINITIONS_H_ diff --git a/bootloaders/metroM4/board_definitions_metro_m4.h b/bootloaders/metroM4/board_definitions_metro_m4.h new file mode 100644 index 000000000..7bb5357df --- /dev/null +++ b/bootloaders/metroM4/board_definitions_metro_m4.h @@ -0,0 +1,82 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _BOARD_DEFINITIONS_H_ +#define _BOARD_DEFINITIONS_H_ +/* + * USB device definitions + */ +#define STRING_PRODUCT "Metro M4" +#define USB_VID_HIGH 0x23 +#define USB_VID_LOW 0x9A +#define USB_PID_HIGH 0x00 +#define USB_PID_LOW 0x20 + + +/* + * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by + * quickly tapping two times on the reset button. + * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not + * be touched from the loaded application. + */ +#define BOOT_DOUBLE_TAP_ADDRESS (HSRAM_ADDR + HSRAM_SIZE - 4) +#define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *)BOOT_DOUBLE_TAP_ADDRESS)) + +/* + * If BOOT_LOAD_PIN is defined the bootloader is started if the selected + * pin is tied LOW. + */ +//#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 +//#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 + +#define GPIO(port, pin) ((((port)&0x7u) << 5) + ((pin)&0x1Fu)) + +#define BOOK_USART_MASK APBAMASK +#define BOOT_USART_MODULE SERCOM0 +#define BOOT_USART_BUS_CLOCK_INDEX MCLK_APBAMASK_SERCOM0 +#define BOOT_GCLK_ID_CORE SERCOM0_GCLK_ID_CORE +#define BOOT_GCLK_ID_SLOW SERCOM0_GCLK_ID_SLOW +#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 +#define BOOT_USART_PAD3 PINMUX_UNUSED +#define BOOT_USART_PAD2 PINMUX_UNUSED + +#define BOOT_USART_PAD1 PINMUX_PA10C_SERCOM0_PAD2 +#define BOOT_USART_PAD0 PINMUX_PA11C_SERCOM0_PAD3 + +/* Master clock frequency */ +#define CPU_FREQUENCY (48000000ul) +#define VARIANT_MCK CPU_FREQUENCY + +/* Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/* Calibration values for DFLL48 pll */ +#define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) +#define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) + +#define BOARD_LED_PORT (0) +#define BOARD_LED_PIN (21) + +#define BOARD_LEDRX_PORT (1) +#define BOARD_LEDRX_PIN (6) + +#define BOARD_LEDTX_PORT (0) +#define BOARD_LEDTX_PIN (27) + +#endif // _BOARD_DEFINITIONS_H_ diff --git a/bootloaders/metroM4/board_driver_led.c b/bootloaders/metroM4/board_driver_led.c new file mode 100644 index 000000000..ffa6c4782 --- /dev/null +++ b/bootloaders/metroM4/board_driver_led.c @@ -0,0 +1,42 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include "board_driver_led.h" + +volatile uint8_t ledKeepValue = 0; +volatile uint8_t ledTargetValue = 20; +volatile int8_t ledDirection = 1; + +inline void LED_pulse() +{ + if (ledKeepValue == 0) { + ledTargetValue += ledDirection; + LED_toggle(); + } + ledKeepValue ++; + + if (ledTargetValue > 240 || ledTargetValue < 10) { + ledDirection = -ledDirection; + ledTargetValue += ledDirection; + } + + if (ledKeepValue == ledTargetValue) { + LED_toggle(); + } +} diff --git a/bootloaders/metroM4/board_driver_led.h b/bootloaders/metroM4/board_driver_led.h new file mode 100644 index 000000000..d7d47cad8 --- /dev/null +++ b/bootloaders/metroM4/board_driver_led.h @@ -0,0 +1,63 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _BOARD_DRIVER_LED_ +#define _BOARD_DRIVER_LED_ + +#include +#include "board_definitions.h" + +#if defined(BOARD_LED_PORT) +inline void LED_init(void) { PORT->Group[BOARD_LED_PORT].DIRSET.reg = (1<Group[BOARD_LED_PORT].OUTSET.reg = (1<Group[BOARD_LED_PORT].OUTCLR.reg = (1<Group[BOARD_LED_PORT].OUTTGL.reg = (1<Group[BOARD_LEDRX_PORT].DIRSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDRX_PORT].OUTSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTTGL.reg = (1<Group[BOARD_LEDTX_PORT].DIRSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDTX_PORT].OUTSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTTGL.reg = (1<USART.SYNCBUSY.bit.ENABLE); + /* Disable the SERCOM UART module */ + sercom->USART.CTRLA.bit.ENABLE = 0; + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.SWRST); + /* Perform a software reset */ + sercom->USART.CTRLA.bit.SWRST = 1; + /* Wait for synchronization */ + while(sercom->USART.CTRLA.bit.SWRST); + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.SWRST || sercom->USART.SYNCBUSY.bit.ENABLE); + /* Update the UART pad settings, mode and data order settings */ + sercom->USART.CTRLA.reg = pad_conf | SERCOM_USART_CTRLA_MODE(1) | SERCOM_USART_CTRLA_DORD; + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.CTRLB); + /* Enable transmit and receive and set data size to 8 bits */ + sercom->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_CHSIZE(0); + /* Load the baud value */ + sercom->USART.BAUD.reg = baud_val; + ///* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.ENABLE); + /* Enable SERCOM UART */ + sercom->USART.CTRLA.bit.ENABLE = 1; +} + +void uart_disable(Sercom *sercom) +{ + /* Wait for synchronization */ + while(sercom->USART.SYNCBUSY.bit.ENABLE); + /* Disable SERCOM UART */ + sercom->USART.CTRLA.bit.ENABLE = 0; +} + +void uart_write_byte(Sercom *sercom, uint8_t data) +{ + /* Wait for Data Register Empty flag */ + while(!sercom->USART.INTFLAG.bit.DRE); + /* Write the data to DATA register */ + sercom->USART.DATA.reg = (uint16_t)data; +} + +uint8_t uart_read_byte(Sercom *sercom) +{ + /* Wait for Receive Complete flag */ + while(!sercom->USART.INTFLAG.bit.RXC); + /* Check for errors */ + if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF) + /* Set the error flag */ + uart_drv_error_flag = true; + /* Return the read data */ + return((uint8_t)sercom->USART.DATA.reg); +} + +void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length) +{ + /* Do the following for specified length */ + do { + /* Wait for Data Register Empty flag */ + while(!sercom->USART.INTFLAG.bit.DRE); + /* Send data from the buffer */ + sercom->USART.DATA.reg = (uint16_t)*ptr++; + } while (length--); +} + +void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length) +{ + /* Do the following for specified length */ + do { + /* Wait for Receive Complete flag */ + while(!sercom->USART.INTFLAG.bit.RXC); + /* Check for errors */ + if (sercom->USART.STATUS.bit.PERR || sercom->USART.STATUS.bit.FERR || sercom->USART.STATUS.bit.BUFOVF) + /* Set the error flag */ + uart_drv_error_flag = true; + /* Store the read data to the buffer */ + *ptr++ = (uint8_t)sercom->USART.DATA.reg; + } while (length--); +} diff --git a/bootloaders/metroM4/board_driver_serial.h b/bootloaders/metroM4/board_driver_serial.h new file mode 100644 index 000000000..809f7ec01 --- /dev/null +++ b/bootloaders/metroM4/board_driver_serial.h @@ -0,0 +1,89 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef UART_DRIVER_H +#define UART_DRIVER_H + +#include +#include +#include + +#define PINMUX_UNUSED 0xFFFFFFFF + +/* SERCOM UART available pad settings */ +enum uart_pad_settings { + UART_RX_PAD0_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(1), + UART_RX_PAD1_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(1), + UART_RX_PAD2_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(2), + UART_RX_PAD3_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(3), + UART_RX_PAD1_TX_PAD0 = SERCOM_USART_CTRLA_RXPO(1), + UART_RX_PAD3_TX_PAD2 = SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1), +}; + +/** + * \brief Initializes the UART + * + * \param Pointer to SERCOM instance + * \param Baud value corresponding to the desired baudrate + * \param SERCOM pad settings + */ +void uart_basic_init(Sercom *sercom, uint16_t baud_val, enum uart_pad_settings pad_conf); + +/** + * \brief Disables UART interface + * + * \param Pointer to SERCOM instance + */ +void uart_disable(Sercom *sercom); + +/** + * \brief Sends a single byte through UART interface + * + * \param Pointer to SERCOM instance + * \param Data to send + */ +void uart_write_byte(Sercom *sercom, uint8_t data); + +/** + * \brief Reads a single character from UART interface + * + * \param Pointer to SERCOM instance + * \return Data byte read + */ +uint8_t uart_read_byte(Sercom *sercom); + +/** + * \brief Sends buffer on UART interface + * + * \param Pointer to SERCOM instance + * \param Pointer to data to send + * \param Number of bytes to send + */ +void uart_write_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length); + +/** + * \brief Reads data on UART interface + * + * \param Pointer to SERCOM instance + * \param Pointer to store read data + * \param Number of bytes to read + */ +void uart_read_buffer_polled(Sercom *sercom, uint8_t *ptr, uint16_t length); + +#endif diff --git a/bootloaders/metroM4/board_driver_usb.c b/bootloaders/metroM4/board_driver_usb.c new file mode 100644 index 000000000..2e45b9c2b --- /dev/null +++ b/bootloaders/metroM4/board_driver_usb.c @@ -0,0 +1,359 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include "board_driver_usb.h" +#include "sam_ba_usb.h" +#include "sam_ba_cdc.h" + +#define NVM_USB_PAD_TRANSN_POS 32 +#define NVM_USB_PAD_TRANSN_SIZE 5 +#define NVM_USB_PAD_TRANSP_POS 37 +#define NVM_USB_PAD_TRANSP_SIZE 5 +#define NVM_USB_PAD_TRIM_POS 42 +#define NVM_USB_PAD_TRIM_SIZE 3 + +__attribute__((__aligned__(4))) UsbDeviceDescriptor usb_endpoint_table[MAX_EP]; // Initialized to zero in USB_Init +__attribute__((__aligned__(4))) uint8_t udd_ep_out_cache_buffer[2][64]; //1 for CTRL, 1 for BULK +__attribute__((__aligned__(4))) uint8_t udd_ep_in_cache_buffer[2][64]; //1 for CTRL, 1 for BULK + +static volatile bool read_job = false; + +/*---------------------------------------------------------------------------- + * \brief + */ +P_USB_CDC USB_Open(P_USB_CDC pCdc, Usb *pUsb) +{ + pCdc->pUsb = pUsb; + pCdc->currentConfiguration = 0; + pCdc->currentConnection = 0; + pCdc->IsConfigured = USB_IsConfigured; +// pCdc->Write = USB_Write; +// pCdc->Read = USB_Read; + + pCdc->pUsb->HOST.CTRLA.bit.ENABLE = true; + + while( pCdc->pUsb->HOST.SYNCBUSY.reg & USB_SYNCBUSY_ENABLE ); //wait for sync + + return pCdc; +} + + +/** + * \brief Load USB calibration value from NVM + */ +static void USB_load_calib(void) +{ + Usb * hw = USB; + uint32_t pad_transn + = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRANSN_POS / 32)) >> (NVM_USB_PAD_TRANSN_POS % 32)) + & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); + uint32_t pad_transp + = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRANSP_POS / 32)) >> (NVM_USB_PAD_TRANSP_POS % 32)) + & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); + uint32_t pad_trim = (*((uint32_t *)(NVMCTRL_SW0) + (NVM_USB_PAD_TRIM_POS / 32)) >> (NVM_USB_PAD_TRIM_POS % 32)) + & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); + if (pad_transn == 0 || pad_transn == 0x1F) { + pad_transn = 9; + } + if (pad_transp == 0 || pad_transp == 0x1F) { + pad_transp = 25; + } + if (pad_trim == 0 || pad_trim == 0x7) { + pad_trim = 6; + } + + hw->DEVICE.PADCAL.reg = USB_PADCAL_TRANSN(pad_transn) | USB_PADCAL_TRANSP(pad_transp) | USB_PADCAL_TRIM(pad_trim); + + hw->DEVICE.QOSCTRL.bit.CQOS = 3; + hw->DEVICE.QOSCTRL.bit.DQOS = 3; +} + +/*---------------------------------------------------------------------------- + * \brief Initializes USB + */ +void USB_Init(void) +{ + uint32_t pad_transn, pad_transp, pad_trim; + + /* Enable USB clock */ + MCLK->APBBMASK.bit.USB_ = 1; + + /* Set up the USB DP/DN pins */ + PORT->Group[0].PINCFG[PIN_PA24H_USB_DM].bit.PMUXEN = 1; + PORT->Group[0].PMUX[PIN_PA24H_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24H_USB_DM & 0x01u))); + PORT->Group[0].PMUX[PIN_PA24H_USB_DM/2].reg |= MUX_PA24H_USB_DM << (4 * (PIN_PA24H_USB_DM & 0x01u)); + PORT->Group[0].PINCFG[PIN_PA25H_USB_DP].bit.PMUXEN = 1; + PORT->Group[0].PMUX[PIN_PA25H_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25H_USB_DP & 0x01u))); + PORT->Group[0].PMUX[PIN_PA25H_USB_DP/2].reg |= MUX_PA25H_USB_DP << (4 * (PIN_PA25H_USB_DP & 0x01u)); + + /* ---------------------------------------------------------------------------------------------- + * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference) + * + */ + GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB; + while(GCLK->SYNCBUSY.bit.GENCTRL0) + { + /* Wait for synchronization */ + } + + /* Reset */ + USB->DEVICE.CTRLA.bit.SWRST = 1; + while (USB->DEVICE.SYNCBUSY.bit.SWRST) + { + /* Sync wait */ + } + + USB_load_calib(); + + /* Set the configuration */ + /* Set mode to Device mode */ + USB->HOST.CTRLA.bit.MODE = 0; + /* Enable Run in Standby */ + USB->HOST.CTRLA.bit.RUNSTDBY = true; + /* Set the descriptor address */ + USB->HOST.DESCADD.reg = (uint32_t)(&usb_endpoint_table[0]); + /* Set speed configuration to Full speed */ + USB->DEVICE.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; + /* Attach to the USB host */ + USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH; + + /* Initialize endpoint table RAM location to a known value 0 */ + memset((uint8_t *)(&usb_endpoint_table[0]), 0, sizeof(usb_endpoint_table)); +} + +uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num) +{ + uint32_t data_address; + uint8_t buf_index; + + /* Set buffer index */ + buf_index = (ep_num == 0) ? 0 : 1; + + /* Check for requirement for multi-packet or auto zlp */ + if (length >= (1 << (usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.SIZE + 3))) + { + /* Update the EP data address */ + data_address = (uint32_t) pData; + /* Enable auto zlp */ + usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = true; + } + else + { + /* Copy to local buffer */ + memcpy(udd_ep_in_cache_buffer[buf_index], pData, length); + /* Update the EP data address */ + data_address = (uint32_t) &udd_ep_in_cache_buffer[buf_index]; + } + + /* Set the buffer address for ep data */ + usb_endpoint_table[ep_num].DeviceDescBank[1].ADDR.reg = data_address; + /* Set the byte count as zero */ + usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = length; + /* Set the multi packet size as zero for multi-packet transfers where length > ep size */ + usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; + /* Clear the transfer complete flag */ + pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; + /* Set the bank as ready */ + pUsb->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.bit.BK1RDY = true; + + /* Wait for transfer to complete */ + while ( (pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT1) == 0 ); + + return length; +} + +/*---------------------------------------------------------------------------- + * \brief Read available data from Endpoint OUT + */ +uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length) +{ + uint32_t packetSize = 0; + + if (!read_job) + { + /* Set the buffer address for ep data */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[USB_EP_OUT-1]; + /* Set the byte count as zero */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + /* Set the byte count as zero */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; + /* Start the reception by clearing the bank 0 ready bit */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true; + /* set the user flag */ + read_job = true; + } + + /* Check for Transfer Complete 0 flag */ + if ( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 ) + { + /* Set packet size */ + packetSize = SAM_BA_MIN(usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT, length); + /* Copy read data to user buffer */ + memcpy(pData, udd_ep_out_cache_buffer[USB_EP_OUT-1], packetSize); + /* Clear the Transfer Complete 0 flag */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; + /* Clear the user flag */ + read_job = false; + } + + return packetSize; +} + +uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length) +{ + if (read_job) + { + /* Stop the reception by setting the bank 0 ready bit */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.bit.BK0RDY = true; + /* Clear the user flag */ + read_job = false; + } + + /* Set the buffer address for ep data */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = ((uint32_t)pData); + /* Set the byte count as zero */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + /* Set the multi packet size as zero for multi-packet transfers where length > ep size */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = length; + /* Clear the bank 0 ready flag */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true; + /* Wait for transfer to complete */ + while (!( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 )); + /* Clear Transfer complete 0 flag */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; + + return length; +} + +/*---------------------------------------------------------------------------- + * \brief Test if the device is configured and handle enumeration + */ +uint8_t USB_IsConfigured(P_USB_CDC pCdc) +{ + Usb *pUsb = pCdc->pUsb; + + /* Check for End of Reset flag */ + if (pUsb->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_EORST) + { + /* Clear the flag */ + pUsb->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; + /* Set Device address as 0 */ + pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | 0; + /* Configure endpoint 0 */ + /* Configure Endpoint 0 for Control IN and Control OUT */ + pUsb->DEVICE.DeviceEndpoint[0].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1); + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; + /* Configure control OUT Packet size to 64 bytes */ + usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3; + /* Configure control IN Packet size to 64 bytes */ + usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3; + /* Configure the data buffer address for control OUT */ + usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[0]; + /* Configure the data buffer address for control IN */ + usb_endpoint_table[0].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[0]; + /* Set Multipacket size to 8 for control OUT and byte count to 0*/ + usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8; + usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0; + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + + // Reset current configuration value to 0 + pCdc->currentConfiguration = 0; + } + else + { + if (pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_RXSTP) + { + sam_ba_usb_CDC_Enumerate(pCdc); + } + } + + return pCdc->currentConfiguration; +} + +/*---------------------------------------------------------------------------- + * \brief Stall the control endpoint + */ +void USB_SendStall(Usb *pUsb, bool direction_in) +{ + /* Check the direction */ + if (direction_in) + { + /* Set STALL request on IN direction */ + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ1 = 1; + } + else + { + /* Set STALL request on OUT direction */ + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ0 = 1; + } +} + +/*---------------------------------------------------------------------------- + * \brief Send zero length packet through the control endpoint + */ +void USB_SendZlp(Usb *pUsb) +{ + /* Set the byte count as zero */ + usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = 0; + /* Clear the transfer complete flag */ + pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; + /* Set the bank as ready */ + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.BK1RDY = true; + /* Wait for transfer to complete */ + while (!( pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT1 )); +} + +/*---------------------------------------------------------------------------- + * \brief Set USB device address obtained from host + */ +void USB_SetAddress(Usb *pUsb, uint16_t wValue) +{ + pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | wValue; +} + +/*---------------------------------------------------------------------------- + * \brief Configure USB device + */ +void USB_Configure(Usb *pUsb) +{ + /* Configure BULK OUT endpoint for CDC Data interface*/ + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(3); + /* Set maximum packet size as 64 bytes */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.SIZE = 3; + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY; + /* Configure the data buffer */ + usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].ADDR.reg = (uint32_t)&udd_ep_out_cache_buffer[1]; + + /* Configure BULK IN endpoint for CDC Data interface */ + pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(3); + /* Set maximum packet size as 64 bytes */ + usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].PCKSIZE.bit.SIZE = 3; + pUsb->DEVICE.DeviceEndpoint[USB_EP_IN].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; + /* Configure the data buffer */ + usb_endpoint_table[USB_EP_IN].DeviceDescBank[1].ADDR.reg = (uint32_t)&udd_ep_in_cache_buffer[1]; + + /* Configure INTERRUPT IN endpoint for CDC COMM interface*/ + pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE1(4); + /* Set maximum packet size as 64 bytes */ + usb_endpoint_table[USB_EP_COMM].DeviceDescBank[1].PCKSIZE.bit.SIZE = 0; + pUsb->DEVICE.DeviceEndpoint[USB_EP_COMM].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY; +} diff --git a/bootloaders/metroM4/board_driver_usb.h b/bootloaders/metroM4/board_driver_usb.h new file mode 100644 index 000000000..4e71b8c1a --- /dev/null +++ b/bootloaders/metroM4/board_driver_usb.h @@ -0,0 +1,45 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _BOARD_DRIVER_USB_H_ +#define _BOARD_DRIVER_USB_H_ + +#include "sam_ba_cdc.h" + +extern UsbDeviceDescriptor usb_endpoint_table[MAX_EP]; +extern uint8_t udd_ep_out_cache_buffer[2][64]; //1 for CTRL, 1 for BULK +extern uint8_t udd_ep_in_cache_buffer[2][64]; //1 for CTRL, 1 for BULK + +P_USB_CDC USB_Open(P_USB_CDC pCdc, Usb *pUsb); + +void USB_Init(void); + +uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num); +uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length); +uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length); + +uint8_t USB_IsConfigured(P_USB_CDC pCdc); + +void USB_SendStall(Usb *pUsb, bool direction_in); +void USB_SendZlp(Usb *pUsb); + +void USB_SetAddress(Usb *pUsb, uint16_t wValue); +void USB_Configure(Usb *pUsb); + +#endif // _BOARD_DRIVER_USB_H_ diff --git a/bootloaders/metroM4/board_init.c b/bootloaders/metroM4/board_init.c new file mode 100644 index 000000000..acdb36a23 --- /dev/null +++ b/bootloaders/metroM4/board_init.c @@ -0,0 +1,145 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include "board_definitions.h" + +/** + * \brief system_init() configures the needed clocks and according Flash Read Wait States. + * We need to: + * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator), will be used as DFLL48M reference. + * 2) Put XOSC32K as source of Generic Clock Generator 3 + * 3) Put Generic Clock Generator 3 as source for Generic Clock Multiplexer 0 (DFLL48M reference) + * 4) Enable DFLL48M clock + * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + */ +// Constants for Clock generators +#define GENERIC_CLOCK_GENERATOR_MAIN (0u) +#define GENERIC_CLOCK_GENERATOR_XOSC32K (3u) +#define GENERIC_CLOCK_GENERATOR_OSCULP32K (2u) /* Initialized at reset for WDT */ +//#define GENERIC_CLOCK_GENERATOR_OSC8M (3u) +// Constants for Clock multiplexers +#define GENERIC_CLOCK_MULTIPLEXER_DFLL48M (0u) + +void board_init(void) +{ + + /* Set 1 Flash Wait State for 48MHz */ + NVMCTRL->CTRLA.reg |= NVMCTRL_CTRLA_RWS(0); + + /* ---------------------------------------------------------------------------------------------- + * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator) + */ + OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_CGM_XT | OSC32KCTRL_XOSC32K_XTALEN; + + while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){ + /* Wait for oscillator to be ready */ + } + + OSC32KCTRL->RTCCTRL.bit.RTCSEL = OSC32KCTRL_RTCCTRL_RTCSEL_ULP1K; + + + /* Software reset the module to ensure it is re-initialized correctly */ + /* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete. + * CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete + */ + GCLK->CTRLA.bit.SWRST = 1; + while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_SWRST ){ + /* wait for reset to complete */ + } + + /* ---------------------------------------------------------------------------------------------- + * 2) Put XOSC32K as source of Generic Clock Generator 3 + */ + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_XOSC32K].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_XOSC32K) | //generic clock gen 3 + GCLK_GENCTRL_GENEN; + + while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL3 ){ + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 3) Put Generic Clock Generator 3 as source for Generic Clock Gen 0 (DFLL48M reference) + */ + GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN; + + /* ---------------------------------------------------------------------------------------------- + * 4) Enable DFLL48M clock + */ + + /* DFLL Configuration in Open Loop mode */ + + OSCCTRL->DFLLCTRLA.reg = 0; + //GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK3_Val); + + OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP( 0x1 ) | + OSCCTRL_DFLLMUL_FSTEP( 0x1 ) | + OSCCTRL_DFLLMUL_MUL( 0 ); + + while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL ) + { + /* Wait for synchronization */ + } + + OSCCTRL->DFLLCTRLB.reg = 0; + while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLCTRLB ) + { + /* Wait for synchronization */ + } + + OSCCTRL->DFLLCTRLA.reg |= OSCCTRL_DFLLCTRLA_ENABLE; + while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_ENABLE ) + { + /* Wait for synchronization */ + } + + OSCCTRL->DFLLVAL.reg = OSCCTRL->DFLLVAL.reg; + while( OSCCTRL->DFLLSYNC.bit.DFLLVAL ); + + OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_WAITLOCK | + OSCCTRL_DFLLCTRLB_CCDIS | OSCCTRL_DFLLCTRLB_USBCRM ; + + while ( !OSCCTRL->STATUS.bit.DFLLRDY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + */ + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_MAIN].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL) | + GCLK_GENCTRL_IDC | + GCLK_GENCTRL_OE | + GCLK_GENCTRL_GENEN; + + while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL0 ) + { + /* Wait for synchronization */ + } + + + /* Turn on the digital interface clock */ + //MCLK->APBAMASK.reg |= MCLK_APBAMASK_GCLK; + + /* + * Now that all system clocks are configured, we can set CLKDIV . + * These values are normally the ones present after Reset. + */ + MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV_DIV1; +} diff --git a/bootloaders/metroM4/board_startup.c b/bootloaders/metroM4/board_startup.c new file mode 100644 index 000000000..317873fcd --- /dev/null +++ b/bootloaders/metroM4/board_startup.c @@ -0,0 +1,160 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include + +struct ConstVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnMemManage_Handler; + void* pfnBusFault_Handler; + void* pfnUsageFault_Handler; + void* pvReservedM9; + void* pvReservedM8; + void* pvReservedM7; + void* pvReservedM6; + void* pfnSVC_Handler; + void* pfnDebugMon_Handler; + void* pvReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; +}; + +/* Symbols exported from linker script */ +extern uint32_t __etext ; +extern uint32_t __data_start__ ; +extern uint32_t __data_end__ ; +extern uint32_t __bss_start__ ; +extern uint32_t __bss_end__ ; +extern uint32_t __StackTop; + +extern int main(void); +extern void __libc_init_array(void); + +/* Exception Table */ +__attribute__ ((section(".isr_vector"))) +const struct ConstVectors exception_table = +{ + /* Configure Initial Stack Pointer, using linker-generated symbols */ + .pvStack = (void*) (&__StackTop), + + .pfnReset_Handler = (void*) Reset_Handler, + .pfnNMI_Handler = (void*) NMI_Handler, + .pfnHardFault_Handler = (void*) HardFault_Handler, + .pfnMemManage_Handler = (void*) MemManage_Handler, + .pfnBusFault_Handler = (void*) BusFault_Handler, + .pfnUsageFault_Handler = (void*) UsageFault_Handler, + .pvReservedM9 = (void*) (0UL), /* Reserved */ + .pvReservedM8 = (void*) (0UL), /* Reserved */ + .pvReservedM7 = (void*) (0UL), /* Reserved */ + .pvReservedM6 = (void*) (0UL), /* Reserved */ + .pfnSVC_Handler = (void*) SVC_Handler, + .pfnDebugMon_Handler = (void*) (0UL), + .pvReservedM3 = (void*) (0UL), /* Reserved */ + .pfnPendSV_Handler = (void*) PendSV_Handler, + .pfnSysTick_Handler = (void*) SysTick_Handler, + +}; + +/** + * \brief This is the code that gets called on processor reset. + * Initializes the device and call the main() routine. + */ +void Reset_Handler( void ) +{ + uint32_t *pSrc, *pDest; + + /* Initialize the initialized data section */ + pSrc = &__etext; + pDest = &__data_start__; + + if ( (&__data_start__ != &__data_end__) && (pSrc != pDest) ) + { + for (; pDest < &__data_end__ ; pDest++, pSrc++ ) + { + *pDest = *pSrc ; + } + } + + /* Clear the zero section */ + if ( &__bss_start__ != &__bss_end__ ) + { + for ( pDest = &__bss_start__ ; pDest < &__bss_end__ ; pDest++ ) + { + *pDest = 0ul ; + } + } + +// board_init(); // will be done in main() after app check + + /* Initialize the C library */ +// __libc_init_array(); + + main(); + + while (1); +} + +void NMI_Handler(void) +{ + __BKPT(14); + while (1); +} + +void HardFault_Handler(void) +{ + __BKPT(13); + while (1); +} + +void MemManage_Handler(void) +{ + __BKPT(13); + while (1); +} + +void BusFault_Handler(void) +{ + __BKPT(13); + while (1); +} + +void UsageFault_Handler(void) +{ + __BKPT(13); + while (1); +} + +void SVC_Handler(void) +{ + __BKPT(5); + while (1); +} + +void PendSV_Handler(void) +{ + __BKPT(2); + while (1); +} diff --git a/bootloaders/metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin b/bootloaders/metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..35aa5202d Binary files /dev/null and b/bootloaders/metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.elf b/bootloaders/metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..553027c2b Binary files /dev/null and b/bootloaders/metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/metroM4/bootloader_FEATHER_M4.ld b/bootloaders/metroM4/bootloader_FEATHER_M4.ld new file mode 100644 index 000000000..a59547c07 --- /dev/null +++ b/bootloaders/metroM4/bootloader_FEATHER_M4.ld @@ -0,0 +1,222 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000-0x0004 /* 4 bytes used by bootloader to keep data between resets */ +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __sketch_vectors_ptr + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + . = ORIGIN(FLASH); + + .vectors : + { + KEEP(*(.isr_vector)) + } > FLASH + + .text : + { + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + PROVIDE(__sketch_vectors_ptr = ORIGIN(FLASH) + LENGTH(FLASH)); + + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/bootloaders/metroM4/bootloader_METRO_M4.ld b/bootloaders/metroM4/bootloader_METRO_M4.ld new file mode 100644 index 000000000..a59547c07 --- /dev/null +++ b/bootloaders/metroM4/bootloader_METRO_M4.ld @@ -0,0 +1,222 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000-0x0004 /* 4 bytes used by bootloader to keep data between resets */ +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __sketch_vectors_ptr + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + . = ORIGIN(FLASH); + + .vectors : + { + KEEP(*(.isr_vector)) + } > FLASH + + .text : + { + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + PROVIDE(__sketch_vectors_ptr = ORIGIN(FLASH) + LENGTH(FLASH)); + + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/bootloaders/metroM4/build_all_bootloaders.sh b/bootloaders/metroM4/build_all_bootloaders.sh new file mode 100644 index 000000000..62d289cac --- /dev/null +++ b/bootloaders/metroM4/build_all_bootloaders.sh @@ -0,0 +1,20 @@ +#!/bin/bash -ex + +BOARD_ID=arduino_zero NAME=samd21_sam_ba make clean all + +BOARD_ID=genuino_zero NAME=samd21_sam_ba_genuino make clean all + +BOARD_ID=arduino_mkr1000 NAME=samd21_sam_ba_arduino_mkr1000 make clean all +mv -v samd21_sam_ba_arduino_mkr1000.* ../mkr1000/ + +BOARD_ID=genuino_mkr1000 NAME=samd21_sam_ba_genuino_mkr1000 make clean all +mv -v samd21_sam_ba_genuino_mkr1000.* ../mkr1000/ + +BOARD_ID=arduino_mkrzero NAME=samd21_sam_ba_arduino_mkrzero make clean all +mv -v samd21_sam_ba_arduino_mkrzero.* ../mkrzero/ + +BOARD_ID=arduino_mkrfox1200 NAME=samd21_sam_ba_arduino_mkrfox1200 make clean all +mv -v samd21_sam_ba_arduino_mkrfox1200.* ../mkrfox1200/ + +echo Done building bootloaders! + diff --git a/bootloaders/metroM4/main.c b/bootloaders/metroM4/main.c new file mode 100644 index 000000000..726a67f19 --- /dev/null +++ b/bootloaders/metroM4/main.c @@ -0,0 +1,235 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include +#include "sam_ba_monitor.h" +#include "sam_ba_serial.h" +#include "board_definitions.h" +#include "board_driver_led.h" +#include "sam_ba_usb.h" +#include "sam_ba_cdc.h" + +extern uint32_t __sketch_vectors_ptr; // Exported value from linker script +extern void board_init(void); + +#if (defined DEBUG) && (DEBUG == 1) +volatile uint32_t* pulSketch_Start_Address; +#endif + +static volatile bool main_b_cdc_enable = false; + +/** + * \brief Check the application startup condition + * + */ +static void check_start_application(void) +{ +// LED_init(); +// LED_off(); + +#if (!defined DEBUG) || ((defined DEBUG) && (DEBUG == 0)) +uint32_t* pulSketch_Start_Address; +#endif + + /* + * Test sketch stack pointer @ &__sketch_vectors_ptr + * Stay in SAM-BA if value @ (&__sketch_vectors_ptr) == 0xFFFFFFFF (Erased flash cell value) + */ + if (__sketch_vectors_ptr == 0xFFFFFFFF) + { + /* Stay in bootloader */ + return; + } + + /* + * Load the sketch Reset Handler address + * __sketch_vectors_ptr is exported from linker script and point on first 32b word of sketch vector table + * First 32b word is sketch stack + * Second 32b word is sketch entry point: Reset_Handler() + */ + pulSketch_Start_Address = &__sketch_vectors_ptr ; + pulSketch_Start_Address++ ; + + /* + * Test vector table address of sketch @ &__sketch_vectors_ptr + * Stay in SAM-BA if this function is not aligned enough, ie not valid + */ + if ( ((uint32_t)(&__sketch_vectors_ptr) & ~SCB_VTOR_TBLOFF_Msk) != 0x00) + { + /* Stay in bootloader */ + return; + } + +#if defined(BOOT_DOUBLE_TAP_ADDRESS) + #define DOUBLE_TAP_MAGIC 0xf01669efUL + //if (PM->RCAUSE.bit.POR) + if( RSTC->RCAUSE.bit.POR ) + { + /* On power-on initialize double-tap */ + BOOT_DOUBLE_TAP_DATA = 0; + } + else + { + if (BOOT_DOUBLE_TAP_DATA == DOUBLE_TAP_MAGIC) + { + /* Second tap, stay in bootloader */ + BOOT_DOUBLE_TAP_DATA = 0; + return; + } + + /* First tap */ + BOOT_DOUBLE_TAP_DATA = DOUBLE_TAP_MAGIC; + + /* Wait 0.5sec to see if the user tap reset again. + * The loop value is based on SAMD51 default 48Mhz clock @ reset. + */ + for (uint32_t i=0; i<6000000; i++) /* 500ms */ + /* force compiler to not optimize this... */ + __asm__ __volatile__(""); + + /* Timeout happened, continue boot... */ + BOOT_DOUBLE_TAP_DATA = 0; + } +#endif + +/* +#if defined(BOOT_LOAD_PIN) + volatile PortGroup *boot_port = (volatile PortGroup *)(&(PORT->Group[BOOT_LOAD_PIN / 32])); + volatile bool boot_en; + + // Enable the input mode in Boot GPIO Pin + boot_port->DIRCLR.reg = BOOT_PIN_MASK; + boot_port->PINCFG[BOOT_LOAD_PIN & 0x1F].reg = PORT_PINCFG_INEN | PORT_PINCFG_PULLEN; + boot_port->OUTSET.reg = BOOT_PIN_MASK; + // Read the BOOT_LOAD_PIN status + boot_en = (boot_port->IN.reg) & BOOT_PIN_MASK; + + // Check the bootloader enable condition + if (!boot_en) + { + // Stay in bootloader + return; + } +#endif +*/ + +// LED_on(); + + /* Rebase the Stack Pointer */ + __set_MSP( (uint32_t)(__sketch_vectors_ptr) ); + + /* Rebase the vector table base address */ + SCB->VTOR = ((uint32_t)(&__sketch_vectors_ptr) & SCB_VTOR_TBLOFF_Msk); + + /* Jump to application Reset Handler in the application */ + asm("bx %0"::"r"(*pulSketch_Start_Address)); +} + +#if DEBUG_ENABLE +# define DEBUG_PIN_HIGH port_pin_set_output_level(BOOT_LED, 1) +# define DEBUG_PIN_LOW port_pin_set_output_level(BOOT_LED, 0) +#else +# define DEBUG_PIN_HIGH do{}while(0) +# define DEBUG_PIN_LOW do{}while(0) +#endif + +/** + * \brief SAMDx1 SAM-BA Main loop. + * \return Unused (ANSI-C compatibility). + */ +int main(void) +{ +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + P_USB_CDC pCdc; +#endif + DEBUG_PIN_HIGH; + + /* Jump in application if condition is satisfied */ + check_start_application(); + + /* We have determined we should stay in the monitor. */ + /* System initialization */ + board_init(); + __enable_irq(); + +#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + /* UART is enabled in all cases */ + serial_open(); +#endif + +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + pCdc = usb_init(); +#endif + + DEBUG_PIN_LOW; + + /* Initialize LEDs */ + LED_init(); + LEDRX_init(); + LEDRX_off(); + LEDTX_init(); + LEDTX_off(); + + /* Start the sys tick (1 ms) */ + SysTick_Config(1000); + + /* Wait for a complete enum on usb or a '#' char on serial line */ + while (1) + { + + #if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + if (pCdc->IsConfigured(pCdc) != 0) + { + main_b_cdc_enable = true; + } + + /* Check if a USB enumeration has succeeded and if comm port has been opened */ + if (main_b_cdc_enable) + { + sam_ba_monitor_init(SAM_BA_INTERFACE_USBCDC); + /* SAM-BA on USB loop */ + while( 1 ) + { + sam_ba_monitor_run(); + } + } + #endif + + #if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + /* Check if a '#' has been received */ + if (!main_b_cdc_enable && serial_sharp_received()) + { + sam_ba_monitor_init(SAM_BA_INTERFACE_USART); + /* SAM-BA on Serial loop */ + while(1) + { + sam_ba_monitor_run(); + } + } + #endif + } +} + +void SysTick_Handler(void) +{ + LED_pulse(); + + sam_ba_monitor_sys_tick(); +} diff --git a/bootloaders/metroM4/sam_ba_cdc.c b/bootloaders/metroM4/sam_ba_cdc.c new file mode 100644 index 000000000..377340921 --- /dev/null +++ b/bootloaders/metroM4/sam_ba_cdc.c @@ -0,0 +1,98 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include "sam_ba_cdc.h" +#include "board_driver_usb.h" + +usb_cdc_line_coding_t line_coding= +{ + 115200, // baudrate + 0, // 1 Stop Bit + 0, // None Parity + 8 // 8 Data bits +}; + +#define pCdc (&sam_ba_cdc) + +int cdc_putc(/*P_USB_CDC pCdc,*/ int value) +{ + /* Send single byte on USB CDC */ + USB_Write(pCdc->pUsb, (const char *)&value, 1, USB_EP_IN); + + return 1; +} + +int cdc_getc(/*P_USB_CDC pCdc*/void) +{ + uint8_t rx_char; + + /* Read singly byte on USB CDC */ + USB_Read(pCdc->pUsb, (char *)&rx_char, 1); + + return (int)rx_char; +} + +bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/void) +{ + /* Check whether the device is configured */ + if ( !USB_IsConfigured(pCdc) ) + return 0; + + /* Return transfer complete 0 flag status */ + return (pCdc->pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0); +} + +uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length) +{ + /* Send the specified number of bytes on USB CDC */ + USB_Write(pCdc->pUsb, (const char *)data, length, USB_EP_IN); + return length; +} + +uint32_t cdc_read_buf(/*P_USB_CDC pCdc,*/ void* data, uint32_t length) +{ + /* Check whether the device is configured */ + if ( !USB_IsConfigured(pCdc) ) + return 0; + + /* Read from USB CDC */ + return USB_Read(pCdc->pUsb, (char *)data, length); +} + +uint32_t cdc_read_buf_xmd(/*P_USB_CDC pCdc,*/ void* data, uint32_t length) +{ + /* Check whether the device is configured */ + if ( !USB_IsConfigured(pCdc) ) + return 0; + + /* Blocking read till specified number of bytes is received */ + // XXX: USB_Read_blocking is not reliable + // return USB_Read_blocking(pCdc, (char *)data, length); + + char *dst = (char *)data; + uint32_t remaining = length; + while (remaining) + { + uint32_t readed = USB_Read(pCdc->pUsb, (char *)dst, remaining); + remaining -= readed; + dst += readed; + } + + return length; +} diff --git a/bootloaders/metroM4/sam_ba_cdc.h b/bootloaders/metroM4/sam_ba_cdc.h new file mode 100644 index 000000000..49b7643cf --- /dev/null +++ b/bootloaders/metroM4/sam_ba_cdc.h @@ -0,0 +1,91 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _SAM_BA_USB_CDC_H_ +#define _SAM_BA_USB_CDC_H_ + +#include +#include "sam_ba_usb.h" + +typedef struct +{ + uint32_t dwDTERate; + uint8_t bCharFormat; + uint8_t bParityType; + uint8_t bDataBits; +} usb_cdc_line_coding_t; + +/* CDC Class Specific Request Code */ +#define GET_LINE_CODING 0x21A1 +#define SET_LINE_CODING 0x2021 +#define SET_CONTROL_LINE_STATE 0x2221 + +extern usb_cdc_line_coding_t line_coding; + + +/** + * \brief Sends a single byte through USB CDC + * + * \param Data to send + * \return number of data sent + */ +int cdc_putc(/*P_USB_CDC pCdc,*/ int value); + +/** + * \brief Reads a single byte through USB CDC + * + * \return Data read through USB + */ +int cdc_getc(/*P_USB_CDC pCdc*/); + +/** + * \brief Checks if a character has been received on USB CDC + * + * \return \c 1 if a byte is ready to be read. + */ +bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/); + +/** + * \brief Sends buffer on USB CDC + * + * \param data pointer + * \param number of data to send + * \return number of data sent + */ +uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length); + +/** + * \brief Gets data on USB CDC + * + * \param data pointer + * \param number of data to read + * \return number of data read + */ +uint32_t cdc_read_buf(/*P_USB_CDC pCdc,*/ void* data, uint32_t length); + +/** + * \brief Gets specified number of bytes on USB CDC + * + * \param data pointer + * \param number of data to read + * \return number of data read + */ +uint32_t cdc_read_buf_xmd(/*P_USB_CDC pCdc,*/ void* data, uint32_t length); + +#endif // _SAM_BA_USB_CDC_H_ diff --git a/bootloaders/metroM4/sam_ba_monitor.c b/bootloaders/metroM4/sam_ba_monitor.c new file mode 100644 index 000000000..5d4d2f5b2 --- /dev/null +++ b/bootloaders/metroM4/sam_ba_monitor.c @@ -0,0 +1,552 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include "sam.h" +#include +#include "sam_ba_monitor.h" +#include "sam_ba_serial.h" +#include "board_driver_serial.h" +#include "board_driver_usb.h" +#include "sam_ba_usb.h" +#include "sam_ba_cdc.h" +#include "board_driver_led.h" + +const char RomBOOT_Version[] = SAM_BA_VERSION; +const char RomBOOT_ExtendedCapabilities[] = "[Arduino:XYZ]"; + +/* Provides one common interface to handle both USART and USB-CDC */ +typedef struct +{ + /* send one byte of data */ + int (*put_c)(int value); + /* Get one byte */ + int (*get_c)(void); + /* Receive buffer not empty */ + bool (*is_rx_ready)(void); + /* Send given data (polling) */ + uint32_t (*putdata)(void const* data, uint32_t length); + /* Get data from comm. device */ + uint32_t (*getdata)(void* data, uint32_t length); + /* Send given data (polling) using xmodem (if necessary) */ + uint32_t (*putdata_xmd)(void const* data, uint32_t length); + /* Get data from comm. device using xmodem (if necessary) */ + uint32_t (*getdata_xmd)(void* data, uint32_t length); +} t_monitor_if; + +#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES +/* Initialize structures with function pointers from supported interfaces */ +const t_monitor_if uart_if = +{ + .put_c = serial_putc, + .get_c = serial_getc, + .is_rx_ready = serial_is_rx_ready, + .putdata = serial_putdata, + .getdata = serial_getdata, + .putdata_xmd = serial_putdata_xmd, + .getdata_xmd = serial_getdata_xmd +}; +#endif + +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES +//Please note that USB doesn't use Xmodem protocol, since USB already includes flow control and data verification +//Data are simply forwarded without further coding. +const t_monitor_if usbcdc_if = +{ + .put_c = cdc_putc, + .get_c = cdc_getc, + .is_rx_ready = cdc_is_rx_ready, + .putdata = cdc_write_buf, + .getdata = cdc_read_buf, + .putdata_xmd = cdc_write_buf, + .getdata_xmd = cdc_read_buf_xmd +}; +#endif + +/* The pointer to the interface object use by the monitor */ +t_monitor_if * ptr_monitor_if; + +/* b_terminal_mode mode (ascii) or hex mode */ +volatile bool b_terminal_mode = false; +volatile bool b_sam_ba_interface_usart = false; + +/* Pulse generation counters to keep track of the time remaining for each pulse type */ +#define TX_RX_LED_PULSE_PERIOD 100 +volatile uint16_t txLEDPulse = 0; // time remaining for Tx LED pulse +volatile uint16_t rxLEDPulse = 0; // time remaining for Rx LED pulse + +void sam_ba_monitor_init(uint8_t com_interface) +{ +#if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + //Selects the requested interface for future actions + if (com_interface == SAM_BA_INTERFACE_USART) + { + ptr_monitor_if = (t_monitor_if*) &uart_if; + b_sam_ba_interface_usart = true; + } +#endif +#if SAM_BA_INTERFACE == SAM_BA_USBCDC_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES + if (com_interface == SAM_BA_INTERFACE_USBCDC) + { + ptr_monitor_if = (t_monitor_if*) &usbcdc_if; + } +#endif +} + +/* + * Central SAM-BA monitor putdata function using the board LEDs + */ +static uint32_t sam_ba_putdata(t_monitor_if* pInterface, void const* data, uint32_t length) +{ + uint32_t result ; + + result=pInterface->putdata(data, length); + + LEDTX_on(); + txLEDPulse = TX_RX_LED_PULSE_PERIOD; + + return result; +} + +/* + * Central SAM-BA monitor getdata function using the board LEDs + */ +static uint32_t sam_ba_getdata(t_monitor_if* pInterface, void* data, uint32_t length) +{ + uint32_t result ; + + result=pInterface->getdata(data, length); + + if (result) + { + LEDRX_on(); + rxLEDPulse = TX_RX_LED_PULSE_PERIOD; + } + + return result; +} + +/* + * Central SAM-BA monitor putdata function using the board LEDs + */ +static uint32_t sam_ba_putdata_xmd(t_monitor_if* pInterface, void const* data, uint32_t length) +{ + uint32_t result ; + + result=pInterface->putdata_xmd(data, length); + + LEDTX_on(); + txLEDPulse = TX_RX_LED_PULSE_PERIOD; + + return result; +} + +/* + * Central SAM-BA monitor getdata function using the board LEDs + */ +static uint32_t sam_ba_getdata_xmd(t_monitor_if* pInterface, void* data, uint32_t length) +{ + uint32_t result ; + + result=pInterface->getdata_xmd(data, length); + + if (result) + { + LEDRX_on(); + rxLEDPulse = TX_RX_LED_PULSE_PERIOD; + } + + return result; +} + +/** + * \brief This function allows data emission by USART + * + * \param *data Data pointer + * \param length Length of the data + */ +void sam_ba_putdata_term(uint8_t* data, uint32_t length) +{ + uint8_t temp, buf[12], *data_ascii; + uint32_t i, int_value; + + if (b_terminal_mode) + { + if (length == 4) + int_value = *(uint32_t *) data; + else if (length == 2) + int_value = *(uint16_t *) data; + else + int_value = *(uint8_t *) data; + + data_ascii = buf + 2; + data_ascii += length * 2 - 1; + + for (i = 0; i < length * 2; i++) + { + temp = (uint8_t) (int_value & 0xf); + + if (temp <= 0x9) + *data_ascii = temp | 0x30; + else + *data_ascii = temp + 0x37; + + int_value >>= 4; + data_ascii--; + } + buf[0] = '0'; + buf[1] = 'x'; + buf[length * 2 + 2] = '\n'; + buf[length * 2 + 3] = '\r'; + sam_ba_putdata(ptr_monitor_if, buf, length * 2 + 4); + } + else + sam_ba_putdata(ptr_monitor_if, data, length); + return; +} + +volatile uint32_t sp; +void call_applet(uint32_t address) +{ + uint32_t app_start_address; + + __disable_irq(); + + sp = __get_MSP(); + + /* Rebase the Stack Pointer */ + __set_MSP(*(uint32_t *) address); + + /* Load the Reset Handler address of the application */ + app_start_address = *(uint32_t *)(address + 4); + + /* Jump to application Reset Handler in the application */ + asm("bx %0"::"r"(app_start_address)); +} + +uint32_t current_number; +uint32_t i, length; +uint8_t command, *ptr_data, *ptr, data[SIZEBUFMAX]; +uint8_t j; +uint32_t u32tmp; + +uint32_t PAGE_SIZE, PAGES, MAX_FLASH; + +// Prints a 32-bit integer in hex. +static void put_uint32(uint32_t n) +{ + char buff[8]; + int i; + for (i=0; i<8; i++) + { + int d = n & 0XF; + n = (n >> 4); + + buff[7-i] = d > 9 ? 'A' + d - 10 : '0' + d; + } + sam_ba_putdata( ptr_monitor_if, buff, 8); +} + +static void sam_ba_monitor_loop(void) +{ + length = sam_ba_getdata(ptr_monitor_if, data, SIZEBUFMAX); + ptr = data; + + for (i = 0; i < length; i++, ptr++) + { + if (*ptr == 0xff) continue; + + if (*ptr == '#') + { + if (b_terminal_mode) + { + sam_ba_putdata(ptr_monitor_if, "\n\r", 2); + } + if (command == 'S') + { + //Check if some data are remaining in the "data" buffer + if(length>i) + { + //Move current indexes to next avail data (currently ptr points to "#") + ptr++; + i++; + + //We need to add first the remaining data of the current buffer already read from usb + //read a maximum of "current_number" bytes + if ((length-i) < current_number) + { + u32tmp=(length-i); + } + else + { + u32tmp=current_number; + } + + memcpy(ptr_data, ptr, u32tmp); + i += u32tmp; + ptr += u32tmp; + j = u32tmp; + } + //update i with the data read from the buffer + i--; + ptr--; + //Do we expect more data ? + if(jput_c(0x6); + } + } + else if (command == 'T') + { + b_terminal_mode = 1; + sam_ba_putdata(ptr_monitor_if, "\n\r", 2); + } + else if (command == 'N') + { + if (b_terminal_mode == 0) + { + sam_ba_putdata( ptr_monitor_if, "\n\r", 2); + } + b_terminal_mode = 0; + } + else if (command == 'V') + { + sam_ba_putdata( ptr_monitor_if, "v", 1); + sam_ba_putdata( ptr_monitor_if, (uint8_t *) RomBOOT_Version, strlen(RomBOOT_Version)); + sam_ba_putdata( ptr_monitor_if, " ", 1); + sam_ba_putdata( ptr_monitor_if, (uint8_t *) RomBOOT_ExtendedCapabilities, strlen(RomBOOT_ExtendedCapabilities)); + sam_ba_putdata( ptr_monitor_if, " ", 1); + ptr = (uint8_t*) &(__DATE__); + i = 0; + while (*ptr++ != '\0') + i++; + sam_ba_putdata( ptr_monitor_if, (uint8_t *) &(__DATE__), i); + sam_ba_putdata( ptr_monitor_if, " ", 1); + i = 0; + ptr = (uint8_t*) &(__TIME__); + while (*ptr++ != '\0') + i++; + sam_ba_putdata( ptr_monitor_if, (uint8_t *) &(__TIME__), i); + sam_ba_putdata( ptr_monitor_if, "\n\r", 2); + } + else if (command == 'X') + { + // Syntax: X[ADDR]# + // Erase the flash memory starting from ADDR to the end of flash. + + //block size 16 pages + + uint32_t dst_addr = current_number; // starting address + + while (dst_addr < MAX_FLASH) + { + while (NVMCTRL->STATUS.bit.READY == 0); + // Execute "EB" Erase Block + NVMCTRL->ADDR.reg = dst_addr; + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_EB; + while (NVMCTRL->STATUS.bit.READY == 0); + + dst_addr += PAGE_SIZE * 16; // Skip a block + } + + // Notify command completed + sam_ba_putdata( ptr_monitor_if, "X\n\r", 3); + } + else if (command == 'Y') + { + // This command writes the content of a buffer in SRAM into flash memory. + + // Syntax: Y[ADDR],0# + // Set the starting address of the SRAM buffer. + + // Syntax: Y[ROM_ADDR],[SIZE]# + // Write the first SIZE bytes from the SRAM buffer (previously set) into + // flash memory starting from address ROM_ADDR + + static uint32_t *src_buff_addr = NULL; + + if (current_number == 0) + { + // Set buffer address + src_buff_addr = (uint32_t*)ptr_data; + } + else + { + // Write to flash + uint32_t size = current_number/4; + uint32_t *src_addr = src_buff_addr; + uint32_t *dst_addr = (uint32_t*)ptr_data; + + // Set automatic page write + NVMCTRL->CTRLA.reg |= NVMCTRL_CTRLA_WMODE(NVMCTRL_CTRLA_WMODE_AP); + + // Do writes in pages + while (size) + { + // Execute "PBC" Page Buffer Clear + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_PBC; + while (NVMCTRL->STATUS.bit.READY == 0) + ; + + // Fill page buffer + uint32_t i; + for (i=0; i<(PAGE_SIZE/4) && iADDR.reg = ((uint32_t)dst_addr); + NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMDEX_KEY | NVMCTRL_CTRLB_CMD_WP; + while (NVMCTRL->STATUS.bit.READY == 0) + ; + + // Advance to next page + dst_addr += i; + src_addr += i; + size -= i; + } + } + + // Notify command completed + sam_ba_putdata( ptr_monitor_if, "Y\n\r", 3); + } + else if (command == 'Z') + { + // This command calculate CRC for a given area of memory. + // It's useful to quickly check if a transfer has been done + // successfully. + + // Syntax: Z[START_ADDR],[SIZE]# + // Returns: Z[CRC]# + + uint8_t *data = (uint8_t *)ptr_data; + uint32_t size = current_number; + uint16_t crc = 0; + uint32_t i = 0; + for (i=0; i", 1); + } + } + else + { + if (('0' <= *ptr) && (*ptr <= '9')) + { + current_number = (current_number << 4) | (*ptr - '0'); + } + else if (('A' <= *ptr) && (*ptr <= 'F')) + { + current_number = (current_number << 4) | (*ptr - 'A' + 0xa); + } + else if (('a' <= *ptr) && (*ptr <= 'f')) + { + current_number = (current_number << 4) | (*ptr - 'a' + 0xa); + } + else if (*ptr == ',') + { + ptr_data = (uint8_t *) current_number; + current_number = 0; + } + else + { + command = *ptr; + current_number = 0; + } + } + } +} + +void sam_ba_monitor_sys_tick(void) +{ + /* Check whether the TX or RX LED one-shot period has elapsed. if so, turn off the LED */ + if (txLEDPulse && !(--txLEDPulse)) + LEDTX_off(); + if (rxLEDPulse && !(--rxLEDPulse)) + LEDRX_off(); +} + +/** + * \brief This function starts the SAM-BA monitor. + */ +void sam_ba_monitor_run(void) +{ + uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 }; + PAGE_SIZE = pageSizes[NVMCTRL->PARAM.bit.PSZ]; + PAGES = NVMCTRL->PARAM.bit.NVMP; + MAX_FLASH = PAGE_SIZE * PAGES; + + ptr_data = NULL; + command = 'z'; + while (1) + { + sam_ba_monitor_loop(); + } +} diff --git a/bootloaders/metroM4/sam_ba_monitor.h b/bootloaders/metroM4/sam_ba_monitor.h new file mode 100644 index 000000000..6cfa4db03 --- /dev/null +++ b/bootloaders/metroM4/sam_ba_monitor.h @@ -0,0 +1,72 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _MONITOR_SAM_BA_H_ +#define _MONITOR_SAM_BA_H_ + +#define SAM_BA_VERSION "2.0" + +/* Enable the interfaces to save code size */ +#define SAM_BA_BOTH_INTERFACES 0 +#define SAM_BA_UART_ONLY 1 +#define SAM_BA_USBCDC_ONLY 2 + +#ifndef SAM_BA_INTERFACE +#define SAM_BA_INTERFACE SAM_BA_BOTH_INTERFACES +#endif + +/* Selects USB as the communication interface of the monitor */ +#define SAM_BA_INTERFACE_USBCDC 0 +/* Selects USART as the communication interface of the monitor */ +#define SAM_BA_INTERFACE_USART 1 + +/* Selects USB as the communication interface of the monitor */ +#define SIZEBUFMAX 64 + +/** + * \brief Initialize the monitor + * + */ +void sam_ba_monitor_init(uint8_t com_interface); + +/** + * \brief System tick function of the SAM-BA Monitor + * + */ +void sam_ba_monitor_sys_tick(void); + +/** + * \brief Main function of the SAM-BA Monitor + * + */ +void sam_ba_monitor_run(void); + +/** + * \brief + * + */ +void sam_ba_putdata_term(uint8_t* data, uint32_t length); + +/** + * \brief + * + */ +void call_applet(uint32_t address); + +#endif // _MONITOR_SAM_BA_H_ diff --git a/bootloaders/metroM4/sam_ba_serial.c b/bootloaders/metroM4/sam_ba_serial.c new file mode 100644 index 000000000..6b02b2850 --- /dev/null +++ b/bootloaders/metroM4/sam_ba_serial.c @@ -0,0 +1,529 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include "board_definitions.h" +#include "sam_ba_serial.h" +#include "board_driver_serial.h" + +/* Local reference to current Usart instance in use with this driver */ +//struct usart_module usart_sam_ba; + +/* Variable to let the main task select the appropriate communication interface */ +volatile uint8_t b_sharp_received; + +/* RX and TX Buffers + rw pointers for each buffer */ +volatile uint8_t buffer_rx_usart[USART_BUFFER_SIZE]; + +volatile uint8_t idx_rx_read; +volatile uint8_t idx_rx_write; + +volatile uint8_t buffer_tx_usart[USART_BUFFER_SIZE]; + +volatile uint8_t idx_tx_read; +volatile uint8_t idx_tx_write; + +/* Test for timeout in AT91F_GetChar */ +uint8_t error_timeout; +uint16_t size_of_data; +uint8_t mode_of_transfer; + +#define BOOT_USART_PAD(n) BOOT_USART_PAD##n + +#define GPIO_PIN(n) (((n)&0x1Fu) << 0) +#define GPIO_PORT(n) ((n) >> 5) + +/** + * \brief Open the given USART + */ +void serial_open(void) +{ + uint32_t port; + uint32_t pin; + + GCLK->PCHCTRL[BOOT_GCLK_ID_CORE].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + GCLK->PCHCTRL[BOOT_GCLK_ID_SLOW].reg = GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + + MCLK->BOOK_USART_MASK.reg |= BOOT_USART_BUS_CLOCK_INDEX ; + + /* Configure the port pins for SERCOM_USART */ + if (BOOT_USART_PAD0 != PINMUX_UNUSED) + { + /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ + port = (BOOT_USART_PAD0 & 0x200000) >> 21; + pin = (BOOT_USART_PAD0 >> 16); + PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; + PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); + PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD0 & 0xFF) << (4 * (pin & 0x01u)); + } + + if (BOOT_USART_PAD1 != PINMUX_UNUSED) + { + /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ + port = (BOOT_USART_PAD1 & 0x200000) >> 21; + pin = BOOT_USART_PAD1 >> 16; + PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; + PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); + PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD1 & 0xFF) << (4 * (pin & 0x01u)); + } + + if (BOOT_USART_PAD2 != PINMUX_UNUSED) + { + /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ + port = (BOOT_USART_PAD2 & 0x200000) >> 21; + pin = BOOT_USART_PAD2 >> 16; + PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; + PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); + PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD2 & 0xFF) << (4 * (pin & 0x01u)); + } + + if (BOOT_USART_PAD3 != PINMUX_UNUSED) + { + /* Mask 6th bit in pin number to check whether it is greater than 32 i.e., PORTB pin */ + port = (BOOT_USART_PAD3 & 0x200000) >> 21; + pin = BOOT_USART_PAD3 >> 16; + PORT->Group[port].PINCFG[(pin - (port*32))].bit.PMUXEN = 1; + PORT->Group[port].PMUX[(pin - (port*32))/2].reg &= ~(0xF << (4 * (pin & 0x01u))); + PORT->Group[port].PMUX[(pin - (port*32))/2].reg |= (BOOT_USART_PAD3 & 0xFF) << (4 * (pin & 0x01u)); + } + + /* Baud rate 115200 - clock 48MHz -> BAUD value-63018 */ + uart_basic_init(BOOT_USART_MODULE, 63018, BOOT_USART_PAD_SETTINGS); + + //Initialize flag + b_sharp_received = false; + idx_rx_read = 0; + idx_rx_write = 0; + idx_tx_read = 0; + idx_tx_write = 0; + + error_timeout = 0; +} + +/** + * \brief Close communication line + */ +void serial_close(void) +{ + uart_disable(BOOT_USART_MODULE); +} + +/** + * \brief Puts a byte on usart line + * The type int is used to support printf redirection from compiler LIB. + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int serial_putc(int value) +{ + uart_write_byte(BOOT_USART_MODULE, (uint8_t)value); + return 1; +} + +int serial_getc(void) +{ + uint16_t retval; + //Wait until input buffer is filled + while(!(serial_is_rx_ready())); + retval = (uint16_t)uart_read_byte(BOOT_USART_MODULE); + //usart_read_wait(&usart_sam_ba, &retval); + return (int)retval; + +} + +int serial_sharp_received(void) +{ + if (serial_is_rx_ready()) + { + if (serial_getc() == SHARP_CHARACTER) + return (true); + } + return (false); +} + +bool serial_is_rx_ready(void) +{ + return (BOOT_USART_MODULE->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_RXC); +} + +int serial_readc(void) +{ + int retval; + retval = buffer_rx_usart[idx_rx_read]; + idx_rx_read = (idx_rx_read + 1) & (USART_BUFFER_SIZE - 1); + return (retval); +} + +//Send given data (polling) +uint32_t serial_putdata(void const* data, uint32_t length) +{ + uint32_t i; + uint8_t* ptrdata; + ptrdata = (uint8_t*) data; + for (i = 0; i < length; i++) + { + serial_putc(*ptrdata); + ptrdata++; + } + return (i); +} + +//Get data from comm. device +uint32_t serial_getdata(void* data, uint32_t length) +{ + uint8_t* ptrdata; + ptrdata = (uint8_t*) data; + *ptrdata = serial_getc(); + return (1); +} + +static const uint16_t crc16Table[256]= +{ + 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, + 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, + 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, + 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, + 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, + 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, + 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, + 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, + 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, + 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, + 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, + 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, + 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, + 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, + 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, + 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, + 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, + 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, + 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, + 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, + 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, + 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, + 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, + 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, + 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, + 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, + 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, + 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, + 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, + 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, + 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, + 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 +}; + +//*---------------------------------------------------------------------------- +//* \brief Compute the CRC +//*---------------------------------------------------------------------------- +unsigned short serial_add_crc(char ptr, unsigned short crc) +{ + return (crc << 8) ^ crc16Table[((crc >> 8) ^ ptr) & 0xff]; +} + +//*---------------------------------------------------------------------------- +//* \brief +//*---------------------------------------------------------------------------- +static uint16_t getbytes(uint8_t *ptr_data, uint16_t length) +{ + uint16_t crc = 0; + uint16_t cpt; + uint8_t c; + + for (cpt = 0; cpt < length; ++cpt) + { + c = serial_getc(); + if (error_timeout) + return 1; + crc = serial_add_crc(c, crc); + //crc = (crc << 8) ^ xcrc16tab[(crc>>8) ^ c]; + if (size_of_data || mode_of_transfer) + { + *ptr_data++ = c; + if (length == PKTLEN_128) + size_of_data--; + } + } + + return crc; +} + +//*---------------------------------------------------------------------------- +//* \brief Used by Xup to send packets. +//*---------------------------------------------------------------------------- +static int putPacket(uint8_t *tmppkt, uint8_t sno) +{ + uint32_t i; + uint16_t chksm; + uint8_t data; + + chksm = 0; + + serial_putc(SOH); + + serial_putc(sno); + serial_putc((uint8_t) ~(sno)); + + for (i = 0; i < PKTLEN_128; i++) + { + if (size_of_data || mode_of_transfer) + { + data = *tmppkt++; + size_of_data--; + } + else + data = 0x00; + + serial_putc(data); + + //chksm = (chksm<<8) ^ xcrc16tab[(chksm>>8)^data]; + chksm = serial_add_crc(data, chksm); + } + + /* An "endian independent way to extract the CRC bytes. */ + serial_putc((uint8_t) (chksm >> 8)); + serial_putc((uint8_t) chksm); + + return (serial_getc()); /* Wait for ack */ +} + +//*---------------------------------------------------------------------------- +//* \brief Called when a transfer from target to host is being made (considered +//* an upload). +//*---------------------------------------------------------------------------- +//Send given data (polling) using xmodem (if necessary) +uint32_t serial_putdata_xmd(void const* data, uint32_t length) +{ + uint8_t c, sno = 1; + uint8_t done; + uint8_t * ptr_data = (uint8_t *) data; + error_timeout = 0; + if (!length) + mode_of_transfer = 1; + else + { + size_of_data = length; + mode_of_transfer = 0; + } + + if (length & (PKTLEN_128 - 1)) + { + length += PKTLEN_128; + length &= ~(PKTLEN_128 - 1); + } + + /* Startup synchronization... */ + /* Wait to receive a NAK or 'C' from receiver. */ + done = 0; + while (!done) { + c = (uint8_t) serial_getc(); + if (error_timeout) + { // Test for timeout in serial_getc + error_timeout = 0; + c = (uint8_t) serial_getc(); + if (error_timeout) + { + error_timeout = 0; + return (0); + } + } + switch (c) + { + case NAK: + done = 1; + // ("CSM"); + break; + case 'C': + done = 1; + // ("CRC"); + break; + case 'q': /* ELS addition, not part of XMODEM spec. */ + return (0); + default: + break; + } + } + + done = 0; + sno = 1; + while (!done) + { + c = (uint8_t) putPacket((uint8_t *) ptr_data, sno); + if (error_timeout) + { // Test for timeout in serial_getc + error_timeout = 0; + return (0); + } + switch (c) + { + case ACK: + ++sno; + length -= PKTLEN_128; + ptr_data += PKTLEN_128; + // ("A"); + break; + + case NAK: + // ("N"); + break; + + case CAN: + case EOT: + default: + done = 0; + break; + } + + if (!length) + { + serial_putc(EOT); + serial_getc(); /* Flush the ACK */ + break; + } + // ("!"); + } + + mode_of_transfer = 0; + // ("Xup_done."); + return (1); + // return(0); +} + +/*---------------------------------------------------------------------------- + * \brief Used by serial_getdata_xmd to retrieve packets. + */ +static uint8_t getPacket(uint8_t *ptr_data, uint8_t sno) +{ + uint8_t seq[2]; + uint16_t crc, xcrc; + + getbytes(seq, 2); + xcrc = getbytes(ptr_data, PKTLEN_128); + if (error_timeout) + return (false); + + /* An "endian independent way to combine the CRC bytes. */ + crc = (uint16_t) serial_getc() << 8; + crc += (uint16_t) serial_getc(); + + if (error_timeout == 1) + return (false); + + if ((crc != xcrc) || (seq[0] != sno) || (seq[1] != (uint8_t) (~sno))) + { + serial_putc(CAN); + return (false); + } + + serial_putc(ACK); + return (true); +} + +//*---------------------------------------------------------------------------- +//* \brief Called when a transfer from host to target is being made (considered +//* an download). +//*---------------------------------------------------------------------------- +//Get data from comm. device using xmodem (if necessary) +uint32_t serial_getdata_xmd(void* data, uint32_t length) +{ + uint32_t timeout; + char c; + uint8_t * ptr_data = (uint8_t *) data; + uint32_t b_run, nbr_of_timeout = 100; + uint8_t sno = 0x01; + uint32_t data_transfered = 0; + + //Copied from legacy source code ... might need some tweaking + uint32_t loops_per_second = CPU_FREQUENCY/60; + + error_timeout = 0; + + if (length == 0) + mode_of_transfer = 1; + else + { + size_of_data = length; + mode_of_transfer = 0; + } + + /* Startup synchronization... */ + /* Continuously send NAK or 'C' until sender responds. */ + // ("Xdown"); + while (1) + { + serial_putc('C'); + timeout = loops_per_second; + while (!(serial_is_rx_ready()) && timeout) + timeout--; + if (timeout) + break; + + if (!(--nbr_of_timeout)) + return (0); +// return -1; + } + + b_run = true; + // ("Got response"); + while (b_run != false) + { + c = (char) serial_getc(); + if (error_timeout) + { // Test for timeout in serial_getc + error_timeout = 0; + return (0); +// return (-1); + } + switch (c) + { + case SOH: /* 128-byte incoming packet */ + // ("O"); + b_run = getPacket(ptr_data, sno); + if (error_timeout) + { // Test for timeout in serial_getc + error_timeout = 0; + return (0); + // return (-1); + } + if (b_run == true) + { + ++sno; + ptr_data += PKTLEN_128; + data_transfered += PKTLEN_128; + } + break; + case EOT: // ("E"); + serial_putc(ACK); + b_run = false; + break; + case CAN: // ("C"); + case ESC: /* "X" User-invoked abort */ + default: + b_run = false; + break; + } + // ("!"); + } + mode_of_transfer = 0; + return (true); +// return(b_run); +} + diff --git a/bootloaders/metroM4/sam_ba_serial.h b/bootloaders/metroM4/sam_ba_serial.h new file mode 100644 index 000000000..cb69f459e --- /dev/null +++ b/bootloaders/metroM4/sam_ba_serial.h @@ -0,0 +1,143 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef _SAM_BA_SERIAL_H_ +#define _SAM_BA_SERIAL_H_ + +#include +#include + + +/* USART buffer size (must be a power of two) */ +#define USART_BUFFER_SIZE (128) + +/* Define the default time-out value for USART. */ +#define USART_DEFAULT_TIMEOUT (1000) + +/* Xmodem related defines */ +/* CRC16 polynomial */ +#define CRC16POLY (0x1021) + +#define SHARP_CHARACTER '#' + +/* X/Ymodem protocol: */ +#define SOH (0x01) +//#define STX (0x02) +#define EOT (0x04) +#define ACK (0x06) +#define NAK (0x15) +#define CAN (0x18) +#define ESC (0x1b) + +#define PKTLEN_128 (128) + + +/** + * \brief Open the given USART + */ +void serial_open(void); + +/** + * \brief Stops the USART + */ +void serial_close(void); + +/** + * \brief Puts a byte on usart line + * + * \param value Value to put + * + * \return \c 1 if function was successfully done, otherwise \c 0. + */ +int serial_putc(int value); + +/** + * \brief Waits and gets a value on usart line + * + * \return value read on usart line + */ +int serial_getc(void); + +/** + * \brief Returns true if the SAM-BA Uart received the sharp char + * + * \return Returns true if the SAM-BA Uart received the sharp char + */ +int serial_sharp_received(void); + +/** + * \brief This function checks if a character has been received on the usart line + * + * \return \c 1 if a byte is ready to be read. + */ +bool serial_is_rx_ready(void); + +/** + * \brief Gets a value on usart line + * + * \return value read on usart line + */ +int serial_readc(void); + +/** + * \brief Send buffer on usart line + * + * \param data pointer + * \param number of data to send + * \return number of data sent + */ +uint32_t serial_putdata(void const* data, uint32_t length); //Send given data (polling) + +/** + * \brief Gets data from usart line + * + * \param data pointer + * \param number of data to get + * \return value read on usart line + */ +uint32_t serial_getdata(void* data, uint32_t length); //Get data from comm. device + +/** + * \brief Send buffer on usart line using Xmodem protocol + * + * \param data pointer + * \param number of data to send + * \return number of data sent + */ +uint32_t serial_putdata_xmd(void const* data, uint32_t length); //Send given data (polling) using xmodem (if necessary) + +/** + * \brief Gets data from usart line using Xmodem protocol + * + * \param data pointer + * \param number of data to get + * \return value read on usart line + */ +uint32_t serial_getdata_xmd(void* data, uint32_t length); //Get data from comm. device using xmodem (if necessary) + +/** + * \brief Compute the CRC + * + * \param Char to add to CRC + * \param Previous CRC + * \return The new computed CRC + */ +unsigned short serial_add_crc(char c, unsigned short crc); + +#endif // _SAM_BA_SERIAL_H_ diff --git a/bootloaders/metroM4/sam_ba_usb.c b/bootloaders/metroM4/sam_ba_usb.c new file mode 100644 index 000000000..068b81d8b --- /dev/null +++ b/bootloaders/metroM4/sam_ba_usb.c @@ -0,0 +1,436 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#include +#include +#include "board_definitions.h" +#include "sam_ba_usb.h" +#include "board_driver_usb.h" +#include "sam_ba_cdc.h" + +/* This data array will be copied into SRAM as its length is inferior to 64 bytes, + * and so can stay in flash. + */ +static __attribute__((__aligned__(4))) +const char devDescriptor[] = +{ + /* Device descriptor */ + 0x12, // bLength + 0x01, // bDescriptorType + 0x00, // bcdUSB L + 0x02, // bcdUSB H + 0x02, // bDeviceClass: CDC class code + 0x00, // bDeviceSubclass: CDC class sub code + 0x00, // bDeviceProtocol: CDC Device protocol + 0x40, // bMaxPacketSize0 + USB_VID_LOW, // idVendor L + USB_VID_HIGH, // idVendor H + USB_PID_LOW, // idProduct L + USB_PID_HIGH, // idProduct H + 0x00, // bcdDevice L, here matching SAM-BA version + 0x02, // bcdDevice H + STRING_INDEX_MANUFACTURER, // iManufacturer + STRING_INDEX_PRODUCT, // iProduct + 0x00, // SerialNumber, should be based on product unique ID + 0x01 // bNumConfigs +}; + +/* This data array will be consumed directly by USB_Write() and must be in SRAM. + * We cannot send data from product internal flash. + */ +static __attribute__((__aligned__(4))) +char cfgDescriptor[] = +{ + /* ============== CONFIGURATION 1 =========== */ + /* Configuration 1 descriptor */ + 0x09, // CbLength + 0x02, // CbDescriptorType + 0x43, // CwTotalLength 2 EP + Control + 0x00, + 0x02, // CbNumInterfaces + 0x01, // CbConfigurationValue + 0x00, // CiConfiguration + 0x80, // CbmAttributes Bus powered without remote wakeup: 0x80, Self powered without remote wakeup: 0xc0 + 0x32, // CMaxPower, report using 100mA, enough for a bootloader + + /* Communication Class Interface Descriptor Requirement */ + 0x09, // bLength + 0x04, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x01, // bNumEndpoints + 0x02, // bInterfaceClass + 0x02, // bInterfaceSubclass + 0x00, // bInterfaceProtocol + 0x00, // iInterface + + /* Header Functional Descriptor */ + 0x05, // bFunction Length + 0x24, // bDescriptor type: CS_INTERFACE + 0x00, // bDescriptor subtype: Header Func Desc + 0x10, // bcdCDC:1.1 + 0x01, + + /* ACM Functional Descriptor */ + 0x04, // bFunctionLength + 0x24, // bDescriptor Type: CS_INTERFACE + 0x02, // bDescriptor Subtype: ACM Func Desc + 0x00, // bmCapabilities + + /* Union Functional Descriptor */ + 0x05, // bFunctionLength + 0x24, // bDescriptorType: CS_INTERFACE + 0x06, // bDescriptor Subtype: Union Func Desc + 0x00, // bMasterInterface: Communication Class Interface + 0x01, // bSlaveInterface0: Data Class Interface + + /* Call Management Functional Descriptor */ + 0x05, // bFunctionLength + 0x24, // bDescriptor Type: CS_INTERFACE + 0x01, // bDescriptor Subtype: Call Management Func Desc + 0x00, // bmCapabilities: D1 + D0 + 0x01, // bDataInterface: Data Class Interface 1 + + /* Endpoint 1 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x83, // bEndpointAddress, Endpoint 03 - IN + 0x03, // bmAttributes INT + 0x08, // wMaxPacketSize + 0x00, + 0xFF, // bInterval + + /* Data Class Interface Descriptor Requirement */ + 0x09, // bLength + 0x04, // bDescriptorType + 0x01, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0x0A, // bInterfaceClass + 0x00, // bInterfaceSubclass + 0x00, // bInterfaceProtocol + 0x00, // iInterface + + /* First alternate setting */ + /* Endpoint 1 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x81, // bEndpointAddress, Endpoint 01 - IN + 0x02, // bmAttributes BULK + USB_EP_IN_SIZE, // wMaxPacketSize + 0x00, + 0x00, // bInterval + + /* Endpoint 2 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x02, // bEndpointAddress, Endpoint 02 - OUT + 0x02, // bmAttributes BULK + USB_EP_OUT_SIZE, // wMaxPacketSize + 0x00, + 0x00 // bInterval +}; + +#ifndef STRING_MANUFACTURER +# define STRING_MANUFACTURER "Arduino LLC" +#endif + +#ifndef STRING_PRODUCT +# define STRING_PRODUCT "Arduino Zero" +#endif + +USB_CDC sam_ba_cdc; + +/*---------------------------------------------------------------------------- + * \brief This function is a callback invoked when a SETUP packet is received + */ +void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) +{ + Usb *pUsb = pCdc->pUsb; + static volatile uint8_t bmRequestType, bRequest, dir; + static volatile uint16_t wValue, wIndex, wLength, wStatus; + + /* Clear the Received Setup flag */ + pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; + + /* Read the USB request parameters */ + bmRequestType = udd_ep_out_cache_buffer[0][0]; + bRequest = udd_ep_out_cache_buffer[0][1]; + wValue = (udd_ep_out_cache_buffer[0][2] & 0xFF); + wValue |= (udd_ep_out_cache_buffer[0][3] << 8); + wIndex = (udd_ep_out_cache_buffer[0][4] & 0xFF); + wIndex |= (udd_ep_out_cache_buffer[0][5] << 8); + wLength = (udd_ep_out_cache_buffer[0][6] & 0xFF); + wLength |= (udd_ep_out_cache_buffer[0][7] << 8); + + /* Clear the Bank 0 ready flag on Control OUT */ + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; + + /* Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 */ + switch ((bRequest << 8) | bmRequestType) + { + case STD_GET_DESCRIPTOR: + if (wValue>>8 == STD_GET_DESCRIPTOR_DEVICE) + { + /* Return Device Descriptor */ + USB_Write(pCdc->pUsb, devDescriptor, SAM_BA_MIN(sizeof(devDescriptor), wLength), USB_EP_CTRL); + } + else if (wValue>>8 == STD_GET_DESCRIPTOR_CONFIGURATION) + { + /* Return Configuration Descriptor */ + USB_Write(pCdc->pUsb, cfgDescriptor, SAM_BA_MIN(sizeof(cfgDescriptor), wLength), USB_EP_CTRL); + } + else if (wValue>>8 == STD_GET_DESCRIPTOR_STRING) + { + switch ( wValue & 0xff ) + { + case STRING_INDEX_LANGUAGES: { + uint16_t STRING_LANGUAGE[2] = { (STD_GET_DESCRIPTOR_STRING<<8) | 4, 0x0409 }; + + USB_Write(pCdc->pUsb, (const char*)STRING_LANGUAGE, SAM_BA_MIN(sizeof(STRING_LANGUAGE), wLength), USB_EP_CTRL); + } + break; + + case STRING_INDEX_MANUFACTURER: + USB_SendString(pCdc->pUsb, STRING_MANUFACTURER, wLength ); + break; + + case STRING_INDEX_PRODUCT: + USB_SendString(pCdc->pUsb, STRING_PRODUCT, wLength ); + break; + default: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + } + } + else + { + /* Stall the request */ + USB_SendStall(pUsb, true); + } + break; + + case STD_SET_ADDRESS: + /* Send ZLP */ + USB_SendZlp(pUsb); + /* Set device address to the newly received address from host */ + USB_SetAddress(pCdc->pUsb, wValue); + break; + + case STD_SET_CONFIGURATION: + /* Store configuration */ + pCdc->currentConfiguration = (uint8_t)wValue; + + /* Send ZLP */ + USB_SendZlp(pUsb); + + /* Configure the 3 needed endpoints */ + USB_Configure(pUsb); + break; + + case STD_GET_CONFIGURATION: + /* Return current configuration value */ + USB_Write(pCdc->pUsb, (char *) &(pCdc->currentConfiguration), sizeof(pCdc->currentConfiguration), USB_EP_CTRL); + break; + + case STD_GET_STATUS_ZERO: + wStatus = 0; + USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); + break; + + case STD_GET_STATUS_INTERFACE: + wStatus = 0; + USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); + break; + + case STD_GET_STATUS_ENDPOINT: + wStatus = 0; + dir = wIndex & 80; + wIndex &= 0x0F; + if (wIndex <= 3) + { + if (dir) + { + wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) ? 1 : 0; + } + else + { + wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) ? 1 : 0; + } + /* Return current status of endpoint */ + USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); + } + else + { + /* Stall the request */ + USB_SendStall(pUsb, true); + } + break; + + case STD_SET_FEATURE_ZERO: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + + case STD_SET_FEATURE_INTERFACE: + /* Send ZLP */ + USB_SendZlp(pUsb); + break; + + case STD_SET_FEATURE_ENDPOINT: + dir = wIndex & 0x80; + wIndex &= 0x0F; + if ((wValue == 0) && wIndex && (wIndex <= 3)) + { + /* Set STALL request for the endpoint */ + if (dir) + { + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; + } + else + { + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; + } + + /* Send ZLP */ + USB_SendZlp(pUsb); + } + else + { + /* Stall the request */ + USB_SendStall(pUsb, true); + } + break; + + case STD_SET_INTERFACE: + case STD_CLEAR_FEATURE_ZERO: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + + case STD_CLEAR_FEATURE_INTERFACE: + /* Send ZLP */ + USB_SendZlp(pUsb); + break; + + case STD_CLEAR_FEATURE_ENDPOINT: + dir = wIndex & 0x80; + wIndex &= 0x0F; + + if ((wValue == 0) && wIndex && (wIndex <= 3)) + { + if (dir) + { + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ1) + { + // Remove stall request + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL1) + { + pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1; + // The Stall has occurred, then reset data toggle + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN; + } + } + } + else + { + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ0) + { + // Remove stall request + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL0) + { + pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0; + // The Stall has occurred, then reset data toggle + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT; + } + } + } + /* Send ZLP */ + USB_SendZlp(pUsb); + } + else + { + USB_SendStall(pUsb, true); + } + break; + + // handle CDC class requests + case SET_LINE_CODING: + /* Send ZLP */ + USB_SendZlp(pUsb); + break; + + case GET_LINE_CODING: + /* Send current line coding */ + USB_Write(pCdc->pUsb, (char *) &line_coding, SAM_BA_MIN(sizeof(usb_cdc_line_coding_t), wLength), USB_EP_CTRL); + break; + + case SET_CONTROL_LINE_STATE: + /* Store the current connection */ + pCdc->currentConnection = wValue; + /* Send ZLP */ + USB_SendZlp(pUsb); + break; + + default: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + } +} + +/*---------------------------------------------------------------------------- + * \brief + */ +P_USB_CDC usb_init(void) +{ + sam_ba_cdc.pUsb = USB; + + /* Initialize USB */ + USB_Init(); + /* Get the default CDC structure settings */ + USB_Open(&sam_ba_cdc, sam_ba_cdc.pUsb); + + return &sam_ba_cdc; +} + +/*---------------------------------------------------------------------------- + * \brief Send a USB descriptor string. + * + * The input string is plain ASCII but is sent out as UTF-16 with the correct 2-byte prefix. + */ +uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t maxLength) +{ + uint8_t string_descriptor[255]; // Max USB-allowed string length + uint16_t* unicode_string=(uint16_t*)(string_descriptor+2); // point on 3 bytes of descriptor + int resulting_length; + + string_descriptor[0] = (strlen(ascii_string)<<1) + 2; + string_descriptor[1] = STD_GET_DESCRIPTOR_STRING; + + for ( resulting_length = 1 ; *ascii_string && (resulting_length>1) ; resulting_length++ ) + { + *unicode_string++ = (uint16_t)(*ascii_string++); + } + + return USB_Write(pUsb, (const char*)string_descriptor, resulting_length<<1, USB_EP_CTRL); +} diff --git a/bootloaders/metroM4/sam_ba_usb.h b/bootloaders/metroM4/sam_ba_usb.h new file mode 100644 index 000000000..457fdbc09 --- /dev/null +++ b/bootloaders/metroM4/sam_ba_usb.h @@ -0,0 +1,103 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + Copyright (c) 2015 Atmel Corporation/Thibaut VIARD. All right reserved. + + 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 +*/ + +#ifndef CDC_ENUMERATE_H +#define CDC_ENUMERATE_H + +#include +#include + +#define USB_EP_CTRL (0u) +#define USB_EP_OUT (2u) +#define USB_EP_OUT_SIZE (0x40u) +#define USB_EP_IN (1u) +#define USB_EP_IN_SIZE (0x40u) +#define USB_EP_COMM (3u) +#define MAX_EP (4u) + +/* USB standard request code */ +#define STD_GET_STATUS_ZERO (0x0080u) +#define STD_GET_STATUS_INTERFACE (0x0081u) +#define STD_GET_STATUS_ENDPOINT (0x0082u) + +#define STD_CLEAR_FEATURE_ZERO (0x0100u) +#define STD_CLEAR_FEATURE_INTERFACE (0x0101u) +#define STD_CLEAR_FEATURE_ENDPOINT (0x0102u) + +#define STD_SET_FEATURE_ZERO (0x0300u) +#define STD_SET_FEATURE_INTERFACE (0x0301u) +#define STD_SET_FEATURE_ENDPOINT (0x0302u) + +#define STD_SET_ADDRESS (0x0500u) +#define STD_GET_DESCRIPTOR (0x0680u) +#define STD_SET_DESCRIPTOR (0x0700u) +#define STD_GET_CONFIGURATION (0x0880u) +#define STD_SET_CONFIGURATION (0x0900u) +#define STD_GET_INTERFACE (0x0A81u) +#define STD_SET_INTERFACE (0x0B01u) +#define STD_SYNCH_FRAME (0x0C82u) + +#define STD_GET_DESCRIPTOR_DEVICE (1u) +#define STD_GET_DESCRIPTOR_CONFIGURATION (2u) +#define STD_GET_DESCRIPTOR_STRING (3u) +#define STD_GET_DESCRIPTOR_INTERFACE (4u) +#define STD_GET_DESCRIPTOR_ENDPOINT (5u) +#define STD_GET_DESCRIPTOR_DEVICE_QUALIFIER (6u) +#define STD_GET_DESCRIPTOR_OTHER_SPEED_CONFIGURATION (7u) +#define STD_GET_DESCRIPTOR_INTERFACE_POWER1 (8u) + +#define FEATURE_ENDPOINT_HALT (0u) +#define FEATURE_DEVICE_REMOTE_WAKEUP (1u) +#define FEATURE_TEST_MODE (2u) + +#define STRING_INDEX_LANGUAGES (0x00u) +#define STRING_INDEX_MANUFACTURER (0x01u) +#define STRING_INDEX_PRODUCT (0x02u) + +#define SAM_BA_MIN(a, b) (((a) < (b)) ? (a) : (b)) + + +typedef struct _USB_CDC +{ + // Private members + Usb *pUsb; + uint8_t currentConfiguration; + uint8_t currentConnection; + // Public Methods: + uint8_t (*IsConfigured)(struct _USB_CDC *pCdc); +// uint32_t (*Write) (Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num); +// uint32_t (*Read) (Usb *pUsb, char *pData, uint32_t length); +} USB_CDC, *P_USB_CDC; + +/** + * \brief Initializes the USB module + * + * \return Pointer to the USB CDC structure + */ +P_USB_CDC usb_init(void); + +void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc); + +uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t maxLength); + +extern USB_CDC sam_ba_cdc; + + + +#endif // CDC_ENUMERATE_H diff --git a/bootloaders/metroM4/samd51_sam_ba.componentinfo.xml b/bootloaders/metroM4/samd51_sam_ba.componentinfo.xml new file mode 100644 index 000000000..e27575522 --- /dev/null +++ b/bootloaders/metroM4/samd51_sam_ba.componentinfo.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/bootloaders/metroM4/samd51_sam_ba.cproj b/bootloaders/metroM4/samd51_sam_ba.cproj new file mode 100644 index 000000000..f5193cae1 --- /dev/null +++ b/bootloaders/metroM4/samd51_sam_ba.cproj @@ -0,0 +1,300 @@ + + + + 2.0 + 7.0 + com.Atmel.ARMGCC.C + dce6c7e3-ee26-4d79-826b-08594b9ad897 + ATSAMD51J19A + none + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + samd21_sam_ba + samd51_sam_ba + samd21_sam_ba + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + + + + + + + + + + + + + + com.atmel.avrdbg.tool.edbg + 00000000EZE000006352 + 0x60060005 + SWD + + + + 0 + + SWD + + com.atmel.avrdbg.tool.atmelice + J41800001895 + Atmel-ICE + + 2000000 + + + + 2000000 + + SWD + + com.atmel.avrdbg.tool.edbg + 00000000EZE000006352 + EDBG + + True + + + + + True + True + True + True + True + + + NDEBUG + + + Optimize for size (-Os) + True + True + + + libm + + + True + -Tsamd21j18a_flash.ld + + + + + + + True + True + True + True + True + + + DEBUG + + + Optimize (-O1) + True + Maximum (-g3) + True + + + libm + + + True + -Tsamd21j18a_flash.ld + Default (-g) + Default (-Wa,-g) + + + True + + DEBUG=1 all + clean + Makefile + + + + + True + True + True + True + True + + + DEBUG + + + Optimize (-O1) + True + Maximum (-g3) + True + + + libm + + + True + -Tsamd21j18a_flash.ld + Default (-g) + Default (-Wa,-g) + + + True + + DEBUG=1 all BOARD_ID=FEATHER_M4 BOARD_CHIP=__SAMD51G19A__ + clean BOARD_ID=FEATHER_M4 + Makefile + bin\featherm4\ + + + + + True + True + True + True + True + + + DEBUG + + + Optimize (-O1) + True + Maximum (-g3) + True + + + libm + + + True + -Tsamd21j18a_flash.ld + Default (-g) + Default (-Wa,-g) + + + True + + DEBUG=0 all BOARD_ID=METRO_M4 BOARD_CHIP=__SAMD51J19A__ + clean BOARD_ID=METRO_M4 + Makefile + bin\metrom4\ + METRO_M4_sam_ba + .elf + + + + compile + board_definitions.h + + + compile + + + compile + + + compile + board_driver_led.c + + + compile + board_driver_led.h + + + compile + board_driver_serial.c + + + compile + board_driver_serial.h + + + compile + board_driver_usb.c + + + compile + board_driver_usb.h + + + compile + board_init.c + + + compile + board_startup.c + + + compile + main.c + + + compile + sam_ba_cdc.c + + + compile + sam_ba_cdc.h + + + compile + sam_ba_monitor.c + + + compile + sam_ba_monitor.h + + + compile + sam_ba_serial.c + + + compile + sam_ba_serial.h + + + compile + sam_ba_usb.c + + + compile + sam_ba_usb.h + + + + + compile + + + compile + + + compile + Makefile + + + compile + README.md + + + + \ No newline at end of file diff --git a/bootloaders/metroM4/samdx1_sam_ba.atsln b/bootloaders/metroM4/samdx1_sam_ba.atsln new file mode 100644 index 000000000..1869bec4c --- /dev/null +++ b/bootloaders/metroM4/samdx1_sam_ba.atsln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Atmel Studio Solution File, Format Version 11.00 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "samd51_sam_ba", "samd51_sam_ba.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Release|ARM = Release|ARM + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.ActiveCfg = metrom4|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.Build.0 = metrom4|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.ActiveCfg = Release|ARM + {DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.Build.0 = Release|ARM + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/bootloaders/metroM4/update-bootloader-metro_m4-v2.0.0-adafruit.5.uf2 b/bootloaders/metroM4/update-bootloader-metro_m4-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..c817470a1 Binary files /dev/null and b/bootloaders/metroM4/update-bootloader-metro_m4-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/mkr1000/samd21_sam_ba_arduino_mkr1000.bin b/bootloaders/mkr1000/samd21_sam_ba_arduino_mkr1000.bin old mode 100755 new mode 100644 diff --git a/bootloaders/mkr1000/samd21_sam_ba_genuino_mkr1000.bin b/bootloaders/mkr1000/samd21_sam_ba_genuino_mkr1000.bin old mode 100755 new mode 100644 diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e15a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e15a.h index 374a532e8..89fe03db6 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e15a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e15a.h @@ -218,7 +218,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e16a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e16a.h index 06bc2012e..c9d769004 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e16a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e16a.h @@ -218,7 +218,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e17a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e17a.h index ab17fbe06..cd2768281 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e17a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e17a.h @@ -218,7 +218,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e18a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e18a.h index df36c1394..f0da13ef3 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e18a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21e18a.h @@ -218,7 +218,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g15a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g15a.h index c8b43b465..4b3d8407e 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g15a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g15a.h @@ -222,7 +222,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g16a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g16a.h index ee3957b73..fe4134f28 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g16a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g16a.h @@ -222,7 +222,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g17a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g17a.h index ca2edaf65..837d1eac0 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g17a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g17a.h @@ -222,7 +222,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g18a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g18a.h index db9b3aae9..79fcea154 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g18a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21g18a.h @@ -222,7 +222,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j15a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j15a.h index 65dd3f44b..81dbb9d48 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j15a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j15a.h @@ -226,7 +226,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j16a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j16a.h index 4606c9eba..9696f4766 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j16a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j16a.h @@ -226,7 +226,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j17a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j17a.h index 69393f6fb..50f0daa95 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j17a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j17a.h @@ -226,7 +226,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j18a.h b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j18a.h index 3f621f870..a8a34c543 100644 --- a/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j18a.h +++ b/bootloaders/mzero/Bootloader_D21/src/ASF/sam0/utils/cmsis/samd21/include/samd21j18a.h @@ -226,7 +226,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/neokeytrinkey_m0/bootloader-neokeytrinkey_m0.bin b/bootloaders/neokeytrinkey_m0/bootloader-neokeytrinkey_m0.bin new file mode 100644 index 000000000..ea8af4d4e Binary files /dev/null and b/bootloaders/neokeytrinkey_m0/bootloader-neokeytrinkey_m0.bin differ diff --git a/bootloaders/neotrinkey_m0/bootloader-neotrinkey_m0.bin b/bootloaders/neotrinkey_m0/bootloader-neotrinkey_m0.bin new file mode 100644 index 000000000..faf74ac7d Binary files /dev/null and b/bootloaders/neotrinkey_m0/bootloader-neotrinkey_m0.bin differ diff --git a/bootloaders/pirky/bootloader-pirkey-v2.0.0-adafruit.5.bin b/bootloaders/pirky/bootloader-pirkey-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..635b684bf Binary files /dev/null and b/bootloaders/pirky/bootloader-pirkey-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/pirky/bootloader-pirkey-v2.0.0-adafruit.5.elf b/bootloaders/pirky/bootloader-pirkey-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..7b52cad5a Binary files /dev/null and b/bootloaders/pirky/bootloader-pirkey-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/pirky/update-bootloader-pirkey-v2.0.0-adafruit.5.uf2 b/bootloaders/pirky/update-bootloader-pirkey-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..19c38eb2e Binary files /dev/null and b/bootloaders/pirky/update-bootloader-pirkey-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/proxlighttrinkey_m0/bootloader-proxlighttrinkey_m0.bin b/bootloaders/proxlighttrinkey_m0/bootloader-proxlighttrinkey_m0.bin new file mode 100644 index 000000000..7b1a0b938 Binary files /dev/null and b/bootloaders/proxlighttrinkey_m0/bootloader-proxlighttrinkey_m0.bin differ diff --git a/bootloaders/qtpyM0/bootloader-qtpy_m0.bin b/bootloaders/qtpyM0/bootloader-qtpy_m0.bin new file mode 100644 index 000000000..930069d6c Binary files /dev/null and b/bootloaders/qtpyM0/bootloader-qtpy_m0.bin differ diff --git a/bootloaders/rotarytrinkey_m0/bootloader-rotarytrinkey_m0.bin b/bootloaders/rotarytrinkey_m0/bootloader-rotarytrinkey_m0.bin new file mode 100644 index 000000000..b879d7ef8 Binary files /dev/null and b/bootloaders/rotarytrinkey_m0/bootloader-rotarytrinkey_m0.bin differ diff --git a/bootloaders/slidetrinkey_m0/bootloader-slidetrinkey_m0.bin b/bootloaders/slidetrinkey_m0/bootloader-slidetrinkey_m0.bin new file mode 100644 index 000000000..e894a13e3 Binary files /dev/null and b/bootloaders/slidetrinkey_m0/bootloader-slidetrinkey_m0.bin differ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/.DS_Store b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/.DS_Store deleted file mode 100755 index d1231f515..000000000 Binary files a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/.DS_Store and /dev/null differ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/.DS_Store b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/.DS_Store deleted file mode 100755 index 5008ddfcf..000000000 Binary files a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/.DS_Store and /dev/null differ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e15a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e15a.h index 5eeb32a81..92c3c952f 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e15a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e15a.h @@ -218,7 +218,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e16a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e16a.h index 1732fe899..7544772c3 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e16a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e16a.h @@ -218,7 +218,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e17a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e17a.h index bad36c60f..985a53228 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e17a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e17a.h @@ -218,7 +218,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e18a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e18a.h index 839706689..1d668f82d 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e18a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21e18a.h @@ -218,7 +218,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g15a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g15a.h index fbc1116eb..37eef1c48 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g15a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g15a.h @@ -222,7 +222,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g16a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g16a.h index d8aa2460f..74240e3ca 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g16a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g16a.h @@ -222,7 +222,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g17a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g17a.h index 0cad9c7fe..44cd3d6ff 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g17a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g17a.h @@ -222,7 +222,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g18a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g18a.h index 76273e118..b7b0d2b59 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g18a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21g18a.h @@ -222,7 +222,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j15a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j15a.h index a3f771ecc..ea4c601eb 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j15a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j15a.h @@ -226,7 +226,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j16a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j16a.h index eaa2ec1d2..c510e92c4 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j16a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j16a.h @@ -226,7 +226,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j17a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j17a.h index 5e956b9ae..8e07a4caf 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j17a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j17a.h @@ -226,7 +226,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j18a.h b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j18a.h index 1a1d7e8bd..b32987a06 100755 --- a/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j18a.h +++ b/bootloaders/sofia/Bootloader_D21_Sofia_V2.1/src/ASF/sam0/utils/cmsis/samd21/include/samd21j18a.h @@ -226,7 +226,11 @@ void I2S_Handler ( void ); * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals */ -#define LITTLE_ENDIAN 1 +#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1) + #error "Little Endian is already defined, but to different value than expected?!" +#else + #define LITTLE_ENDIAN 1 +#endif #define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ #define __MPU_PRESENT 0 /*!< MPU present or not */ #define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ diff --git a/bootloaders/trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.bin b/bootloaders/trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.bin new file mode 100755 index 000000000..418928a21 Binary files /dev/null and b/bootloaders/trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.bin differ diff --git a/bootloaders/trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.elf b/bootloaders/trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.elf new file mode 100755 index 000000000..9e81cae0d Binary files /dev/null and b/bootloaders/trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.elf differ diff --git a/bootloaders/trinketm0/update-bootloader-trinket_m0-v2.0.0-adafruit.5.uf2 b/bootloaders/trinketm0/update-bootloader-trinket_m0-v2.0.0-adafruit.5.uf2 new file mode 100644 index 000000000..0c1e589d8 Binary files /dev/null and b/bootloaders/trinketm0/update-bootloader-trinket_m0-v2.0.0-adafruit.5.uf2 differ diff --git a/bootloaders/zero/Makefile b/bootloaders/zero/Makefile index 1e5fad5e5..eee929188 100644 --- a/bootloaders/zero/Makefile +++ b/bootloaders/zero/Makefile @@ -18,34 +18,44 @@ # ----------------------------------------------------------------------------- # Paths ifeq ($(OS),Windows_NT) + # Are we using mingw/msys/msys2/cygwin? ifeq ($(TERM),xterm) - T=$(shell cygpath -u $(LOCALAPPDATA)) +# this is the path coming with night build +# T=$(shell cygpath -u $(LOCALAPPDATA)) +# this is the path till 1.6.5 r5 + T=$(shell cygpath -u $(APPDATA)) MODULE_PATH?=$(T)/Arduino15/packages/arduino + ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- RM=rm SEP=/ else - MODULE_PATH?=$(LOCALAPPDATA)/Arduino15/packages/arduino +# this is the path coming with night build +# MODULE_PATH?=$(LOCALAPPDATA)/Arduino15/packages/arduino +# this is the path till 1.6.5 r5 + MODULE_PATH?=$(APPDATA)/Arduino15/packages/arduino + ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- RM=rm SEP=\\ endif else - UNAME_S := $(shell uname -s) - - ifeq ($(UNAME_S),Linux) - MODULE_PATH?=$(HOME)/.arduino15/packages/arduino - RM=rm - SEP=/ - endif - - ifeq ($(UNAME_S),Darwin) - MODULE_PATH?=$(HOME)/Library/Arduino15/packages/arduino/ - RM=rm - SEP=/ - endif + UNAME_S := $(shell uname -s) + + ifeq ($(UNAME_S),Linux) + MODULE_PATH?=$(HOME)/.arduino15/packages/arduino + ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- + RM=rm + SEP=/ + endif + + ifeq ($(UNAME_S),Darwin) + MODULE_PATH?=$(HOME)/Library/Arduino15/packages/arduino/ + ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- + RM=rm + SEP=/ + endif endif -ARM_GCC_PATH?=$(MODULE_PATH)/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi- BUILD_PATH=build # ----------------------------------------------------------------------------- @@ -55,27 +65,21 @@ OBJCOPY=$(ARM_GCC_PATH)objcopy NM=$(ARM_GCC_PATH)nm SIZE=$(ARM_GCC_PATH)size -# ----------------------------------------------------------------------------- -# Boards definitions -BOARD_ID?=arduino_zero -NAME?=samd21_sam_ba - # ----------------------------------------------------------------------------- # Compiler options -CFLAGS_EXTRA=-D__SAMD21G18A__ -DBOARD_ID_$(BOARD_ID) CFLAGS=-mthumb -mcpu=cortex-m0plus -Wall -c -std=gnu99 -ffunction-sections -fdata-sections -nostdlib -nostartfiles --param max-inline-insns-single=500 ifdef DEBUG - CFLAGS+=-g3 -O1 -DDEBUG=1 +CFLAGS+=-g3 -O1 -DDEBUG=1 else - CFLAGS+=-Os -DDEBUG=0 +CFLAGS+=-Os -DDEBUG=0 endif -ELF=$(NAME).elf -BIN=$(NAME).bin -HEX=$(NAME).hex - +# Arduino Zero (PID == 0x004D) +CFLAGS_EXTRA?=-D__SAMD21G18A__ -DUSB_PID_HIGH=0x00 -DUSB_PID_LOW=0x4D +# Genuino Zero (PID == 0x024D) +# CFLAGS_EXTRA?=-D__SAMD21G18A__ -DUSB_PID_HIGH=0x02 -DUSB_PID_LOW=0x4D -INCLUDES=-I"$(MODULE_PATH)/tools/CMSIS/4.5.0/CMSIS/Include/" -I"$(MODULE_PATH)/tools/CMSIS-Atmel/1.1.0/CMSIS/Device/ATMEL/" +INCLUDES=-I"$(MODULE_PATH)/tools/CMSIS/4.0.0-atmel/CMSIS/Include/" -I"$(MODULE_PATH)/tools/CMSIS/4.0.0-atmel/Device/ATMEL/" # ----------------------------------------------------------------------------- # Linker options @@ -85,38 +89,40 @@ LDFLAGS+=-Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbol # ----------------------------------------------------------------------------- # Source files and objects SOURCES= \ - board_driver_i2c.c \ - board_driver_led.c \ - board_driver_pmic.c \ - board_driver_serial.c \ - board_driver_usb.c \ - board_init.c \ - board_startup.c \ - main.c \ - sam_ba_usb.c \ - sam_ba_cdc.c \ - sam_ba_monitor.c \ - sam_ba_serial.c +board_driver_led.c \ +board_driver_serial.c \ +board_driver_usb.c \ +board_init.c \ +board_startup.c \ +main.c \ +sam_ba_usb.c \ +sam_ba_cdc.c \ +sam_ba_monitor.c \ +sam_ba_serial.c OBJECTS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.o)) DEPS=$(addprefix $(BUILD_PATH)/, $(SOURCES:.c=.d)) +NAME=samd21_sam_ba +ELF=$(NAME).elf +BIN=$(NAME).bin +HEX=$(NAME).hex + ifneq "test$(AVRSTUDIO_EXE_PATH)" "test" - AS_BUILD=copy_for_atmel_studio - AS_CLEAN=clean_for_atmel_studio +AS_BUILD=copy_for_atmel_studio +AS_CLEAN=clean_for_atmel_studio else - AS_BUILD= - AS_CLEAN= +AS_BUILD= +AS_CLEAN= endif -LD_SCRIPT=bootloader_samd21x18.ld all: print_info $(SOURCES) $(BIN) $(HEX) $(AS_BUILD) $(ELF): Makefile $(BUILD_PATH) $(OBJECTS) @echo ---------------------------------------------------------- @echo Creating ELF binary - "$(CC)" -L. -L$(BUILD_PATH) $(LDFLAGS) -Os -Wl,--gc-sections -save-temps -T$(LD_SCRIPT) -Wl,-Map,"$(BUILD_PATH)/$(NAME).map" -o "$(BUILD_PATH)/$(ELF)" -Wl,--start-group $(OBJECTS) -lm -Wl,--end-group + "$(CC)" -L. -L$(BUILD_PATH) $(LDFLAGS) -Os -Wl,--gc-sections -save-temps -Tbootloader_samd21x18.ld -Wl,-Map,"$(BUILD_PATH)/$(NAME).map" -o "$(BUILD_PATH)/$(ELF)" -Wl,--start-group $(OBJECTS) -lm -Wl,--end-group "$(NM)" "$(BUILD_PATH)/$(ELF)" >"$(BUILD_PATH)/$(NAME)_symbols.txt" "$(SIZE)" --format=sysv -t -x $(BUILD_PATH)/$(ELF) diff --git a/bootloaders/zero/README.md b/bootloaders/zero/README.md index b0d939db9..44f4e4e02 100644 --- a/bootloaders/zero/README.md +++ b/bootloaders/zero/README.md @@ -9,10 +9,6 @@ Multi-plaform GCC is provided by ARM here: https://launchpad.net/gcc-arm-embedde Atmel Studio contains both make and ARM GCC toolchain. You don't need to install them in this specific use case. -For all builds and platforms you will need to have the Arduino IDE installed and the board support -package for "Arduino SAMD Boards (32-bits ARM Cortex-M0+)". You can install the latter -from the former's "Boards Manager" UI. - ### Windows * Native command line @@ -77,19 +73,3 @@ Bootloader code will be located at 0x0 and executed before any applicative code. Applications compiled to be executed along with the bootloader will start at 0x2000 (see linker script bootloader_samd21x18.ld). Before jumping to the application, the bootloader changes the VTOR register to use the interrupt vectors of the application @0x2000.<- not required as application code is taking care of this. - -## 5- How to build - -If not specified the makefile builds for **Arduino Zero**: - -``` -make -``` - -if you want to make a custom bootloader for a derivative board you must supply all the necessary information in a `board_definitions_xxx.h` file, and add the corresponding case in `board_definitions.h`. -For example for the **Arduino MKR1000** we use `board_definitions_arduino_mkr1000.h` and it is build with the following command: - -``` -BOARD_ID=arduino_mkr1000 NAME=samd21_sam_ba_arduino_mkr1000 make clean all -``` - diff --git a/bootloaders/zero/board_definitions.h b/bootloaders/zero/board_definitions.h index 9d6721105..8129e401b 100644 --- a/bootloaders/zero/board_definitions.h +++ b/bootloaders/zero/board_definitions.h @@ -17,6 +17,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef _BOARD_DEFINITIONS_H_ +#define _BOARD_DEFINITIONS_H_ + #if defined(BOARD_ID_arduino_zero) #include "board_definitions_arduino_zero.h" #elif defined(BOARD_ID_genuino_zero) @@ -46,3 +49,53 @@ #define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f)) +/* + * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by + * quickly tapping two times on the reset button. + * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not + * be touched from the loaded application. + */ +#define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul) +#define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) + +/* + * If BOOT_LOAD_PIN is defined the bootloader is started if the selected + * pin is tied LOW. + */ +//#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 +//#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 +#define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f)) + +#define CPU_FREQUENCY (48000000ul) + +#define BOOT_USART_MODULE SERCOM0 +#define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM0 +#define BOOT_USART_PER_CLOCK_INDEX GCLK_ID_SERCOM0_CORE +#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2 +#define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 +#define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 +#define BOOT_USART_PAD1 PINMUX_UNUSED +#define BOOT_USART_PAD0 PINMUX_UNUSED + +/* Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/* Master clock frequency */ +#define VARIANT_MCK CPU_FREQUENCY + +#define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58) +#define NVM_SW_CALIB_DFLL48M_FINE_VAL (64) + +/* + * LEDs definitions + */ +#define BOARD_LED_PORT (0) +#define BOARD_LED_PIN (17) + +#define BOARD_LEDRX_PORT (1) +#define BOARD_LEDRX_PIN (3) + +#define BOARD_LEDTX_PORT (0) +#define BOARD_LEDTX_PIN (27) + +#endif // _BOARD_DEFINITIONS_H_ diff --git a/bootloaders/zero/board_driver_led.c b/bootloaders/zero/board_driver_led.c index ffa6c4782..1a2430aff 100644 --- a/bootloaders/zero/board_driver_led.c +++ b/bootloaders/zero/board_driver_led.c @@ -19,24 +19,4 @@ #include "board_driver_led.h" -volatile uint8_t ledKeepValue = 0; -volatile uint8_t ledTargetValue = 20; -volatile int8_t ledDirection = 1; -inline void LED_pulse() -{ - if (ledKeepValue == 0) { - ledTargetValue += ledDirection; - LED_toggle(); - } - ledKeepValue ++; - - if (ledTargetValue > 240 || ledTargetValue < 10) { - ledDirection = -ledDirection; - ledTargetValue += ledDirection; - } - - if (ledKeepValue == ledTargetValue) { - LED_toggle(); - } -} diff --git a/bootloaders/zero/board_driver_led.h b/bootloaders/zero/board_driver_led.h index d7d47cad8..6f1fd7580 100644 --- a/bootloaders/zero/board_driver_led.h +++ b/bootloaders/zero/board_driver_led.h @@ -23,41 +23,19 @@ #include #include "board_definitions.h" -#if defined(BOARD_LED_PORT) inline void LED_init(void) { PORT->Group[BOARD_LED_PORT].DIRSET.reg = (1<Group[BOARD_LED_PORT].OUTSET.reg = (1<Group[BOARD_LED_PORT].OUTCLR.reg = (1<Group[BOARD_LED_PORT].OUTTGL.reg = (1<Group[BOARD_LEDRX_PORT].DIRSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDRX_PORT].OUTSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTSET.reg = (1<Group[BOARD_LEDRX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDRX_PORT].OUTTGL.reg = (1<Group[BOARD_LEDTX_PORT].DIRSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDTX_PORT].OUTSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTSET.reg = (1<Group[BOARD_LEDTX_PORT].OUTCLR.reg = (1<Group[BOARD_LEDTX_PORT].OUTTGL.reg = (1< #define PINMUX_UNUSED 0xFFFFFFFF +#define GCLK_ID_SERCOM0_CORE 0x14 /* SERCOM UART available pad settings */ enum uart_pad_settings { diff --git a/bootloaders/zero/board_driver_usb.c b/bootloaders/zero/board_driver_usb.c index f1c83f44f..6534fa338 100644 --- a/bootloaders/zero/board_driver_usb.c +++ b/bootloaders/zero/board_driver_usb.c @@ -172,12 +172,13 @@ uint32_t USB_Write(Usb *pUsb, const char *pData, uint32_t length, uint8_t ep_num /* Set the multi packet size as zero for multi-packet transfers where length > ep size */ usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0; /* Clear the transfer complete flag */ - pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; + //pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT1 = true; + pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT |= (1<<1); /* Set the bank as ready */ pUsb->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.bit.BK1RDY = true; /* Wait for transfer to complete */ - while ( (pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT1) == 0 ); + while ( (pUsb->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.bit.TRCPT & (1<<1)) == 0 ); return length; } @@ -204,14 +205,15 @@ uint32_t USB_Read(Usb *pUsb, char *pData, uint32_t length) } /* Check for Transfer Complete 0 flag */ - if ( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 ) + if ( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0) ) { /* Set packet size */ packetSize = SAM_BA_MIN(usb_endpoint_table[USB_EP_OUT].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT, length); /* Copy read data to user buffer */ memcpy(pData, udd_ep_out_cache_buffer[USB_EP_OUT-1], packetSize); /* Clear the Transfer Complete 0 flag */ - pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; + //pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 = true; + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT |= (1 << 0); /* Clear the user flag */ read_job = false; } @@ -238,9 +240,10 @@ uint32_t USB_Read_blocking(Usb *pUsb, char *pData, uint32_t length) /* Clear the bank 0 ready flag */ pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPSTATUSCLR.bit.BK0RDY = true; /* Wait for transfer to complete */ - while (!( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 )); + while (!( pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0) )); /* Clear Transfer complete 0 flag */ - pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0; + //pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0 = true; + pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT |= (1 << 0); return length; } @@ -256,7 +259,7 @@ uint8_t USB_IsConfigured(P_USB_CDC pCdc) if (pUsb->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_EORST) { /* Clear the flag */ - pUsb->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; + pUsb->DEVICE.INTFLAG.bit.EORST = true; /* Set Device address as 0 */ pUsb->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | 0; /* Configure endpoint 0 */ @@ -300,12 +303,14 @@ void USB_SendStall(Usb *pUsb, bool direction_in) if (direction_in) { /* Set STALL request on IN direction */ - pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ1 = 1; + //pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ = (1<<1); } else { /* Set STALL request on OUT direction */ - pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ0 = 1; + //pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; + pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.STALLRQ = (1<<0); } } @@ -317,11 +322,12 @@ void USB_SendZlp(Usb *pUsb) /* Set the byte count as zero */ usb_endpoint_table[0].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = 0; /* Clear the transfer complete flag */ - pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1; + //pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT1 = true; + pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT |= (1 << 1); /* Set the bank as ready */ pUsb->DEVICE.DeviceEndpoint[0].EPSTATUSSET.bit.BK1RDY = true; /* Wait for transfer to complete */ - while (!( pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT1 )); + while (!( pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.TRCPT & (1<<1) )); } /*---------------------------------------------------------------------------- diff --git a/bootloaders/zero/board_startup.c b/bootloaders/zero/board_startup.c index 593d93b60..aaa5a019f 100644 --- a/bootloaders/zero/board_startup.c +++ b/bootloaders/zero/board_startup.c @@ -139,3 +139,9 @@ void PendSV_Handler(void) __BKPT(2); while (1); } + +void SysTick_Handler(void) +{ + __BKPT(1); + while (1); +} diff --git a/bootloaders/zero/main.c b/bootloaders/zero/main.c index af004cc68..3b18872a8 100644 --- a/bootloaders/zero/main.c +++ b/bootloaders/zero/main.c @@ -23,33 +23,18 @@ #include "sam_ba_serial.h" #include "board_definitions.h" #include "board_driver_led.h" -#include "board_driver_i2c.h" #include "sam_ba_usb.h" #include "sam_ba_cdc.h" extern uint32_t __sketch_vectors_ptr; // Exported value from linker script extern void board_init(void); +#if (defined DEBUG) && (DEBUG == 1) volatile uint32_t* pulSketch_Start_Address; - -static void jump_to_application(void) { - - /* Rebase the Stack Pointer */ - __set_MSP( (uint32_t)(__sketch_vectors_ptr) ); - - /* Rebase the vector table base address */ - SCB->VTOR = ((uint32_t)(&__sketch_vectors_ptr) & SCB_VTOR_TBLOFF_Msk); - - /* Jump to application Reset Handler in the application */ - asm("bx %0"::"r"(*pulSketch_Start_Address)); -} +#endif static volatile bool main_b_cdc_enable = false; -#ifdef CONFIGURE_PMIC -static volatile bool jump_to_app = false; -#endif - /** * \brief Check the application startup condition * @@ -59,35 +44,6 @@ static void check_start_application(void) // LED_init(); // LED_off(); - /* - * Test sketch stack pointer @ &__sketch_vectors_ptr - * Stay in SAM-BA if value @ (&__sketch_vectors_ptr) == 0xFFFFFFFF (Erased flash cell value) - */ - if (__sketch_vectors_ptr == 0xFFFFFFFF) - { - /* Stay in bootloader */ - return; - } - - /* - * Load the sketch Reset Handler address - * __sketch_vectors_ptr is exported from linker script and point on first 32b word of sketch vector table - * First 32b word is sketch stack - * Second 32b word is sketch entry point: Reset_Handler() - */ - pulSketch_Start_Address = &__sketch_vectors_ptr ; - pulSketch_Start_Address++ ; - - /* - * Test vector table address of sketch @ &__sketch_vectors_ptr - * Stay in SAM-BA if this function is not aligned enough, ie not valid - */ - if ( ((uint32_t)(&__sketch_vectors_ptr) & ~SCB_VTOR_TBLOFF_Msk) != 0x00) - { - /* Stay in bootloader */ - return; - } - #if defined(BOOT_DOUBLE_TAP_ADDRESS) #define DOUBLE_TAP_MAGIC 0x07738135 if (PM->RCAUSE.bit.POR) @@ -119,6 +75,39 @@ static void check_start_application(void) } #endif +#if (!defined DEBUG) || ((defined DEBUG) && (DEBUG == 0)) +uint32_t* pulSketch_Start_Address; +#endif + + /* + * Test sketch stack pointer @ &__sketch_vectors_ptr + * Stay in SAM-BA if value @ (&__sketch_vectors_ptr) == 0xFFFFFFFF (Erased flash cell value) + */ + if (__sketch_vectors_ptr == 0xFFFFFFFF) + { + /* Stay in bootloader */ + return; + } + + /* + * Load the sketch Reset Handler address + * __sketch_vectors_ptr is exported from linker script and point on first 32b word of sketch vector table + * First 32b word is sketch stack + * Second 32b word is sketch entry point: Reset_Handler() + */ + pulSketch_Start_Address = &__sketch_vectors_ptr ; + pulSketch_Start_Address++ ; + + /* + * Test vector table address of sketch @ &__sketch_vectors_ptr + * Stay in SAM-BA if this function is not aligned enough, ie not valid + */ + if ( ((uint32_t)(&__sketch_vectors_ptr) & ~SCB_VTOR_TBLOFF_Msk) != 0x00) + { + /* Stay in bootloader */ + return; + } + /* #if defined(BOOT_LOAD_PIN) volatile PortGroup *boot_port = (volatile PortGroup *)(&(PORT->Group[BOOT_LOAD_PIN / 32])); @@ -141,12 +130,15 @@ static void check_start_application(void) */ // LED_on(); -#ifdef CONFIGURE_PMIC - jump_to_app = true; -#else - jump_to_application(); -#endif + /* Rebase the Stack Pointer */ + __set_MSP( (uint32_t)(__sketch_vectors_ptr) ); + + /* Rebase the vector table base address */ + SCB->VTOR = ((uint32_t)(&__sketch_vectors_ptr) & SCB_VTOR_TBLOFF_Msk); + + /* Jump to application Reset Handler in the application */ + asm("bx %0"::"r"(*pulSketch_Start_Address)); } #if DEBUG_ENABLE @@ -176,13 +168,6 @@ int main(void) board_init(); __enable_irq(); -#ifdef CONFIGURE_PMIC - configure_pmic(); - if (jump_to_app == true) { - jump_to_application(); - } -#endif - #if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES /* UART is enabled in all cases */ serial_open(); @@ -194,16 +179,6 @@ int main(void) DEBUG_PIN_LOW; - /* Initialize LEDs */ - LED_init(); - LEDRX_init(); - LEDRX_off(); - LEDTX_init(); - LEDTX_off(); - - /* Start the sys tick (1 ms) */ - SysTick_Config(1000); - /* Wait for a complete enum on usb or a '#' char on serial line */ while (1) { @@ -239,10 +214,3 @@ int main(void) #endif } } - -void SysTick_Handler(void) -{ - LED_pulse(); - - sam_ba_monitor_sys_tick(); -} diff --git a/bootloaders/zero/main.h b/bootloaders/zero/main.h new file mode 100644 index 000000000..f2b10dc46 --- /dev/null +++ b/bootloaders/zero/main.h @@ -0,0 +1,69 @@ +/* ---------------------------------------------------------------------------- + * SAM Software Package License + * ---------------------------------------------------------------------------- + * Copyright (c) 2011-2012, Atmel Corporation + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following condition is met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Atmel's name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * ---------------------------------------------------------------------------- + */ + +#pragma once + +// Gently pulse the D13 LED +#define LED_PIN 17 +#define PORTA PORT->Group[0] +#define LED_PORT PORTA + +#define LED_ON LED_PORT.OUTSET.reg = (uint32_t)(1 << LED_PIN); +#define LED_OFF LED_PORT.OUTCLR.reg = (uint32_t)(1 << LED_PIN); +/* + * If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by + * quickly tapping two times on the reset button. + * BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not + * be touched from the loaded application. + */ +#define BOOT_DOUBLE_TAP_ADDRESS 0x20007FFC +#define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS)) + +/* + * If BOOT_LOAD_PIN is defined the bootloader is started if the selected + * pin is tied LOW. + */ +//#define BOOT_LOAD_PIN PIN_PA21 // Pin 7 +//#define BOOT_LOAD_PIN PIN_PA15 // Pin 5 +#define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f)) + +#define CPU_FREQUENCY 8000000 +#define APP_START_ADDRESS 0x00002000 +#define FLASH_WAIT_STATES 1 + +#define BOOT_USART_MODULE SERCOM0 +//#define BOOT_USART_MODULE SERCOM5 +#define BOOT_USART_MUX_SETTINGS UART_RX_PAD3_TX_PAD2 +//#define BOOT_USART_PAD3 PINMUX_PB23D_SERCOM5_PAD3 +//#define BOOT_USART_PAD2 PINMUX_PB22D_SERCOM5_PAD2 +#define BOOT_USART_PAD3 PINMUX_PA11C_SERCOM0_PAD3 +#define BOOT_USART_PAD2 PINMUX_PA10C_SERCOM0_PAD2 +#define BOOT_USART_PAD1 PINMUX_UNUSED +#define BOOT_USART_PAD0 PINMUX_UNUSED + diff --git a/bootloaders/zero/sam_ba_cdc.c b/bootloaders/zero/sam_ba_cdc.c index 377340921..fc5efe348 100644 --- a/bootloaders/zero/sam_ba_cdc.c +++ b/bootloaders/zero/sam_ba_cdc.c @@ -55,7 +55,7 @@ bool cdc_is_rx_ready(/*P_USB_CDC pCdc*/void) return 0; /* Return transfer complete 0 flag status */ - return (pCdc->pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT0); + return (pCdc->pUsb->DEVICE.DeviceEndpoint[USB_EP_OUT].EPINTFLAG.bit.TRCPT & (1<<0)); } uint32_t cdc_write_buf(/*P_USB_CDC pCdc,*/ void const* data, uint32_t length) diff --git a/bootloaders/zero/sam_ba_monitor.c b/bootloaders/zero/sam_ba_monitor.c index 8b31b9471..7daeb3067 100644 --- a/bootloaders/zero/sam_ba_monitor.c +++ b/bootloaders/zero/sam_ba_monitor.c @@ -25,7 +25,6 @@ #include "board_driver_usb.h" #include "sam_ba_usb.h" #include "sam_ba_cdc.h" -#include "board_driver_led.h" const char RomBOOT_Version[] = SAM_BA_VERSION; const char RomBOOT_ExtendedCapabilities[] = "[Arduino:XYZ]"; @@ -85,11 +84,6 @@ t_monitor_if * ptr_monitor_if; volatile bool b_terminal_mode = false; volatile bool b_sam_ba_interface_usart = false; -/* Pulse generation counters to keep track of the time remaining for each pulse type */ -#define TX_RX_LED_PULSE_PERIOD 100 -volatile uint16_t txLEDPulse = 0; // time remaining for Tx LED pulse -volatile uint16_t rxLEDPulse = 0; // time remaining for Rx LED pulse - void sam_ba_monitor_init(uint8_t com_interface) { #if SAM_BA_INTERFACE == SAM_BA_UART_ONLY || SAM_BA_INTERFACE == SAM_BA_BOTH_INTERFACES @@ -108,74 +102,8 @@ void sam_ba_monitor_init(uint8_t com_interface) #endif } -/* - * Central SAM-BA monitor putdata function using the board LEDs - */ -static uint32_t sam_ba_putdata(t_monitor_if* pInterface, void const* data, uint32_t length) -{ - uint32_t result ; - - result=pInterface->putdata(data, length); - - LEDTX_on(); - txLEDPulse = TX_RX_LED_PULSE_PERIOD; - - return result; -} - -/* - * Central SAM-BA monitor getdata function using the board LEDs - */ -static uint32_t sam_ba_getdata(t_monitor_if* pInterface, void* data, uint32_t length) -{ - uint32_t result ; - - result=pInterface->getdata(data, length); - - if (result) - { - LEDRX_on(); - rxLEDPulse = TX_RX_LED_PULSE_PERIOD; - } - - return result; -} - -/* - * Central SAM-BA monitor putdata function using the board LEDs - */ -static uint32_t sam_ba_putdata_xmd(t_monitor_if* pInterface, void const* data, uint32_t length) -{ - uint32_t result ; - - result=pInterface->putdata_xmd(data, length); - - LEDTX_on(); - txLEDPulse = TX_RX_LED_PULSE_PERIOD; - - return result; -} - -/* - * Central SAM-BA monitor getdata function using the board LEDs - */ -static uint32_t sam_ba_getdata_xmd(t_monitor_if* pInterface, void* data, uint32_t length) -{ - uint32_t result ; - - result=pInterface->getdata_xmd(data, length); - - if (result) - { - LEDRX_on(); - rxLEDPulse = TX_RX_LED_PULSE_PERIOD; - } - - return result; -} - /** - * \brief This function allows data emission by USART + * \brief This function allows data rx by USART * * \param *data Data pointer * \param length Length of the data @@ -213,10 +141,10 @@ void sam_ba_putdata_term(uint8_t* data, uint32_t length) buf[1] = 'x'; buf[length * 2 + 2] = '\n'; buf[length * 2 + 3] = '\r'; - sam_ba_putdata(ptr_monitor_if, buf, length * 2 + 4); + ptr_monitor_if->putdata(buf, length * 2 + 4); } else - sam_ba_putdata(ptr_monitor_if, data, length); + ptr_monitor_if->putdata(data, length); return; } @@ -259,12 +187,12 @@ static void put_uint32(uint32_t n) buff[7-i] = d > 9 ? 'A' + d - 10 : '0' + d; } - sam_ba_putdata( ptr_monitor_if, buff, 8); + ptr_monitor_if->putdata(buff, 8); } static void sam_ba_monitor_loop(void) { - length = sam_ba_getdata(ptr_monitor_if, data, SIZEBUFMAX); + length = ptr_monitor_if->getdata(data, SIZEBUFMAX); ptr = data; for (i = 0; i < length; i++, ptr++) @@ -275,7 +203,7 @@ static void sam_ba_monitor_loop(void) { if (b_terminal_mode) { - sam_ba_putdata(ptr_monitor_if, "\n\r", 2); + ptr_monitor_if->putdata("\n\r", 2); } if (command == 'S') { @@ -307,13 +235,13 @@ static void sam_ba_monitor_loop(void) ptr--; //Do we expect more data ? if(jgetdata_xmd(ptr_data, current_number-j); __asm("nop"); } else if (command == 'R') { - sam_ba_putdata_xmd(ptr_monitor_if, ptr_data, current_number); + ptr_monitor_if->putdata_xmd(ptr_data, current_number); } else if (command == 'O') { @@ -354,35 +282,35 @@ static void sam_ba_monitor_loop(void) else if (command == 'T') { b_terminal_mode = 1; - sam_ba_putdata(ptr_monitor_if, "\n\r", 2); + ptr_monitor_if->putdata("\n\r", 2); } else if (command == 'N') { if (b_terminal_mode == 0) { - sam_ba_putdata( ptr_monitor_if, "\n\r", 2); + ptr_monitor_if->putdata("\n\r", 2); } b_terminal_mode = 0; } else if (command == 'V') { - sam_ba_putdata( ptr_monitor_if, "v", 1); - sam_ba_putdata( ptr_monitor_if, (uint8_t *) RomBOOT_Version, strlen(RomBOOT_Version)); - sam_ba_putdata( ptr_monitor_if, " ", 1); - sam_ba_putdata( ptr_monitor_if, (uint8_t *) RomBOOT_ExtendedCapabilities, strlen(RomBOOT_ExtendedCapabilities)); - sam_ba_putdata( ptr_monitor_if, " ", 1); + ptr_monitor_if->putdata("v", 1); + ptr_monitor_if->putdata((uint8_t *) RomBOOT_Version, strlen(RomBOOT_Version)); + ptr_monitor_if->putdata(" ", 1); + ptr_monitor_if->putdata((uint8_t *) RomBOOT_ExtendedCapabilities, strlen(RomBOOT_ExtendedCapabilities)); + ptr_monitor_if->putdata(" ", 1); ptr = (uint8_t*) &(__DATE__); i = 0; while (*ptr++ != '\0') i++; - sam_ba_putdata( ptr_monitor_if, (uint8_t *) &(__DATE__), i); - sam_ba_putdata( ptr_monitor_if, " ", 1); + ptr_monitor_if->putdata((uint8_t *) &(__DATE__), i); + ptr_monitor_if->putdata(" ", 1); i = 0; ptr = (uint8_t*) &(__TIME__); while (*ptr++ != '\0') i++; - sam_ba_putdata( ptr_monitor_if, (uint8_t *) &(__TIME__), i); - sam_ba_putdata( ptr_monitor_if, "\n\r", 2); + ptr_monitor_if->putdata((uint8_t *) &(__TIME__), i); + ptr_monitor_if->putdata("\n\r", 2); } else if (command == 'X') { @@ -406,7 +334,7 @@ static void sam_ba_monitor_loop(void) } // Notify command completed - sam_ba_putdata( ptr_monitor_if, "X\n\r", 3); + ptr_monitor_if->putdata("X\n\r", 3); } else if (command == 'Y') { @@ -465,7 +393,7 @@ static void sam_ba_monitor_loop(void) } // Notify command completed - sam_ba_putdata( ptr_monitor_if, "Y\n\r", 3); + ptr_monitor_if->putdata("Y\n\r", 3); } else if (command == 'Z') { @@ -484,9 +412,9 @@ static void sam_ba_monitor_loop(void) crc = serial_add_crc(*data++, crc); // Send response - sam_ba_putdata( ptr_monitor_if, "Z", 1); + ptr_monitor_if->putdata("Z", 1); put_uint32(crc); - sam_ba_putdata( ptr_monitor_if, "#\n\r", 3); + ptr_monitor_if->putdata("#\n\r", 3); } command = 'z'; @@ -494,7 +422,7 @@ static void sam_ba_monitor_loop(void) if (b_terminal_mode) { - sam_ba_putdata( ptr_monitor_if, ">", 1); + ptr_monitor_if->putdata(">", 1); } } else @@ -525,15 +453,6 @@ static void sam_ba_monitor_loop(void) } } -void sam_ba_monitor_sys_tick(void) -{ - /* Check whether the TX or RX LED one-shot period has elapsed. if so, turn off the LED */ - if (txLEDPulse && !(--txLEDPulse)) - LEDTX_off(); - if (rxLEDPulse && !(--rxLEDPulse)) - LEDRX_off(); -} - /** * \brief This function starts the SAM-BA monitor. */ diff --git a/bootloaders/zero/sam_ba_serial.c b/bootloaders/zero/sam_ba_serial.c index 09607ecf6..a06de01dc 100644 --- a/bootloaders/zero/sam_ba_serial.c +++ b/bootloaders/zero/sam_ba_serial.c @@ -108,8 +108,8 @@ void serial_open(void) /* Wait for synchronization */ } - /* Baud rate 115200 - clock 48MHz -> BAUD value-63018 */ - uart_basic_init(BOOT_USART_MODULE, 63018, BOOT_USART_PAD_SETTINGS); + /* Baud rate 115200 - clock 8MHz -> BAUD value-50436 */ + uart_basic_init(BOOT_USART_MODULE, 50436, BOOT_USART_PAD_SETTINGS); //Initialize flag b_sharp_received = false; diff --git a/bootloaders/zero/sam_ba_usb.c b/bootloaders/zero/sam_ba_usb.c index 068b81d8b..090375c7f 100644 --- a/bootloaders/zero/sam_ba_usb.c +++ b/bootloaders/zero/sam_ba_usb.c @@ -19,7 +19,6 @@ #include #include -#include "board_definitions.h" #include "sam_ba_usb.h" #include "board_driver_usb.h" #include "sam_ba_cdc.h" @@ -39,14 +38,19 @@ const char devDescriptor[] = 0x00, // bDeviceSubclass: CDC class sub code 0x00, // bDeviceProtocol: CDC Device protocol 0x40, // bMaxPacketSize0 - USB_VID_LOW, // idVendor L - USB_VID_HIGH, // idVendor H + 0x41, // idVendor L + 0x23, // idVendor H USB_PID_LOW, // idProduct L USB_PID_HIGH, // idProduct H 0x00, // bcdDevice L, here matching SAM-BA version 0x02, // bcdDevice H +#if 0 // TODO: pending validation STRING_INDEX_MANUFACTURER, // iManufacturer STRING_INDEX_PRODUCT, // iProduct +#else + 0x00, // iManufacturer + 0x00, // iProduct +#endif // 0 0x00, // SerialNumber, should be based on product unique ID 0x01 // bNumConfigs }; @@ -167,7 +171,7 @@ void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) static volatile uint16_t wValue, wIndex, wLength, wStatus; /* Clear the Received Setup flag */ - pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; + pUsb->DEVICE.DeviceEndpoint[0].EPINTFLAG.bit.RXSTP = true; /* Read the USB request parameters */ bmRequestType = udd_ep_out_cache_buffer[0][0]; @@ -191,40 +195,47 @@ void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) /* Return Device Descriptor */ USB_Write(pCdc->pUsb, devDescriptor, SAM_BA_MIN(sizeof(devDescriptor), wLength), USB_EP_CTRL); } - else if (wValue>>8 == STD_GET_DESCRIPTOR_CONFIGURATION) - { - /* Return Configuration Descriptor */ - USB_Write(pCdc->pUsb, cfgDescriptor, SAM_BA_MIN(sizeof(cfgDescriptor), wLength), USB_EP_CTRL); - } - else if (wValue>>8 == STD_GET_DESCRIPTOR_STRING) + else { - switch ( wValue & 0xff ) + if (wValue>>8 == STD_GET_DESCRIPTOR_CONFIGURATION) { - case STRING_INDEX_LANGUAGES: { - uint16_t STRING_LANGUAGE[2] = { (STD_GET_DESCRIPTOR_STRING<<8) | 4, 0x0409 }; - - USB_Write(pCdc->pUsb, (const char*)STRING_LANGUAGE, SAM_BA_MIN(sizeof(STRING_LANGUAGE), wLength), USB_EP_CTRL); + /* Return Configuration Descriptor */ + USB_Write(pCdc->pUsb, cfgDescriptor, SAM_BA_MIN(sizeof(cfgDescriptor), wLength), USB_EP_CTRL); + } + else + { +#if 0 // TODO: pending validation + if (wValue>>8 == STD_GET_DESCRIPTOR_STRING) + { + switch ( wValue & 0xff ) + { + case STRING_INDEX_LANGUAGES: + uint16_t STRING_LANGUAGE[2] = { (STD_GET_DESCRIPTOR_STRING<<8) | 4, 0x0409 }; + + USB_Write(pCdc->pUsb, (const char*)STRING_LANGUAGE, SAM_BA_MIN(sizeof(STRING_LANGUAGE), wLength), USB_EP_CTRL); + break; + + case STRING_INDEX_MANUFACTURER: + USB_SendString(pCdc->pUsb, STRING_MANUFACTURER, strlen(STRING_MANUFACTURER), wLength ); + break; + + case STRING_INDEX_PRODUCT: + USB_SendString(pCdc->pUsb, STRING_PRODUCT, strlen(STRING_PRODUCT), wLength ); + break; + default: + /* Stall the request */ + USB_SendStall(pUsb, true); + break; + } } - break; - - case STRING_INDEX_MANUFACTURER: - USB_SendString(pCdc->pUsb, STRING_MANUFACTURER, wLength ); - break; - - case STRING_INDEX_PRODUCT: - USB_SendString(pCdc->pUsb, STRING_PRODUCT, wLength ); - break; - default: + else +#endif // 0 + { /* Stall the request */ USB_SendStall(pUsb, true); - break; + } } } - else - { - /* Stall the request */ - USB_SendStall(pUsb, true); - } break; case STD_SET_ADDRESS: @@ -268,11 +279,13 @@ void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) { if (dir) { - wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) ? 1 : 0; + //wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) ? 1 : 0; + wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<1)) ? 1 : 0; } else { - wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) ? 1 : 0; + //wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) ? 1 : 0; + wStatus = (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<0)) ? 1 : 0; } /* Return current status of endpoint */ USB_Write(pCdc->pUsb, (char *) &wStatus, sizeof(wStatus), USB_EP_CTRL); @@ -302,11 +315,13 @@ void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) /* Set STALL request for the endpoint */ if (dir) { - pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; + //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1; + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.bit.STALLRQ = (1<<1); } else { - pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; + //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0; + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSSET.bit.STALLRQ = (1<<0); } /* Send ZLP */ @@ -338,13 +353,14 @@ void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) { if (dir) { - if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ1) + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<1)) { // Remove stall request - pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; - if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL1) + //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1; + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.bit.STALLRQ = (1<<1); + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL & (1<<1)) { - pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1; + pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL = (1<<1); // The Stall has occurred, then reset data toggle pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN; } @@ -352,13 +368,14 @@ void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc) } else { - if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ0) + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUS.bit.STALLRQ & (1<<0)) { // Remove stall request - pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; - if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL0) + //pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0; + pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.bit.STALLRQ = (1<<0); + if (pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL & (1<<0)) { - pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0; + pUsb->DEVICE.DeviceEndpoint[wIndex].EPINTFLAG.bit.STALL = (1<<0); // The Stall has occurred, then reset data toggle pUsb->DEVICE.DeviceEndpoint[wIndex].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT; } @@ -413,24 +430,27 @@ P_USB_CDC usb_init(void) return &sam_ba_cdc; } +#if 0 // TODO: pending validation /*---------------------------------------------------------------------------- * \brief Send a USB descriptor string. * * The input string is plain ASCII but is sent out as UTF-16 with the correct 2-byte prefix. */ -uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t maxLength) +uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t length, uint8_t maxLength) { uint8_t string_descriptor[255]; // Max USB-allowed string length uint16_t* unicode_string=(uint16_t*)(string_descriptor+2); // point on 3 bytes of descriptor - int resulting_length; - string_descriptor[0] = (strlen(ascii_string)<<1) + 2; - string_descriptor[1] = STD_GET_DESCRIPTOR_STRING; + int resulting_length = 1; - for ( resulting_length = 1 ; *ascii_string && (resulting_length>1) ; resulting_length++ ) + for ( ; *ascii_string && (length>=0) && (resulting_length<(maxLength>>1)) ; ascii_string++, length--, resulting_length++ ) { - *unicode_string++ = (uint16_t)(*ascii_string++); + *unicode_string++ = (uint16_t)(*ascii_string); } - return USB_Write(pUsb, (const char*)string_descriptor, resulting_length<<1, USB_EP_CTRL); + string_descriptor[0] = (resulting_length<<1); + string_descriptor[1] = STD_GET_DESCRIPTOR_STRING; + + return USB_Write(pUsb, (const char*)unicode_string, resulting_length, USB_EP_CTRL); } +#endif // 0 diff --git a/bootloaders/zero/sam_ba_usb.h b/bootloaders/zero/sam_ba_usb.h index 457fdbc09..42c0d608f 100644 --- a/bootloaders/zero/sam_ba_usb.h +++ b/bootloaders/zero/sam_ba_usb.h @@ -66,9 +66,11 @@ #define FEATURE_DEVICE_REMOTE_WAKEUP (1u) #define FEATURE_TEST_MODE (2u) +#if 0 // TODO: pending validation #define STRING_INDEX_LANGUAGES (0x00u) #define STRING_INDEX_MANUFACTURER (0x01u) #define STRING_INDEX_PRODUCT (0x02u) +#endif // 0 #define SAM_BA_MIN(a, b) (((a) < (b)) ? (a) : (b)) @@ -94,7 +96,9 @@ P_USB_CDC usb_init(void); void sam_ba_usb_CDC_Enumerate(P_USB_CDC pCdc); -uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t maxLength); +#if 0 // TODO: pending validation +uint32_t USB_SendString(Usb *pUsb, const char* ascii_string, uint8_t length, uint8_t maxLength); +#endif // 0 extern USB_CDC sam_ba_cdc; diff --git a/bootloaders/zero/samd21_sam_ba.bin b/bootloaders/zero/samd21_sam_ba.bin old mode 100755 new mode 100644 index cc88fa191..d727d0707 Binary files a/bootloaders/zero/samd21_sam_ba.bin and b/bootloaders/zero/samd21_sam_ba.bin differ diff --git a/bootloaders/zero/samd21_sam_ba.elf b/bootloaders/zero/samd21_sam_ba.elf new file mode 100644 index 000000000..edee94811 Binary files /dev/null and b/bootloaders/zero/samd21_sam_ba.elf differ diff --git a/bootloaders/zero/samd21_sam_ba.hex b/bootloaders/zero/samd21_sam_ba.hex index 95fe19aa1..12ee99817 100644 --- a/bootloaders/zero/samd21_sam_ba.hex +++ b/bootloaders/zero/samd21_sam_ba.hex @@ -1,409 +1,376 @@ -:10000000FC7F002015060000050600000906000020 +:10000000FC7F0020E9050000D5050000D9050000AF :1000100000000000000000000000000000000000E0 -:100020000000000000000000000000000D060000BD -:10003000000000000000000011060000650700003D +:10002000000000000000000000000000DD050000EE +:100030000000000000000000E1050000E5050000F0 :1000400010B5064C2378002B07D1054B002B02D0AE -:10005000044800E000BF0123237010BD5C000020B5 -:10006000000000000819000008B5084B002B03D061 +:10005000044800E000BF0123237010BD58000020B9 +:1000600000000000F816000008B5084B002B03D074 :100070000748084900E000BF07480368002B03D089 :10008000064B002B00D0984708BDC046000000007A -:100090000819000060000020580000200000000047 -:1000A000154A164B1178002909D115491878097895 -:1000B0004118C9B21970802012498002C8611178B4 -:1000C0000131C9B211701978F02902D819780929BB -:1000D00009D80B4908784042C0B2087018780978EE -:1000E0004118C9B2197012781B789A4203D1802244 -:1000F000044B9202DA617047780000200100002072 -:10010000000000200044004110B5C3699C07FCD4E6 -:1001100003680224A3430360C46901231C42FBD18A -:100120000468234303600368DC07FCD4C46901232B -:100130001C42FBD1C469DC401C42F7D1084B1A4376 -:100140000260C3695A07FCD4C0239B0243608181CB -:10015000C3699C07FCD4036802221343036010BDEB -:1001600004000040037EDA07FCD5018570470000DB -:10017000027E01235107FBD5428B1A4207D1428BE5 -:10018000DA401A4203D1428B92081A4202D0034B42 -:1001900001221A70008DC0B27047C046790000205D -:1001A00070B50368041C988B1A1C0821FF320842A2 -:1001B00026D0802099839872112353704021144BCC -:1001C000917150715E68134DC0202E40800506432A -:1001D0005E605E693540284358610F4818600F48DB -:1001E00018615D680E4828408025AD02284358609C -:1001F0005868800B8003586000235171237105E01B -:10020000137ADA0602D5201C00F0E6FA207970BDD8 -:1002100098010020FFFFFF8F9800002018010020A8 -:10022000FF3F00F0002303714371044B01608360C2 -:100230000B78022213430B707047C046A1010000E7 -:1002400038B5364B2021DA6901200A43DA61344B94 -:1002500006241A7802431A70324B0F221978914300 -:1002600019701978214319702F490C7820430870B0 -:1002700019780A401A701A7860210A431A702B4BB9 -:100280002B4A5A805A7852B2002AFBDB294B0121B3 -:100290001A780A431A709A78D107FCD42648026863 -:1002A000510B1F221140914200D1052111408C01B8 -:1002B0001D8D22492940214319850468A10C0A405B -:1002C0001F2A00D11D221C8D1F210A408C4322436E -:1002D0001A8502680721D20D0A408A4200D1032202 -:1002E0000A40188D1103164A02400A431A851978EC -:1002F0007F220A401A701A78042112480A431A70A1 -:1003000058621A890C218A431A811A8901218A4369 -:100310001A810021802201F076F938BD00040040E6 -:10032000584400413C44004159440041000C004005 -:100330000640000000500041246080003FF8FFFFAD -:10034000FF8FFFFF98010020F7B5141C1F4A5F01C3 -:1003500001971D1CD319061C5869271C4000400F2B -:1003600003301033C74006D00F1C80225968120694 -:100370000A435A6009E02F1C7B1E9F41144BBF01AA -:10038000FF18381C221C01F035F901990F48083577 -:1003900042181761131C5269A104920B890C920335 -:1003A0000A435A6159690B4A0A405A616B01F318B2 -:1003B0000222DA715979802252420A435A716B0142 -:1003C000F318DB799A07FAD5201CFEBD98010020AE -:1003D00018010020FF3F00F0F8B51A4E051C3378D5 -:1003E000141C002B12D1184B184A1A645A6C920B29 -:1003F00092035A64586C164A02405A64A2235B0066 -:10040000EA5C40200243EA54012333704827FF3757 -:10041000EA5D0123134012D00B4B5A6C9204920CEC -:10042000A24202D25C6CA404A40C081C221C074942 -:1004300001F0E0F80123EB550023337000E01C1CB1 -:10044000201CF8BD7A00002098010020D800002070 -:10045000FF3F00F0FF3083792022002900D11022D5 -:100460001343837170470000084BFF305A69920BA9 -:1004700092035A6102230372827980235B42134301 -:100480008371037A9A07FCD57047C0469801002013 -:1004900080235B421943C9B28172704770B5A023B3 -:1004A00003225B00C254134B134A5C6CC0211440FE -:1004B00089050C4346255C64FF35402444550F4DA7 -:1004C00030261D6490256D0046555D6B154029430F -:1004D000922559636D0080214155094D1D63B0255A -:1004E0006D0044555C6F22405A67B2235B00C154D3 -:1004F00070BDC04698010020FFFFFF8FD80000208C -:100500005801002030B5364A1E235168082099430F -:1005100002231943516033498A6902438A61324890 -:10052000324A9082908A03439382D3689807FCD51D -:100530002F4B012018701878C40704D52C48407838 -:1005400040B20028F7DB01209860587840B20028BC -:10055000FBDB284C26484460587840B20028FBDB7F -:1005600082242348E4014480587840B20028FBDB11 -:10057000908C8024A0439084D068C506FCD51E4C86 -:100580001A48C462D4681948E506FBD5848C1B4D13 -:100590002C438484D4681548E506FBD5848C022559 -:1005A0002C438484D0680406FCD51048C0684506F6 -:1005B000F8D5D068C406FCD500229A605A7852B2A9 -:1005C000002AFBDB0E480A4A50605A7852B2002AD1 -:1005D000FBDB00230B724B728B72CB7230BDC046BB -:1005E00000400041000400400C06000000080040EC -:1005F000000C004001050100B805FF7D040A000061 -:10060000000703000EBEFEE70DBEFEE705BEFEE7D7 -:1006100002BEFEE70E4A0F4838B5824204D10E4AA8 -:100620000E4B93420ED10AE00D4C9442F7D00023BA -:10063000D1188842F3D9E55804330D60F8E700F08B -:1006400011F804E09342FAD2002102C3FAE7FEE770 -:10065000000000205C000020A40300205C000020BB -:100660000C190000334A38B51368141C01331ED02E -:10067000D1B200291BD1304B1878012318402F4BE1 -:100680000AD11D682E498D4201D118600FE0196012 -:100690002C4901390029FCD11960236883F30888AB -:1006A000FF239A43284B9A60224B5B681847FFF759 -:1006B00029FF62B600F0CCFD00F05AF8234B8022EF -:1006C000920223499A6008220A602249041C0A60A7 -:1006D000802212059A609A611F4B204AC0215A60FD -:1006E000194A0906106A0002000A01431162002239 -:1006F0009A6007221A60A368201C9847184B0028AC -:1007000001D001221A701A78002A05D0002000F0CA -:1007100093FA00F019FBFCE71B78002BEBD100F0FB -:100720000BFE0028E7D0012000F086FA00F00CFB59 -:10073000FCE7C0460020000038040040FC7F002099 -:100740003581730748E8010000ED00E000440041F6 -:10075000884400419844004110E000E0E7030000B5 -:100760007B00002008B5FFF79BFC00F0C9FA08BD2C -:1007700010B5054B054C2360FFF762FD201C216876 -:10078000FFF750FD201C10BD005000411802002052 -:1007900070B5051CC0B0081C161C0C1C00F03BFFFB -:1007A00040006A460323023053701070760801231C -:1007B000E218013A11785A00002906D1281C69462E -:1007C0000023FFF7C1FD40B070BDB342F6DA6846C2 -:1007D00081520133ECE70000F7B5BA4A0468137898 -:1007E000B949271CFF37051C102038720B7053784D -:1007F000B648B74E037093783380D17833880902B6 -:100800000B4333801179B34B198051791888090251 -:10081000084318809079B0490880D279088812027C -:1008200002430A8040227A71A84F3A78A64F1202FA -:1008300038780F1C0243A9488446181C624500D131 -:10084000C2E020DC802149008A4200D16EE109DC4F -:10085000812A00D192E0822A00D195E0802A00D03E -:1008600064E18BE081235B009A4200D1CFE000DAA3 -:1008700058E1C0239B009A4200D157E1984B9A421D -:1008800000D14FE152E190231B019A4269D015DC5F -:10089000D023DB009A4222D088231B019A4269D0E0 -:1008A000A023DB009A4200D040E1201CFFF7DCFDD2 -:1008B0003188286889B2FFF7EBFD3BE1894B9A420A -:1008C00000D12FE100DC31E1874B9A4200D11DE1DC -:1008D000864B9A4200D029E133886B7122E133883C -:1008E0001B0A012B08D10B8812222868934201D8D9 -:1008F0000A8892B27E4911E133881B0A022B08D183 -:100900000B8843222868934201D80A8892B2794919 -:1009100004E133881B0A032B00D007E13388DBB2E4 -:10092000012B17D0002B07D0022B00D0FEE00A8845 -:100930002868D2B2704911E0042201A86F4900F082 -:1009400059FE3B8804222868934201D83A8892B223 -:1009500001A9E3E00A8828686949D2B2FFF718FFC5 -:10096000E8E03388201C2B71FFF77EFD201CFFF789 -:1009700095FDDFE0291C01C90122CFE06149002378 -:100980000B8028680222CAE05E4900220A8018888B -:10099000502210405C4A10701E880F203040188092 -:1009A0001888032800D9C1E012781B8808335B013E -:1009B000E418A379002A01D09B0600E0DB06DB0FD8 -:1009C0000B8028680222A9E019887F2291434E4AB1 -:1009D000C9B2117018880F2101401980318800298F -:1009E00000D0A3E01988002900D19FE019880329CD -:1009F00000D99BE012781B8808335B01E318002ABA -:100A000002D020225A718DE0102159718AE00288AB -:100A10007F239A433C4BD2B21A7001880F220A40BE -:100A200002803288002A00D080E00288002A00D1AB -:100A30007CE00288032A00D978E01B78002B1FD0C5 -:100A4000038808335B01E3189B799A066AD503880B -:100A5000202208335B01E3181A71038808335B0115 -:100A6000E318DB795F065DD50388402208335B011C -:100A7000E318DA710388022208335B01E3181EE0F1 -:100A8000038808335B01E3189B79D9064AD50388AC -:100A9000102208335B01E3181A71038808335B01E5 -:100AA000E318DB799A063DD50388202208335B01E1 -:100AB000E318DA710388012208335B01E3181A7125 -:100AC00030E0C046980000207D0000208200002019 -:100AD0008400002086000020800000200203000027 -:100AE0000103000021200000A121000021220000BC -:100AF0005C160000040000204C1600003C160000AC -:100B0000401600007E0000207C0000200B88082298 -:100B10002868934201D80A8892B207490023FFF758 -:100B200013FC07E0201CFFF79FFC03E0201C0121C1 -:100B3000FFF790FCF7BDC0464800002007B5054B05 -:100B40000122019001A91868131CFFF7FDFB012089 -:100B50000EBDC0461802002013B5054B6C46073485 -:100B60001868211C0122FFF737FC207816BDC0460B -:100B70001802002010B5074C201CFFF711FB031CC6 -:100B80000020834205D022684823FF33D05C012334 -:100B9000184010BD1802002010B5054A0C1C031C9B -:100BA000191C10680123221CFFF7CEFB201C10BD6E -:100BB0001802002070B5084C061C201C0D1CFFF705 -:100BC000EFFA0023984205D02068311C2A1CFFF759 -:100BD00003FC031C181C70BD18020020F8B50C4C57 -:100BE000051C201C0E1CFFF7DBFA0023271C341CFD -:100BF00098420AD0002C07D0291C221C3868FFF725 -:100C0000EBFB241A2D18F5E7331C181CF8BDC04661 -:100C10001802002008B5031C081C111C9847044B3F -:100C2000802212055A61034B64221A8008BDC04617 -:100C3000004400418C000020012805D1054B064AE4 -:100C40001A60064B187004E0002802D1044A014BD8 -:100C50001A6070478802002090160000940000205F -:100C6000DC16000030B50A1C1C4985B00978031C4D -:100C700000292AD0042A01D1006804E0022A01D107 -:100C8000008800E00078520004A98B180B3B9C1AE6 -:100C9000A3420BD00F210140092902D83025294356 -:100CA00000E0373119700009013BF1E701A9302359 -:100CB0000B7078234B700A208B1898700D20D87019 -:100CC000074B04321B68D86803E005490968C86807 -:100CD000191CFFF79FFF05B030BDC04688000020FB -:100CE0008802002072B6EFF30883044A1360036899 -:100CF00083F30888436818477047C0468C02002079 -:100D00000D4B1A88002A09D01A88013A92B21A802B -:100D1000002A03D18022094B12059A61084B1A88D8 -:100D2000002A08D01A88013A92B21A80002A02D109 -:100D3000044B08221A6070478C00002000440041D8 -:100D40008A00002098440041F0B591B008A9CE4A2D -:100D50000B1C31CA31C351CA51C360CA60C3CB4BEB -:100D6000CB489A687A255203520F92005258C949CB -:100D700002609C68A4B262430C60C74900240A6008 -:100D8000C64A1460C64C2570C64CC74D2368281C43 -:100D90001B6940219847002805D0C44B08221A60DF -:100DA000C34B64221A80C34B00221860C24B1D60E3 -:100DB000C24BC24DBF4F1A602A683B689A42E3D2C9 -:100DC000BD4B1B681A78FF2A00D120E2232A00D0ED -:100DD000F7E1BB4E3378002B06D0B24BB9491B6804 -:100DE0000222D868FFF716FFAD4B1B78532B3FD17B -:100DF0003B682A6893421ED9AF4801322A609A1A8A -:100E0000B14B01681B6801310160B04E9A4201D2BA -:100E1000326000E03360A14832680068049000F05E -:100E2000E9FB336829685A182A60A34A1668F11842 -:100E30001160A74A13702B68013B2B609E4B1A6808 -:100E4000013A1A60A24BA04A1B7811688B420DD25E -:100E500022689248C91A006892699047002805D014 -:100E6000924B08221A60924B64221A80C04696E187 -:100E7000522B0ED18948944A2368006811685B6937 -:100E800003909847934B802212055A616422924B3B -:100E90000DE04F2B05D1814B8B4A1B6812681A70ED -:100EA0007DE1482B05D17D4B874A1B6812681A806B -:100EB00075E1572B05D1794B834A1B6812681A607C -:100EC0006DE16F2B03D1754B0121186807E0682B8A -:100ED00008D1724B7C481B6802211B880360FFF716 -:100EE000C1FE5CE1772B06D16C4B77481B6804216F -:100EF0001B680360F3E7472B13D1734B1868FFF7A8 -:100F0000F1FE764B1B6883F3088862B6744B1B783E -:100F1000002B00D143E1634B06201B681B689847F8 -:100F20003DE1542B04D1012333705E4B1B6864E018 -:100F30004E2B0CD13378002B06D15A4B61491B68DC -:100F40000222D868FFF766FE0023337027E1562B94 -:100F500057D123686349D8680122FFF75BFE2368F5 -:100F60006149D8680322FFF755FE604D2368291CAC -:100F7000D8680122FFF74EFE23685D49D8680D222C -:100F8000FFF748FE2368291CD8680122FFF742FEBC -:100F9000494F4A4D5749002339602B603A1C281CA1 -:100FA00013685E1C16601B780593002B03D0036842 -:100FB00001330360F4E73B4E2A683368D868FFF7D3 -:100FC00029FE33684949D8680122FFF723FE0599B5 -:100FD000296049493960384A1368581C10601B78E9 -:100FE000002B04D0354B1A6801321A60F3E73368DE -:100FF0002A68D868FFF70EFE3368D86831490222A4 -:10100000CBE0314A582B17D1214E234D3668136857 -:101010002A68B10093420AD21C4D5808E86137484B -:1010200028801A4D287DC607FBD55B18F2E71D4BBB -:1010300033491B68D868AFE0592B00D07DE01268B7 -:10104000164B3049002A02D11B680B6070E00F4D2F -:10105000086819686B680D4E8025AB439208736071 -:10106000002A65D0284B094D2B80084E337DDD07C3 -:10107000FBD50023064D2D680195AD08AB4247D343 -:10108000224D024E35804AE07016000000400041BB -:101090004002002038020020340200208402002098 -:1010A00030020020880200204402002094440041C5 -:1010B0008A000020280200202C0200203C02002090 -:1010C00088000020D016000090020020940200202A -:1010D00024020020004400418C0000208C020020EB -:1010E00094000020AC160000D5160000AE160000DB -:1010F000F8160000B0160000BC16000002A5FFFFA5 -:10110000C51600009000002044A5FFFF04A5FFFFC6 -:101110009342B5D09D00465901334E51AAE7404E47 -:10112000357DEE07FBD59D0049194019D21A97E786 -:101130003C4B3D491B68D8682EE05A2B2FD13B4BC6 -:1011400017681D680026EF19BD4206D02878311CAB -:1011500000F014F90135061CF6E7324B34491B68E0 -:101160000122D868FFF756FD07230F223240111CD9 -:1011700036093031092A00DD07311820C0186A46C7 -:101180008154013BF1D2236806A9D8680822FFF7F1 -:1011900041FD23682749D8680322FFF73BFD264B12 -:1011A0007A221A70254B00221A60254B1B78934235 -:1011B0002DD01C4B23491B680122D868FFF72AFD5C -:1011C00025E0111C3039C8B21C4B092804D81D6811 -:1011D0002A01114319601AE0111C4139052903D86D -:1011E0001E68373A310106E0111C6139052904D81F -:1011F0001868573A01010A4308E02C2A03D10B4A28 -:101200001968116001E00C490A7000221A600E4B47 -:101210001A6801321A600D4B1A680132C9E5C046DE -:101220000040004188020020C9160000840200200E -:10123000CD160000CF1600003002002090020020E2 -:1012400088000020D31600003C0200202C02002061 -:1012500010B51C4B01201A78022402431A701A4B55 -:101260000F22197891431970197821431970174981 -:101270000C782043087019780A401A701A782021D7 -:101280000A431A70124B04211A6A0A431A62114B5C -:10129000114A5A805A7852B2002AFBDBC4220F4806 -:1012A0000F499203FEF730FF0E4A002313700E4AD7 -:1012B00013700E4A13700E4A13700E4A13700E4AC2 -:1012C000137010BD4A440041354400414B44004175 -:1012D00000040040000C00401440000000080042E0 -:1012E0002AF60000980200201F0300209902002027 -:1012F0009C020020200300201D03002008B5C1B27D -:101300000248FEF72FFF012008BDC046000800423A -:10131000024B187E4007C00F7047C04600080042CD -:1013200008B5FFF7F5FF0028FBD00248FEF720FFC5 -:1013300008BDC0460008004208B5FFF7E9FF0023DA -:10134000984205D0FFF7ECFF031C233B5A42534160 -:10135000181C08BD70B5041C0D1C4618B44204D0FE -:101360002078FFF7CBFF0134F8E7281C70BD10B5DB -:10137000041CFFF7D5FF2070012010BD0B0A584058 -:10138000034B4000C05A0902484080B27047C04633 -:1013900006170000F7B50024051C0F1C261CBC42D4 -:1013A00020D0FFF7BDFF114BC0B21B780190002B7E -:1013B0001AD1311CFFF7E2FF0D4B061C1A88002AD8 -:1013C00004D10C4A11782A1C002907D001996A1C03 -:1013D0002970802F02D11988013919800134A4B2F3 -:1013E000151CDCE7301C00E00120FEBD1D030020C1 -:1013F0009A0200201E030020F0B53E4E85B0002268 -:1014000003900C1C32703C4B914201D1012201E04F -:101410003A490C801A707F231C4201D080349C43CF -:10142000FFF77EFF3378C0B2002B07D00025357060 -:10143000FFF776FF3378C0B2AB4236D1432803D0F2 -:10144000712853D01528EBD1012300930120FFF719 -:1014500055FF0098FFF752FF00998025C843C0B29E -:10146000FFF74CFF039B00270293244A1388002BAD -:101470001DD1214901930978002918D10198FFF75E -:101480003DFF391C0198FFF779FF013D071C002D36 -:10149000EBD1000AC0B2FFF731FFF8B2FFF72EFF21 -:1014A000FFF73EFF3378002B0AD035701FE002991A -:1014B000013B09781380029B019101330293DDE720 -:1014C000C0B2062807D1009B03990133DBB28031FB -:1014D0000093803C0391002CB8D10420FFF70EFF4D -:1014E000FFF71EFF044B01251C7000E00025281C9F -:1014F00005B0F0BD1D0300201E0300209A0200204D -:10150000F0B5384C87B0002301902370994201D187 -:10151000012301E0344A1180344A642613704320C9 -:10152000FFF7ECFE324FFFF7F3FE002803D1002F48 -:1015300003D0013FF7E7002F03D1013E002EEED18B -:101540004DE00125FFF7ECFE2378002B38D1C0B227 -:101550000290012805D004283DD10620FFF7CEFED9 -:1015600039E005AE0221301CFFF714FF01988021FD -:10157000FFF710FF23780390002B18D1FFF7D0FE60 -:101580000702FFF7CDFEBFB223783F18BFB2012B91 -:101590000DD0039B9F4207D13378AB4204D1EB437C -:1015A0007278DBB29A4204D01820FFF7A7FE00231E -:1015B00003E00620FFF7A2FE029B2278002A02D059 -:1015C000002626700BE0012B05D1019A6B1C80329E -:1015D000DDB20192B6E7054A002313700126301CE4 -:1015E00007B0F0BD1D0300209A0200201E0300205A -:1015F00000350C0010B50023934203D0CC5CC454DA -:101600000133F9E710BD031C8218934202D0197010 -:101610000133FAE770470023C25C0133002AFBD193 -:10162000581E7047F8B5C046F8BC08BC9E467047C7 -:10163000F8B5C046F8BC08BC9E46704704030904D0 -:1016400041726475696E6F204C4C43004172647541 -:10165000696E6F205A65726F00000000120100026F -:101660000200004041234D00000201020001000081 -:1016700008000000100000002000000040000000F2 -:1016800080000000000100000002000000040000D3 -:10169000FD1200002113000011130000551300007B -:1016A0006F130000F9130000011500007600200000 -:1016B00044656320323020323031360031353A33E0 -:1016C000363A333900580A0D00590A0D005A0023E2 -:1016D0000A0D003E00322E30000000003D0B0000DD -:1016E000590B0000750B0000990B0000B50B0000B2 -:1016F000990B0000DD0B00005B41726475696E6F31 -:101700003A58595A5D00000021104220633084404D -:10171000A550C660E770088129914AA16BB18CC1C0 -:10172000ADD1CEE1EFF13112100273325222B55237 -:101730009442F772D662399318837BB35AA3BDD310 -:101740009CC3FFF3DEE36224433420040114E66407 -:10175000C774A44485546AA54BB528850995EEE560 -:10176000CFF5ACC58DD55336722611163006D77617 -:10177000F6669556B4465BB77AA719973887DFF7B0 -:10178000FEE79DD7BCC7C448E5588668A7784008DF -:10179000611802282338CCC9EDD98EE9AFF9488900 -:1017A00069990AA92BB9F55AD44AB77A966A711A77 -:1017B000500A333A122AFDDBDCCBBFFB9EEB799B50 -:1017C000588B3BBB1AABA66C877CE44CC55C222CC7 -:1017D000033C600C411CAEED8FFDECCDCDDD2AADA0 -:1017E0000BBD688D499D977EB66ED55EF44E133E57 -:1017F000322E511E700E9FFFBEEFDDDFFCCF1BBFF0 -:101800003AAF599F788F8891A981CAB1EBA10CD1C9 -:101810002DC14EF16FE18010A100C230E3200450D1 -:10182000254046706760B9839893FBA3DAB33DC344 -:101830001CD37FE35EF3B1029012F322D232354221 -:10184000145277625672EAB5CBA5A89589856EF5D4 -:101850004FE52CD50DC5E234C324A0148104667471 -:10186000476424540544DBA7FAB79987B8975FE724 -:101870007EF71DC73CD7D326F2369106B0165766C1 -:101880007676154634564CD96DC90EF92FE9C899AC -:10189000E9898AB9ABA94458654806782768C01811 -:1018A000E1088238A3287DCB5CDB3FEB1EFBF98B84 -:1018B000D89BBBAB9ABB754A545A376A167AF10A61 -:1018C000D01AB32A923A2EFD0FED6CDD4DCDAABD94 -:1018D0008BADE89DC98D267C076C645C454CA23CB1 -:1018E000832CE01CC10C1FEF3EFF5DCF7CDF9BAF64 -:1018F000BABFD98FF89F176E367E554E745E932E01 -:0C190000B23ED10EF01E000000000000FE -:10190C0001140000090243000201008032090400A6 -:10191C00000102020000052400100104240200054D -:10192C00240600010524010001070583030800FFBC -:10193C0009040100020A00000007058102400000B2 -:10194C00070502024000000000C201000000080070 -:0C195C00690000004100000000000000D5 -:0400000300000615DE +:10009000F81600005C000020540000200000000062 +:1000A00010B5C3699C07FCD403680224A343036012 +:1000B000C46901231C42FBD1046823430360036825 +:1000C000DC07FCD4C46901231C42FBD1C469DC40B9 +:1000D0001C42F7D1084B1A430260C3695A07FCD48B +:1000E000C0239B0243608181C3699C07FCD40368E1 +:1000F00002221343036010BD04000040037EDA07B0 +:10010000FCD5018570470000027E01235107FBD515 +:10011000428B1A4207D1428BDA401A4203D1428BFA +:1001200092081A4202D0034B01221A70008DC0B20D +:100130007047C0467400002070B50368041C988B9B +:100140001A1C0821FF32084228D0988B174D014312 +:10015000802099839872112353704021144B917120 +:1001600050715E68C0202E40800506435E605E6967 +:100170003540284358610F4818600F4818615D6882 +:100180000E4828408025AD02284358605868800BEF +:100190008003586000235171237105E0137ADA0659 +:1001A00002D5201C00F0A0FA207970BDFFFFFF8F60 +:1001B0008C0100208C0000200C010020FF3F00F08B +:1001C000002303714371044B016083600B780222AA +:1001D00013430B707047C0463901000038B5364BE9 +:1001E0002021DA6901200A43DA61344B06241A78A7 +:1001F00002431A70324B0F22197891431970197803 +:10020000214319702F490C782043087019780A404F +:100210001A701A7860210A431A702B4B2B4A5A80A5 +:100220005A7852B2002AFBDB294B01211A780A4383 +:100230001A709A78D107FCD426480268510B1F2205 +:100240001140914200D1052111408C011D8D2249A0 +:100250002940214319850468A10C0A401F2A00D1B6 +:100260001D221C8D1F210A408C4322431A850268DF +:100270000721D20D0A408A4200D103220A40188D7C +:100280001103164A02400A431A8519787F220A4050 +:100290001A701A78042112480A431A7058621A898F +:1002A0000C218A431A811A8901218A431A8100216B +:1002B000802201F0B6F838BD0004004058440041E7 +:1002C0003C44004159440041000C004006400000FD +:1002D00000500041246080003FF8FFFFFF8FFFFFC8 +:1002E0008C010020F7B5141C234A5F0101971D1CE7 +:1002F000D319061C5869271C4000400F03301033E7 +:10030000C74006D00F1C8022596812060A435A6063 +:1003100009E02F1C7B1E9F41184BBF01FF18381CA2 +:10032000221C01F075F8019913480835421817612D +:10033000131C5269A104920B890C92030A435A615F +:1003400059690F4A02200A405A616B01F318D979A2 +:10035000032211400143D8799043021C0A43DA7109 +:100360005979802252420A435A716B01F318DB79A2 +:100370009A07FAD5201CFEBD8C0100200C0100203C +:10038000FF3F00F0F8B51E4E041C3378151C002BFF +:1003900012D11C4B1C4A1A645A6C920B92035A6479 +:1003A000586C1A4A02405A64A2235B00E25C402067 +:1003B0000243E254012333704827FF37E25D0123F3 +:1003C00013401AD00F4B5A6C9204920CAA4202D2DC +:1003D0005D6CAD04AD0C081C2A1C0B4901F018F82B +:1003E000E25D03231A4001210A43E15D99430B1C9E +:1003F0001343E3550023337000E01D1C281CF8BD97 +:10040000750000208C010020CC000020FF3F00F090 +:10041000FF30827930239A43131C2022002900D117 +:1004200010221343837170470C4BFF305A6902212D +:10043000920B92035A61027A03231A400A43017A0B +:1004400099430B1C13430372827980235B4213434D +:100450008371037A9A07FCD57047C0468C0100204F +:1004600080235B421943C9B28172704770B5A023E3 +:1004700003225B00C254134B134A5C6CC02114402E +:1004800089050C4346255C64FF35402444550F4DD7 +:1004900030261D6490256D0046555D6B154029433F +:1004A000922559636D0080214155094D1D63B0258A +:1004B0006D0044555C6F22405A67B2235B00C15403 +:1004C00070BDC0468C010020FFFFFF8FCC000020D4 +:1004D0004C01002030B5364A1E235168082099434C +:1004E00002231943516033498A6902438A613248C1 +:1004F000324A9082908A03439382D3689807FCD54E +:100500002F4B012018701878C40704D52C48407868 +:1005100040B20028F7DB01209860587840B20028EC +:10052000FBDB284C26484460587840B20028FBDBAF +:1005300082242348E4014480587840B20028FBDB41 +:10054000908C8024A0439084D068C506FCD51E4CB6 +:100550001A48C462D4681948E506FBD5848C1B4D43 +:100560002C438484D4681548E506FBD5848C022589 +:100570002C438484D0680406FCD51048C068450626 +:10058000F8D5D068C406FCD500229A605A7852B2D9 +:10059000002AFBDB0E480A4A50605A7852B2002A01 +:1005A000FBDB00230B724B728B72CB7230BDC046EB +:1005B00000400041000400400C060000000800401C +:1005C000000C004001050100B805FF7D040A000091 +:1005D000000703000EBEFEE70DBEFEE705BEFEE708 +:1005E00002BEFEE701BEFEE70E4A0F4838B5824262 +:1005F00004D10E4A0E4B93420ED10AE00D4C9442A8 +:10060000F7D00023D1188842F3D9E55804330D60A0 +:10061000F8E700F011F804E09342FAD2002102C397 +:10062000FAE7FEE7000000205800002098030020B1 +:1006300058000020FC16000010B5244B0022197849 +:1006400001231940224B0AD11868224A904201D155 +:10065000196014E01A60204A013A002AFCD11A609D +:100660001E4B1968181C4A1C09D0FF22134206D1E0 +:1006700081F3088893431A4A936043681847FFF749 +:1006800029FF62B600F0F2FC00F0C8F9041CA36870 +:10069000201C9847134B002801D001221A701A78A9 +:1006A000002A05D0002000F035FA00F091FAFCE7AE +:1006B0001B78002BEBD100F04DFD0028E7D0012086 +:1006C00000F028FA00F084FAFCE7C0463804004045 +:1006D000FC7F00203581730748E8010000200000FE +:1006E00000ED00E076000020F8B50468051C201C31 +:1006F000FF30037AB64A10210B430372B54F1378CB +:10070000B5493B705378B54E0B7093783380D178F0 +:10071000338809020B4333801179B14B1980517929 +:100720001F8809020F431F809779AE490F80D27945 +:100730000F8812023A430A8040224271A648A54F10 +:1007400002783878A84F12020243181CBA4200D12E +:1007500099E01EDC802149008A4200D158E107DC83 +:10076000812A6AD0822A6ED0802A00D050E164E0CB +:1007700081235B009A4200D1AFE000DA23E1C0237D +:100780009B009A4200D143E1984B9A4200D11AE172 +:100790003EE190231B019A4242D015DCD023DB00BE +:1007A0009A4222D088231B019A4242D0A023DB0028 +:1007B0009A4200D02CE1201CFFF736FE31882868D1 +:1007C00089B2FFF74DFE27E1894B9A4200D1FAE04A +:1007D00000DC1DE1874B9A4200D1E8E0864B9A424B +:1007E00000D015E133886B71EDE033881B0A012BD3 +:1007F00008D10B8812222868934201D80A8892B245 +:100800007E49DCE033881B0A022B00D000E10B8814 +:1008100043222868934201D80A8892B27849CEE0F0 +:100820003388201C2B71FFF7FFFD201CFFF71EFEF5 +:10083000F2E0291C01C90122C1E0724900230B80AA +:1008400028680222BCE06F4900220A8018885022E2 +:1008500010406D4A10701E880F2030401880188894 +:10086000032800D9D4E012781B8808335B01E41810 +:10087000A379002A01D09B0600E0DB06DB0F0B808A +:10088000286802229BE019887F2291435E4AC9B200 +:10089000117018880F21014019803188002900D07B +:1008A000B6E01988002900D1B2E01988032900D9DF +:1008B000AEE012781B8808335B01E318002A05D0EC +:1008C0005A7930218A4320210A4304E05A793021A1 +:1008D0008A43102002435A7175E002887F239A43AD +:1008E000494BD2B21A7001880F220A400280328826 +:1008F000002A00D08CE00288002A00D188E002881B +:10090000032A00D984E01B78002B27D00388083302 +:100910005B01E3189B79990655D50388302108338C +:100920005B01E3181A798A4320210A431A7103886C +:1009300008335B01E318DB795A0644D5038860214C +:1009400008335B01E318DA798A4340210A43DA71FC +:100950000388022208335B01E31826E0038808338A +:100960005B01E3189B79DF062DD50388302108331E +:100970005B01E3181A798A4310210A431A7103882C +:1009800008335B01E318DB7999061CD503886021E5 +:1009900008335B01E318DA798A4320210A43DA71CC +:1009A0000388012208335B01E3181A710BE00B88FE +:1009B00008222868934201D80A8892B2134900237A +:1009C000FFF790FC28E0201CFFF72EFD24E0C04636 +:1009D0008C0000208100002077000020780000209B +:1009E0007C0000207E0000200203000001030000C4 +:1009F00021200000A1210000212200004C14000051 +:100A0000000000207A000020800000204400002028 +:100A1000201C0121FFF7FCFCF8BDC04610B5054BBA +:100A2000054C2360FFF7DAFB201C2168FFF7C8FBA9 +:100A3000201C10BD005000410C02002007B5054BE2 +:100A40000122019001A91868131CFFF74BFC01203B +:100A50000EBDC0460C02002013B5054B6C46073492 +:100A60001868211C0122FFF78DFC207816BDC046B6 +:100A70000C02002010B5074C201CFFF75DFB031C87 +:100A80000020834205D022684823FF33D05C012335 +:100A9000184010BD0C02002010B5054A0C1C031CA8 +:100AA000191C10680123221CFFF71CFC201C10BD20 +:100AB0000C02002070B5084C061C201C0D1CFFF712 +:100AC0003BFB0023984205D02068311C2A1CFFF70D +:100AD00059FC031C181C70BD0C020020F8B50C4C0E +:100AE000051C201C0E1CFFF727FB0023271C341CB1 +:100AF00098420AD0002C07D0291C221C3868FFF726 +:100B000041FC241A2D18F5E7331C181CF8BDC0460B +:100B10000C020020012805D1054B064A1A60064B3D +:100B2000187004E0002802D1044A014B1A60704793 +:100B30007C0200208014000089000020CC140000FA +:100B400030B51A4B85B01B78002B29D0042901D170 +:100B5000026804E0022901D1028800E0027849001D +:100B600004A843180B3B5C1AA3420BD00F20104083 +:100B7000092802D83025284300E0373018701209C0 +:100B8000013BF1E701A830230370782343700A2268 +:100B900043189A700D22DA70054B04311B6801E08E +:100BA000034B1B68DB68984705B030BD8800002008 +:100BB0007C02002072B6EFF30883044A13600368D6 +:100BC00083F30888436818477047C04680020020B6 +:100BD000F0B58FB006A9CD4A0B1C31CA31C351CA3A +:100BE00051C360CA60C3CA4CCA48A3687A255B0374 +:100BF0005B0F9B005B58C8490360A26892B25343E5 +:100C00000A60C649C64A0B6000231360C54B1D70BD +:100C1000C54BC64D1B68281C1B6940219847C44B17 +:100C200000221860C34B1D60C34BC34DC04F1A60F8 +:100C3000286839688842EBD2BE4B1B681A78FF2AB5 +:100C400000D1F7E1232A00D0CEE1BC4E3378002B4F +:100C500005D0B54BBA481B680221DB689847B14BF9 +:100C60001B78532B38D13B682A6893421ED9B14870 +:100C700001322A609A1AB34B01681B680131016086 +:100C8000B14E9A4201D2326000E03360A44832682B +:100C90000068029000F0BCFB336829685A182A608B +:100CA000A44A1668F1181160A84A13702B68013B1A +:100CB0002B60A04B1A68013A1A60A44BA14A1B781A +:100CC00011688B4206D2984A954812680068C91A82 +:100CD00092699047C04676E1522B07D1904A924BD9 +:100CE00010681B68974A5B6911686BE14F2B05D14F +:100CF0008B4B944A1B6812681A7064E1482B05D12B +:100D0000874B904A1B6812681A805CE1572B05D10B +:100D1000834B8C4A1B6812681A6054E16F2B03D115 +:100D20007F4B0121186807E0682B08D17C4B854870 +:100D30001B6802211B880360FFF702FF43E1772B4A +:100D400006D1774B7F481B6804211B680360F3E7DB +:100D5000472B13D17B4B1868FFF72CFF7C4B1B688C +:100D600083F3088862B67B4B1B78002B00D12AE105 +:100D70006D4B06201B681B68984724E1542B04D157 +:100D800001233370684B1B685CE04E2B0BD133782A +:100D9000002B05D1644B6A481B680221DB68984729 +:100DA000002333700FE1562B50D15F4D01212B688A +:100DB0006948DB6898472B680321DB6867489847D8 +:100DC000674E2B68301CDB68012198472B680D218A +:100DD000DB68644898472B68301CDB680121984722 +:100DE000544F614B544E3B60002333603A1C311C1E +:100DF0001368581C10601B780393002B03D00B68FA +:100E000001330B60F4E72B683168DB68564898477C +:100E10002B685348DB68012198470398306053489A +:100E20003860444A1368591C11601A78424B002AF2 +:100E300003D01A6801321A60F3E72A681968D36888 +:100E400098472B68DB683E480221BBE03D4A582B9F +:100E500015D1304E314D366813682A68B10093427F +:100E600008D25808E06142482080207DC507FCD5A3 +:100E70005B18F4E72C4B3F481B68DB68A1E0592B5B +:100E800033D11268264B3C49002A02D11B680B6003 +:100E900026E00868196863688025AB4392086360A0 +:100EA000002A1DD0354B2380237DDE07FCD500238F +:100EB000184D2D680095AD08AB4202D3304D25800A +:100EC00006E09342FAD09D00465901334E51EFE7B8 +:100ED000257DEE07FCD59D0049194019D21ADFE7A0 +:100EE000114B28481B68DB686BE05A2B6BD10C4B0D +:100EF00017681D680026EF19BD4245D02878311CBF +:100F000000F04AF90135061CF6E7C04660140000FF +:100F100000400041340200202C0200202802002062 +:100F200078020020240200207C02002038020020E9 +:100F30001C02002020020020300200208800002037 +:100F4000C014000084020020880200201802002043 +:100F500080020020890000209C140000C5140000BD +:100F60009E140000E8140000A0140000AC1400005F +:100F700002A5FFFFB51400008400002044A5FFFF78 +:100F800004A5FFFFB91400002E4D2F482B68012146 +:100F9000DB68984707230F223240111C3609303195 +:100FA000092A00DD07311020C0186A468154013B30 +:100FB000F1D22B6804A8DB68082198472B682348E6 +:100FC000DB6803219847224D7A232B70214B0022A6 +:100FD0001A60214B1B7893422CD01A4B01211B68BD +:100FE0001E48DB68984725E0111C3039C8B2194B00 +:100FF000092804D81E683201114319601AE0111C37 +:101000004139052903D81868373A010106E0111C57 +:101010006139052904D81D68573A29010A4308E0B7 +:101020002C2A03D10E4A1E68166001E008490A7096 +:1010300000221A600B4B1A6801321A600A4B1A68B8 +:101040000132F2E57C020020BD140000BF14000054 +:10105000240200208402002088000020C314000025 +:1010600078020020300200202002002010B51C4B26 +:1010700001201A78022402431A701A4B0F221978A1 +:101080009143197019782143197017490C7820433E +:10109000087019780A401A701A7820210A431A70C9 +:1010A000124B04211A6A0A431A62114B114A5A80E0 +:1010B0005A7852B2002AFBDBC4220F480F49920330 +:1010C000FEF7EEFF0E4A002313700E4A13700E4A0D +:1010D00013700E4A13700E4A13700E4A137010BD2F +:1010E0004A440041354400414B4400410004004063 +:1010F000000C0040144000000008004204C500003D +:101100008C020020130300208D020020900200209A +:10111000140300201103002008B5C1B20248FEF7F5 +:10112000EDFF012008BDC04600080042024B187EBA +:101130004007C00F7047C0460008004208B5FFF7DF +:10114000F5FF0028FBD00248FEF7DEFF08BDC046D1 +:101150000008004208B5FFF7E9FF0023984205D0D8 +:10116000FFF7ECFF031C233B5A425341181C08BDF8 +:1011700070B5041C0D1C4618B44204D02078FFF74B +:10118000CBFF0134F8E7281C70BD10B5041CFFF735 +:10119000D5FF2070012010BD0B0A5840034B4000C2 +:1011A000C05A0902484080B27047C046F614000099 +:1011B000F7B50024051C0F1C261CBC4220D0FFF7ED +:1011C000BDFF114BC0B21B780190002B1AD1311C0E +:1011D000FFF7E2FF0D4B061C1A88002A04D10C4AC7 +:1011E00011782A1C002907D001996A1C2970802FC8 +:1011F00002D11988013919800134A4B2151CDCE729 +:10120000301C00E00120FEBD110300208E020020F2 +:1012100012030020F0B53E4E85B0002203900C1C56 +:1012200032703C4B914201D1012201E03A490C80DD +:101230001A707F231C4201D080349C43FFF77EFF4D +:101240003378C0B2002B07D000253570FFF776FF4A +:101250003378C0B2AB4236D1432803D0712853D083 +:101260001528EBD1012300930120FFF755FF0098CB +:10127000FFF752FF00998025C843C0B2FFF74CFF2B +:10128000039B00270293244A1388002B1DD1214978 +:1012900001930978002918D10198FFF73DFF391C07 +:1012A0000198FFF779FF013D071C002DEBD1000AE3 +:1012B000C0B2FFF731FFF8B2FFF72EFFFFF73EFF96 +:1012C0003378002B0AD035701FE00299013B097872 +:1012D0001380029B019101330293DDE7C0B206281F +:1012E00007D1009B03990133DBB280310093803C2E +:1012F0000391002CB8D10420FFF70EFFFFF71EFF6B +:10130000044B01251C7000E00025281C05B0F0BD31 +:1013100011030020120300208E020020F0B5384C8B +:1013200087B0002301902370994201D1012301E08D +:10133000344A1180344A642613704320FFF7ECFED0 +:10134000324FFFF7F3FE002803D1002F03D0013FF7 +:10135000F7E7002F03D1013E002EEED14DE001252D +:10136000FFF7ECFE2378002B38D1C0B202900128A1 +:1013700005D004283DD10620FFF7CEFE39E005AEAA +:101380000221301CFFF714FF01988021FFF710FFA6 +:1013900023780390002B18D1FFF7D0FE0702FFF748 +:1013A000CDFEBFB223783F18BFB2012B0DD0039BF7 +:1013B0009F4207D13378AB4204D1EB437278DBB262 +:1013C0009A4204D01820FFF7A7FE002303E006206E +:1013D000FFF7A2FE029B2278002A02D00026267088 +:1013E0000BE0012B05D1019A6B1C8032DDB201921A +:1013F000B6E7054A002313700126301C07B0F0BD84 +:10140000110300208E0200201203002000350C0082 +:1014100010B50023934203D0CC5CC4540133F9E7E8 +:1014200010BD031C8218934202D019700133FAE7F1 +:1014300070470000F8B5C046F8BC08BC9E4670472F +:10144000F8B5C046F8BC08BC9E46704712010002C1 +:101450000200004041234D00000200000001000096 +:101460000800000010000000200000004000000004 +:1014700080000000000100000002000000040000E5 +:10148000191100003D1100002D1100007111000024 +:101490008B110000151200001D13000076002000C3 +:1014A0004F637420313020323031350031353A35D8 +:1014B000373A343500580A0D00590A0D005A0023F6 +:1014C0000A0D003E00322E30000000003D0A0000F0 +:1014D000590A0000750A0000990A0000B50A0000C8 +:1014E000990A0000DD0A00005B41726475696E6F45 +:1014F0003A58595A5D000000211042206330844060 +:10150000A550C660E770088129914AA16BB18CC1D2 +:10151000ADD1CEE1EFF13112100273325222B55249 +:101520009442F772D662399318837BB35AA3BDD322 +:101530009CC3FFF3DEE36224433420040114E66419 +:10154000C774A44485546AA54BB528850995EEE572 +:10155000CFF5ACC58DD55336722611163006D77629 +:10156000F6669556B4465BB77AA719973887DFF7C2 +:10157000FEE79DD7BCC7C448E5588668A7784008F1 +:10158000611802282338CCC9EDD98EE9AFF9488912 +:1015900069990AA92BB9F55AD44AB77A966A711A89 +:1015A000500A333A122AFDDBDCCBBFFB9EEB799B62 +:1015B000588B3BBB1AABA66C877CE44CC55C222CD9 +:1015C000033C600C411CAEED8FFDECCDCDDD2AADB2 +:1015D0000BBD688D499D977EB66ED55EF44E133E69 +:1015E000322E511E700E9FFFBEEFDDDFFCCF1BBF02 +:1015F0003AAF599F788F8891A981CAB1EBA10CD1DC +:101600002DC14EF16FE18010A100C230E3200450E3 +:10161000254046706760B9839893FBA3DAB33DC356 +:101620001CD37FE35EF3B1029012F322D232354233 +:10163000145277625672EAB5CBA5A89589856EF5E6 +:101640004FE52CD50DC5E234C324A0148104667483 +:10165000476424540544DBA7FAB79987B8975FE736 +:101660007EF71DC73CD7D326F2369106B0165766D3 +:101670007676154634564CD96DC90EF92FE9C899BE +:10168000E9898AB9ABA94458654806782768C01823 +:10169000E1088238A3287DCB5CDB3FEB1EFBF98B96 +:1016A000D89BBBAB9ABB754A545A376A167AF10A73 +:1016B000D01AB32A923A2EFD0FED6CDD4DCDAABDA6 +:1016C0008BADE89DC98D267C076C645C454CA23CC3 +:1016D000832CE01CC10C1FEF3EFF5DCF7CDF9BAF76 +:1016E000BABFD98FF89F176E367E554E745E932E13 +:0C16F000B23ED10EF01E00000000000011 +:1016FC0009024300020100803209040000010202C9 +:10170C000000052400100104240200052406000139 +:10171C000524010001070583030800FF09040100EB +:10172C00020A0000000705810240000007050202C2 +:10173C004000000000C20100000008006900000029 +:08174C00410000000000000054 +:04000003000005E90B :00000001FF diff --git a/bootloaders/zero/samd21_sam_ba_genuino.bin b/bootloaders/zero/samd21_sam_ba_genuino.bin old mode 100755 new mode 100644 index 35b766107..47cd3cf05 Binary files a/bootloaders/zero/samd21_sam_ba_genuino.bin and b/bootloaders/zero/samd21_sam_ba_genuino.bin differ diff --git a/bootloaders/zero/samd21_sam_ba_genuino.hex b/bootloaders/zero/samd21_sam_ba_genuino.hex index 84119520f..7e45320b7 100644 --- a/bootloaders/zero/samd21_sam_ba_genuino.hex +++ b/bootloaders/zero/samd21_sam_ba_genuino.hex @@ -1,409 +1,376 @@ -:10000000FC7F002015060000050600000906000020 +:10000000FC7F0020E9050000D5050000D9050000AF :1000100000000000000000000000000000000000E0 -:100020000000000000000000000000000D060000BD -:10003000000000000000000011060000650700003D +:10002000000000000000000000000000DD050000EE +:100030000000000000000000E1050000E5050000F0 :1000400010B5064C2378002B07D1054B002B02D0AE -:10005000044800E000BF0123237010BD5C000020B5 -:10006000000000000819000008B5084B002B03D061 +:10005000044800E000BF0123237010BD58000020B9 +:1000600000000000F816000008B5084B002B03D074 :100070000748084900E000BF07480368002B03D089 :10008000064B002B00D0984708BDC046000000007A -:100090000819000060000020580000200000000047 -:1000A000154A164B1178002909D115491878097895 -:1000B0004118C9B21970802012498002C8611178B4 -:1000C0000131C9B211701978F02902D819780929BB -:1000D00009D80B4908784042C0B2087018780978EE -:1000E0004118C9B2197012781B789A4203D1802244 -:1000F000044B9202DA617047780000200100002072 -:10010000000000200044004110B5C3699C07FCD4E6 -:1001100003680224A3430360C46901231C42FBD18A -:100120000468234303600368DC07FCD4C46901232B -:100130001C42FBD1C469DC401C42F7D1084B1A4376 -:100140000260C3695A07FCD4C0239B0243608181CB -:10015000C3699C07FCD4036802221343036010BDEB -:1001600004000040037EDA07FCD5018570470000DB -:10017000027E01235107FBD5428B1A4207D1428BE5 -:10018000DA401A4203D1428B92081A4202D0034B42 -:1001900001221A70008DC0B27047C046790000205D -:1001A00070B50368041C988B1A1C0821FF320842A2 -:1001B00026D0802099839872112353704021144BCC -:1001C000917150715E68134DC0202E40800506432A -:1001D0005E605E693540284358610F4818600F48DB -:1001E00018615D680E4828408025AD02284358609C -:1001F0005868800B8003586000235171237105E01B -:10020000137ADA0602D5201C00F0E6FA207970BDD8 -:1002100098010020FFFFFF8F9800002018010020A8 -:10022000FF3F00F0002303714371044B01608360C2 -:100230000B78022213430B707047C046A1010000E7 -:1002400038B5364B2021DA6901200A43DA61344B94 -:1002500006241A7802431A70324B0F221978914300 -:1002600019701978214319702F490C7820430870B0 -:1002700019780A401A701A7860210A431A702B4BB9 -:100280002B4A5A805A7852B2002AFBDB294B0121B3 -:100290001A780A431A709A78D107FCD42648026863 -:1002A000510B1F221140914200D1052111408C01B8 -:1002B0001D8D22492940214319850468A10C0A405B -:1002C0001F2A00D11D221C8D1F210A408C4322436E -:1002D0001A8502680721D20D0A408A4200D1032202 -:1002E0000A40188D1103164A02400A431A851978EC -:1002F0007F220A401A701A78042112480A431A70A1 -:1003000058621A890C218A431A811A8901218A4369 -:100310001A810021802201F076F938BD00040040E6 -:10032000584400413C44004159440041000C004005 -:100330000640000000500041246080003FF8FFFFAD -:10034000FF8FFFFF98010020F7B5141C1F4A5F01C3 -:1003500001971D1CD319061C5869271C4000400F2B -:1003600003301033C74006D00F1C80225968120694 -:100370000A435A6009E02F1C7B1E9F41144BBF01AA -:10038000FF18381C221C01F035F901990F48083577 -:1003900042181761131C5269A104920B890C920335 -:1003A0000A435A6159690B4A0A405A616B01F318B2 -:1003B0000222DA715979802252420A435A716B0142 -:1003C000F318DB799A07FAD5201CFEBD98010020AE -:1003D00018010020FF3F00F0F8B51A4E051C3378D5 -:1003E000141C002B12D1184B184A1A645A6C920B29 -:1003F00092035A64586C164A02405A64A2235B0066 -:10040000EA5C40200243EA54012333704827FF3757 -:10041000EA5D0123134012D00B4B5A6C9204920CEC -:10042000A24202D25C6CA404A40C081C221C074942 -:1004300001F0E0F80123EB550023337000E01C1CB1 -:10044000201CF8BD7A00002098010020D800002070 -:10045000FF3F00F0FF3083792022002900D11022D5 -:100460001343837170470000084BFF305A69920BA9 -:1004700092035A6102230372827980235B42134301 -:100480008371037A9A07FCD57047C0469801002013 -:1004900080235B421943C9B28172704770B5A023B3 -:1004A00003225B00C254134B134A5C6CC0211440FE -:1004B00089050C4346255C64FF35402444550F4DA7 -:1004C00030261D6490256D0046555D6B154029430F -:1004D000922559636D0080214155094D1D63B0255A -:1004E0006D0044555C6F22405A67B2235B00C154D3 -:1004F00070BDC04698010020FFFFFF8FD80000208C -:100500005801002030B5364A1E235168082099430F -:1005100002231943516033498A6902438A61324890 -:10052000324A9082908A03439382D3689807FCD51D -:100530002F4B012018701878C40704D52C48407838 -:1005400040B20028F7DB01209860587840B20028BC -:10055000FBDB284C26484460587840B20028FBDB7F -:1005600082242348E4014480587840B20028FBDB11 -:10057000908C8024A0439084D068C506FCD51E4C86 -:100580001A48C462D4681948E506FBD5848C1B4D13 -:100590002C438484D4681548E506FBD5848C022559 -:1005A0002C438484D0680406FCD51048C0684506F6 -:1005B000F8D5D068C406FCD500229A605A7852B2A9 -:1005C000002AFBDB0E480A4A50605A7852B2002AD1 -:1005D000FBDB00230B724B728B72CB7230BDC046BB -:1005E00000400041000400400C06000000080040EC -:1005F000000C004001050100B805FF7D040A000061 -:10060000000703000EBEFEE70DBEFEE705BEFEE7D7 -:1006100002BEFEE70E4A0F4838B5824204D10E4AA8 -:100620000E4B93420ED10AE00D4C9442F7D00023BA -:10063000D1188842F3D9E55804330D60F8E700F08B -:1006400011F804E09342FAD2002102C3FAE7FEE770 -:10065000000000205C000020A40300205C000020BB -:100660000C190000334A38B51368141C01331ED02E -:10067000D1B200291BD1304B1878012318402F4BE1 -:100680000AD11D682E498D4201D118600FE0196012 -:100690002C4901390029FCD11960236883F30888AB -:1006A000FF239A43284B9A60224B5B681847FFF759 -:1006B00029FF62B600F0CCFD00F05AF8234B8022EF -:1006C000920223499A6008220A602249041C0A60A7 -:1006D000802212059A609A611F4B204AC0215A60FD -:1006E000194A0906106A0002000A01431162002239 -:1006F0009A6007221A60A368201C9847184B0028AC -:1007000001D001221A701A78002A05D0002000F0CA -:1007100093FA00F019FBFCE71B78002BEBD100F0FB -:100720000BFE0028E7D0012000F086FA00F00CFB59 -:10073000FCE7C0460020000038040040FC7F002099 -:100740003581730748E8010000ED00E000440041F6 -:10075000884400419844004110E000E0E7030000B5 -:100760007B00002008B5FFF79BFC00F0C9FA08BD2C -:1007700010B5054B054C2360FFF762FD201C216876 -:10078000FFF750FD201C10BD005000411802002052 -:1007900070B5051CC0B0081C161C0C1C00F03BFFFB -:1007A00040006A460323023053701070760801231C -:1007B000E218013A11785A00002906D1281C69462E -:1007C0000023FFF7C1FD40B070BDB342F6DA6846C2 -:1007D00081520133ECE70000F7B5BA4A0468137898 -:1007E000B949271CFF37051C102038720B7053784D -:1007F000B648B74E037093783380D17833880902B6 -:100800000B4333801179B34B198051791888090251 -:10081000084318809079B0490880D279088812027C -:1008200002430A8040227A71A84F3A78A64F1202FA -:1008300038780F1C0243A9488446181C624500D131 -:10084000C2E020DC802149008A4200D16EE109DC4F -:10085000812A00D192E0822A00D195E0802A00D03E -:1008600064E18BE081235B009A4200D1CFE000DAA3 -:1008700058E1C0239B009A4200D157E1984B9A421D -:1008800000D14FE152E190231B019A4269D015DC5F -:10089000D023DB009A4222D088231B019A4269D0E0 -:1008A000A023DB009A4200D040E1201CFFF7DCFDD2 -:1008B0003188286889B2FFF7EBFD3BE1894B9A420A -:1008C00000D12FE100DC31E1874B9A4200D11DE1DC -:1008D000864B9A4200D029E133886B7122E133883C -:1008E0001B0A012B08D10B8812222868934201D8D9 -:1008F0000A8892B27E4911E133881B0A022B08D183 -:100900000B8843222868934201D80A8892B2794919 -:1009100004E133881B0A032B00D007E13388DBB2E4 -:10092000012B17D0002B07D0022B00D0FEE00A8845 -:100930002868D2B2704911E0042201A86F4900F082 -:1009400059FE3B8804222868934201D83A8892B223 -:1009500001A9E3E00A8828686949D2B2FFF718FFC5 -:10096000E8E03388201C2B71FFF77EFD201CFFF789 -:1009700095FDDFE0291C01C90122CFE06149002378 -:100980000B8028680222CAE05E4900220A8018888B -:10099000502210405C4A10701E880F203040188092 -:1009A0001888032800D9C1E012781B8808335B013E -:1009B000E418A379002A01D09B0600E0DB06DB0FD8 -:1009C0000B8028680222A9E019887F2291434E4AB1 -:1009D000C9B2117018880F2101401980318800298F -:1009E00000D0A3E01988002900D19FE019880329CD -:1009F00000D99BE012781B8808335B01E318002ABA -:100A000002D020225A718DE0102159718AE00288AB -:100A10007F239A433C4BD2B21A7001880F220A40BE -:100A200002803288002A00D080E00288002A00D1AB -:100A30007CE00288032A00D978E01B78002B1FD0C5 -:100A4000038808335B01E3189B799A066AD503880B -:100A5000202208335B01E3181A71038808335B0115 -:100A6000E318DB795F065DD50388402208335B011C -:100A7000E318DA710388022208335B01E3181EE0F1 -:100A8000038808335B01E3189B79D9064AD50388AC -:100A9000102208335B01E3181A71038808335B01E5 -:100AA000E318DB799A063DD50388202208335B01E1 -:100AB000E318DA710388012208335B01E3181A7125 -:100AC00030E0C046980000207D0000208200002019 -:100AD0008400002086000020800000200203000027 -:100AE0000103000021200000A121000021220000BC -:100AF0005C160000040000204C1600003C160000AC -:100B0000401600007E0000207C0000200B88082298 -:100B10002868934201D80A8892B207490023FFF758 -:100B200013FC07E0201CFFF79FFC03E0201C0121C1 -:100B3000FFF790FCF7BDC0464800002007B5054B05 -:100B40000122019001A91868131CFFF7FDFB012089 -:100B50000EBDC0461802002013B5054B6C46073485 -:100B60001868211C0122FFF737FC207816BDC0460B -:100B70001802002010B5074C201CFFF711FB031CC6 -:100B80000020834205D022684823FF33D05C012334 -:100B9000184010BD1802002010B5054A0C1C031C9B -:100BA000191C10680123221CFFF7CEFB201C10BD6E -:100BB0001802002070B5084C061C201C0D1CFFF705 -:100BC000EFFA0023984205D02068311C2A1CFFF759 -:100BD00003FC031C181C70BD18020020F8B50C4C57 -:100BE000051C201C0E1CFFF7DBFA0023271C341CFD -:100BF00098420AD0002C07D0291C221C3868FFF725 -:100C0000EBFB241A2D18F5E7331C181CF8BDC04661 -:100C10001802002008B5031C081C111C9847044B3F -:100C2000802212055A61034B64221A8008BDC04617 -:100C3000004400418C000020012805D1054B064AE4 -:100C40001A60064B187004E0002802D1044A014BD8 -:100C50001A6070478802002090160000940000205F -:100C6000DC16000030B50A1C1C4985B00978031C4D -:100C700000292AD0042A01D1006804E0022A01D107 -:100C8000008800E00078520004A98B180B3B9C1AE6 -:100C9000A3420BD00F210140092902D83025294356 -:100CA00000E0373119700009013BF1E701A9302359 -:100CB0000B7078234B700A208B1898700D20D87019 -:100CC000074B04321B68D86803E005490968C86807 -:100CD000191CFFF79FFF05B030BDC04688000020FB -:100CE0008802002072B6EFF30883044A1360036899 -:100CF00083F30888436818477047C0468C02002079 -:100D00000D4B1A88002A09D01A88013A92B21A802B -:100D1000002A03D18022094B12059A61084B1A88D8 -:100D2000002A08D01A88013A92B21A80002A02D109 -:100D3000044B08221A6070478C00002000440041D8 -:100D40008A00002098440041F0B591B008A9CE4A2D -:100D50000B1C31CA31C351CA51C360CA60C3CB4BEB -:100D6000CB489A687A255203520F92005258C949CB -:100D700002609C68A4B262430C60C74900240A6008 -:100D8000C64A1460C64C2570C64CC74D2368281C43 -:100D90001B6940219847002805D0C44B08221A60DF -:100DA000C34B64221A80C34B00221860C24B1D60E3 -:100DB000C24BC24DBF4F1A602A683B689A42E3D2C9 -:100DC000BD4B1B681A78FF2A00D120E2232A00D0ED -:100DD000F7E1BB4E3378002B06D0B24BB9491B6804 -:100DE0000222D868FFF716FFAD4B1B78532B3FD17B -:100DF0003B682A6893421ED9AF4801322A609A1A8A -:100E0000B14B01681B6801310160B04E9A4201D2BA -:100E1000326000E03360A14832680068049000F05E -:100E2000E9FB336829685A182A60A34A1668F11842 -:100E30001160A74A13702B68013B2B609E4B1A6808 -:100E4000013A1A60A24BA04A1B7811688B420DD25E -:100E500022689248C91A006892699047002805D014 -:100E6000924B08221A60924B64221A80C04696E187 -:100E7000522B0ED18948944A2368006811685B6937 -:100E800003909847934B802212055A616422924B3B -:100E90000DE04F2B05D1814B8B4A1B6812681A70ED -:100EA0007DE1482B05D17D4B874A1B6812681A806B -:100EB00075E1572B05D1794B834A1B6812681A607C -:100EC0006DE16F2B03D1754B0121186807E0682B8A -:100ED00008D1724B7C481B6802211B880360FFF716 -:100EE000C1FE5CE1772B06D16C4B77481B6804216F -:100EF0001B680360F3E7472B13D1734B1868FFF7A8 -:100F0000F1FE764B1B6883F3088862B6744B1B783E -:100F1000002B00D143E1634B06201B681B689847F8 -:100F20003DE1542B04D1012333705E4B1B6864E018 -:100F30004E2B0CD13378002B06D15A4B61491B68DC -:100F40000222D868FFF766FE0023337027E1562B94 -:100F500057D123686349D8680122FFF75BFE2368F5 -:100F60006149D8680322FFF755FE604D2368291CAC -:100F7000D8680122FFF74EFE23685D49D8680D222C -:100F8000FFF748FE2368291CD8680122FFF742FEBC -:100F9000494F4A4D5749002339602B603A1C281CA1 -:100FA00013685E1C16601B780593002B03D0036842 -:100FB00001330360F4E73B4E2A683368D868FFF7D3 -:100FC00029FE33684949D8680122FFF723FE0599B5 -:100FD000296049493960384A1368581C10601B78E9 -:100FE000002B04D0354B1A6801321A60F3E73368DE -:100FF0002A68D868FFF70EFE3368D86831490222A4 -:10100000CBE0314A582B17D1214E234D3668136857 -:101010002A68B10093420AD21C4D5808E86137484B -:1010200028801A4D287DC607FBD55B18F2E71D4BBB -:1010300033491B68D868AFE0592B00D07DE01268B7 -:10104000164B3049002A02D11B680B6070E00F4D2F -:10105000086819686B680D4E8025AB439208736071 -:10106000002A65D0284B094D2B80084E337DDD07C3 -:10107000FBD50023064D2D680195AD08AB4247D343 -:10108000224D024E35804AE07016000000400041BB -:101090004002002038020020340200208402002098 -:1010A00030020020880200204402002094440041C5 -:1010B0008A000020280200202C0200203C02002090 -:1010C00088000020D016000090020020940200202A -:1010D00024020020004400418C0000208C020020EB -:1010E00094000020AC160000D5160000AE160000DB -:1010F000F8160000B0160000BC16000002A5FFFFA5 -:10110000C51600009000002044A5FFFF04A5FFFFC6 -:101110009342B5D09D00465901334E51AAE7404E47 -:10112000357DEE07FBD59D0049194019D21A97E786 -:101130003C4B3D491B68D8682EE05A2B2FD13B4BC6 -:1011400017681D680026EF19BD4206D02878311CAB -:1011500000F014F90135061CF6E7324B34491B68E0 -:101160000122D868FFF756FD07230F223240111CD9 -:1011700036093031092A00DD07311820C0186A46C7 -:101180008154013BF1D2236806A9D8680822FFF7F1 -:1011900041FD23682749D8680322FFF73BFD264B12 -:1011A0007A221A70254B00221A60254B1B78934235 -:1011B0002DD01C4B23491B680122D868FFF72AFD5C -:1011C00025E0111C3039C8B21C4B092804D81D6811 -:1011D0002A01114319601AE0111C4139052903D86D -:1011E0001E68373A310106E0111C6139052904D81F -:1011F0001868573A01010A4308E02C2A03D10B4A28 -:101200001968116001E00C490A7000221A600E4B47 -:101210001A6801321A600D4B1A680132C9E5C046DE -:101220000040004188020020C9160000840200200E -:10123000CD160000CF1600003002002090020020E2 -:1012400088000020D31600003C0200202C02002061 -:1012500010B51C4B01201A78022402431A701A4B55 -:101260000F22197891431970197821431970174981 -:101270000C782043087019780A401A701A782021D7 -:101280000A431A70124B04211A6A0A431A62114B5C -:10129000114A5A805A7852B2002AFBDBC4220F4806 -:1012A0000F499203FEF730FF0E4A002313700E4AD7 -:1012B00013700E4A13700E4A13700E4A13700E4AC2 -:1012C000137010BD4A440041354400414B44004175 -:1012D00000040040000C00401440000000080042E0 -:1012E0002AF60000980200201F0300209902002027 -:1012F0009C020020200300201D03002008B5C1B27D -:101300000248FEF72FFF012008BDC046000800423A -:10131000024B187E4007C00F7047C04600080042CD -:1013200008B5FFF7F5FF0028FBD00248FEF720FFC5 -:1013300008BDC0460008004208B5FFF7E9FF0023DA -:10134000984205D0FFF7ECFF031C233B5A42534160 -:10135000181C08BD70B5041C0D1C4618B44204D0FE -:101360002078FFF7CBFF0134F8E7281C70BD10B5DB -:10137000041CFFF7D5FF2070012010BD0B0A584058 -:10138000034B4000C05A0902484080B27047C04633 -:1013900006170000F7B50024051C0F1C261CBC42D4 -:1013A00020D0FFF7BDFF114BC0B21B780190002B7E -:1013B0001AD1311CFFF7E2FF0D4B061C1A88002AD8 -:1013C00004D10C4A11782A1C002907D001996A1C03 -:1013D0002970802F02D11988013919800134A4B2F3 -:1013E000151CDCE7301C00E00120FEBD1D030020C1 -:1013F0009A0200201E030020F0B53E4E85B0002268 -:1014000003900C1C32703C4B914201D1012201E04F -:101410003A490C801A707F231C4201D080349C43CF -:10142000FFF77EFF3378C0B2002B07D00025357060 -:10143000FFF776FF3378C0B2AB4236D1432803D0F2 -:10144000712853D01528EBD1012300930120FFF719 -:1014500055FF0098FFF752FF00998025C843C0B29E -:10146000FFF74CFF039B00270293244A1388002BAD -:101470001DD1214901930978002918D10198FFF75E -:101480003DFF391C0198FFF779FF013D071C002D36 -:10149000EBD1000AC0B2FFF731FFF8B2FFF72EFF21 -:1014A000FFF73EFF3378002B0AD035701FE002991A -:1014B000013B09781380029B019101330293DDE720 -:1014C000C0B2062807D1009B03990133DBB28031FB -:1014D0000093803C0391002CB8D10420FFF70EFF4D -:1014E000FFF71EFF044B01251C7000E00025281C9F -:1014F00005B0F0BD1D0300201E0300209A0200204D -:10150000F0B5384C87B0002301902370994201D187 -:10151000012301E0344A1180344A642613704320C9 -:10152000FFF7ECFE324FFFF7F3FE002803D1002F48 -:1015300003D0013FF7E7002F03D1013E002EEED18B -:101540004DE00125FFF7ECFE2378002B38D1C0B227 -:101550000290012805D004283DD10620FFF7CEFED9 -:1015600039E005AE0221301CFFF714FF01988021FD -:10157000FFF710FF23780390002B18D1FFF7D0FE60 -:101580000702FFF7CDFEBFB223783F18BFB2012B91 -:101590000DD0039B9F4207D13378AB4204D1EB437C -:1015A0007278DBB29A4204D01820FFF7A7FE00231E -:1015B00003E00620FFF7A2FE029B2278002A02D059 -:1015C000002626700BE0012B05D1019A6B1C80329E -:1015D000DDB20192B6E7054A002313700126301CE4 -:1015E00007B0F0BD1D0300209A0200201E0300205A -:1015F00000350C0010B50023934203D0CC5CC454DA -:101600000133F9E710BD031C8218934202D0197010 -:101610000133FAE770470023C25C0133002AFBD193 -:10162000581E7047F8B5C046F8BC08BC9E467047C7 -:10163000F8B5C046F8BC08BC9E46704704030904D0 -:1016400041726475696E6F204C4C430047656E753E -:10165000696E6F205A65726F00000000120100026F -:101660000200004041234D0200020102000100007F -:1016700008000000100000002000000040000000F2 -:1016800080000000000100000002000000040000D3 -:10169000FD1200002113000011130000551300007B -:1016A0006F130000F9130000011500007600200000 -:1016B00044656320323020323031360031353A33E0 -:1016C000363A343100580A0D00590A0D005A0023E9 -:1016D0000A0D003E00322E30000000003D0B0000DD -:1016E000590B0000750B0000990B0000B50B0000B2 -:1016F000990B0000DD0B00005B41726475696E6F31 -:101700003A58595A5D00000021104220633084404D -:10171000A550C660E770088129914AA16BB18CC1C0 -:10172000ADD1CEE1EFF13112100273325222B55237 -:101730009442F772D662399318837BB35AA3BDD310 -:101740009CC3FFF3DEE36224433420040114E66407 -:10175000C774A44485546AA54BB528850995EEE560 -:10176000CFF5ACC58DD55336722611163006D77617 -:10177000F6669556B4465BB77AA719973887DFF7B0 -:10178000FEE79DD7BCC7C448E5588668A7784008DF -:10179000611802282338CCC9EDD98EE9AFF9488900 -:1017A00069990AA92BB9F55AD44AB77A966A711A77 -:1017B000500A333A122AFDDBDCCBBFFB9EEB799B50 -:1017C000588B3BBB1AABA66C877CE44CC55C222CC7 -:1017D000033C600C411CAEED8FFDECCDCDDD2AADA0 -:1017E0000BBD688D499D977EB66ED55EF44E133E57 -:1017F000322E511E700E9FFFBEEFDDDFFCCF1BBFF0 -:101800003AAF599F788F8891A981CAB1EBA10CD1C9 -:101810002DC14EF16FE18010A100C230E3200450D1 -:10182000254046706760B9839893FBA3DAB33DC344 -:101830001CD37FE35EF3B1029012F322D232354221 -:10184000145277625672EAB5CBA5A89589856EF5D4 -:101850004FE52CD50DC5E234C324A0148104667471 -:10186000476424540544DBA7FAB79987B8975FE724 -:101870007EF71DC73CD7D326F2369106B0165766C1 -:101880007676154634564CD96DC90EF92FE9C899AC -:10189000E9898AB9ABA94458654806782768C01811 -:1018A000E1088238A3287DCB5CDB3FEB1EFBF98B84 -:1018B000D89BBBAB9ABB754A545A376A167AF10A61 -:1018C000D01AB32A923A2EFD0FED6CDD4DCDAABD94 -:1018D0008BADE89DC98D267C076C645C454CA23CB1 -:1018E000832CE01CC10C1FEF3EFF5DCF7CDF9BAF64 -:1018F000BABFD98FF89F176E367E554E745E932E01 -:0C190000B23ED10EF01E000000000000FE -:10190C0001140000090243000201008032090400A6 -:10191C00000102020000052400100104240200054D -:10192C00240600010524010001070583030800FFBC -:10193C0009040100020A00000007058102400000B2 -:10194C00070502024000000000C201000000080070 -:0C195C00690000004100000000000000D5 -:0400000300000615DE +:10009000F81600005C000020540000200000000062 +:1000A00010B5C3699C07FCD403680224A343036012 +:1000B000C46901231C42FBD1046823430360036825 +:1000C000DC07FCD4C46901231C42FBD1C469DC40B9 +:1000D0001C42F7D1084B1A430260C3695A07FCD48B +:1000E000C0239B0243608181C3699C07FCD40368E1 +:1000F00002221343036010BD04000040037EDA07B0 +:10010000FCD5018570470000027E01235107FBD515 +:10011000428B1A4207D1428BDA401A4203D1428BFA +:1001200092081A4202D0034B01221A70008DC0B20D +:100130007047C0467400002070B50368041C988B9B +:100140001A1C0821FF32084228D0988B174D014312 +:10015000802099839872112353704021144B917120 +:1001600050715E68C0202E40800506435E605E6967 +:100170003540284358610F4818600F4818615D6882 +:100180000E4828408025AD02284358605868800BEF +:100190008003586000235171237105E0137ADA0659 +:1001A00002D5201C00F0A0FA207970BDFFFFFF8F60 +:1001B0008C0100208C0000200C010020FF3F00F08B +:1001C000002303714371044B016083600B780222AA +:1001D00013430B707047C0463901000038B5364BE9 +:1001E0002021DA6901200A43DA61344B06241A78A7 +:1001F00002431A70324B0F22197891431970197803 +:10020000214319702F490C782043087019780A404F +:100210001A701A7860210A431A702B4B2B4A5A80A5 +:100220005A7852B2002AFBDB294B01211A780A4383 +:100230001A709A78D107FCD426480268510B1F2205 +:100240001140914200D1052111408C011D8D2249A0 +:100250002940214319850468A10C0A401F2A00D1B6 +:100260001D221C8D1F210A408C4322431A850268DF +:100270000721D20D0A408A4200D103220A40188D7C +:100280001103164A02400A431A8519787F220A4050 +:100290001A701A78042112480A431A7058621A898F +:1002A0000C218A431A811A8901218A431A8100216B +:1002B000802201F0B6F838BD0004004058440041E7 +:1002C0003C44004159440041000C004006400000FD +:1002D00000500041246080003FF8FFFFFF8FFFFFC8 +:1002E0008C010020F7B5141C234A5F0101971D1CE7 +:1002F000D319061C5869271C4000400F03301033E7 +:10030000C74006D00F1C8022596812060A435A6063 +:1003100009E02F1C7B1E9F41184BBF01FF18381CA2 +:10032000221C01F075F8019913480835421817612D +:10033000131C5269A104920B890C92030A435A615F +:1003400059690F4A02200A405A616B01F318D979A2 +:10035000032211400143D8799043021C0A43DA7109 +:100360005979802252420A435A716B01F318DB79A2 +:100370009A07FAD5201CFEBD8C0100200C0100203C +:10038000FF3F00F0F8B51E4E041C3378151C002BFF +:1003900012D11C4B1C4A1A645A6C920B92035A6479 +:1003A000586C1A4A02405A64A2235B00E25C402067 +:1003B0000243E254012333704827FF37E25D0123F3 +:1003C00013401AD00F4B5A6C9204920CAA4202D2DC +:1003D0005D6CAD04AD0C081C2A1C0B4901F018F82B +:1003E000E25D03231A4001210A43E15D99430B1C9E +:1003F0001343E3550023337000E01D1C281CF8BD97 +:10040000750000208C010020CC000020FF3F00F090 +:10041000FF30827930239A43131C2022002900D117 +:1004200010221343837170470C4BFF305A6902212D +:10043000920B92035A61027A03231A400A43017A0B +:1004400099430B1C13430372827980235B4213434D +:100450008371037A9A07FCD57047C0468C0100204F +:1004600080235B421943C9B28172704770B5A023E3 +:1004700003225B00C254134B134A5C6CC02114402E +:1004800089050C4346255C64FF35402444550F4DD7 +:1004900030261D6490256D0046555D6B154029433F +:1004A000922559636D0080214155094D1D63B0258A +:1004B0006D0044555C6F22405A67B2235B00C15403 +:1004C00070BDC0468C010020FFFFFF8FCC000020D4 +:1004D0004C01002030B5364A1E235168082099434C +:1004E00002231943516033498A6902438A613248C1 +:1004F000324A9082908A03439382D3689807FCD54E +:100500002F4B012018701878C40704D52C48407868 +:1005100040B20028F7DB01209860587840B20028EC +:10052000FBDB284C26484460587840B20028FBDBAF +:1005300082242348E4014480587840B20028FBDB41 +:10054000908C8024A0439084D068C506FCD51E4CB6 +:100550001A48C462D4681948E506FBD5848C1B4D43 +:100560002C438484D4681548E506FBD5848C022589 +:100570002C438484D0680406FCD51048C068450626 +:10058000F8D5D068C406FCD500229A605A7852B2D9 +:10059000002AFBDB0E480A4A50605A7852B2002A01 +:1005A000FBDB00230B724B728B72CB7230BDC046EB +:1005B00000400041000400400C060000000800401C +:1005C000000C004001050100B805FF7D040A000091 +:1005D000000703000EBEFEE70DBEFEE705BEFEE708 +:1005E00002BEFEE701BEFEE70E4A0F4838B5824262 +:1005F00004D10E4A0E4B93420ED10AE00D4C9442A8 +:10060000F7D00023D1188842F3D9E55804330D60A0 +:10061000F8E700F011F804E09342FAD2002102C397 +:10062000FAE7FEE7000000205800002098030020B1 +:1006300058000020FC16000010B5244B0022197849 +:1006400001231940224B0AD11868224A904201D155 +:10065000196014E01A60204A013A002AFCD11A609D +:100660001E4B1968181C4A1C09D0FF22134206D1E0 +:1006700081F3088893431A4A936043681847FFF749 +:1006800029FF62B600F0F2FC00F0C8F9041CA36870 +:10069000201C9847134B002801D001221A701A78A9 +:1006A000002A05D0002000F035FA00F091FAFCE7AE +:1006B0001B78002BEBD100F04DFD0028E7D0012086 +:1006C00000F028FA00F084FAFCE7C0463804004045 +:1006D000FC7F00203581730748E8010000200000FE +:1006E00000ED00E076000020F8B50468051C201C31 +:1006F000FF30037AB64A10210B430372B54F1378CB +:10070000B5493B705378B54E0B7093783380D178F0 +:10071000338809020B4333801179B14B1980517929 +:100720001F8809020F431F809779AE490F80D27945 +:100730000F8812023A430A8040224271A648A54F10 +:1007400002783878A84F12020243181CBA4200D12E +:1007500099E01EDC802149008A4200D158E107DC83 +:10076000812A6AD0822A6ED0802A00D050E164E0CB +:1007700081235B009A4200D1AFE000DA23E1C0237D +:100780009B009A4200D143E1984B9A4200D11AE172 +:100790003EE190231B019A4242D015DCD023DB00BE +:1007A0009A4222D088231B019A4242D0A023DB0028 +:1007B0009A4200D02CE1201CFFF736FE31882868D1 +:1007C00089B2FFF74DFE27E1894B9A4200D1FAE04A +:1007D00000DC1DE1874B9A4200D1E8E0864B9A424B +:1007E00000D015E133886B71EDE033881B0A012BD3 +:1007F00008D10B8812222868934201D80A8892B245 +:100800007E49DCE033881B0A022B00D000E10B8814 +:1008100043222868934201D80A8892B27849CEE0F0 +:100820003388201C2B71FFF7FFFD201CFFF71EFEF5 +:10083000F2E0291C01C90122C1E0724900230B80AA +:1008400028680222BCE06F4900220A8018885022E2 +:1008500010406D4A10701E880F2030401880188894 +:10086000032800D9D4E012781B8808335B01E41810 +:10087000A379002A01D09B0600E0DB06DB0F0B808A +:10088000286802229BE019887F2291435E4AC9B200 +:10089000117018880F21014019803188002900D07B +:1008A000B6E01988002900D1B2E01988032900D9DF +:1008B000AEE012781B8808335B01E318002A05D0EC +:1008C0005A7930218A4320210A4304E05A793021A1 +:1008D0008A43102002435A7175E002887F239A43AD +:1008E000494BD2B21A7001880F220A400280328826 +:1008F000002A00D08CE00288002A00D188E002881B +:10090000032A00D984E01B78002B27D00388083302 +:100910005B01E3189B79990655D50388302108338C +:100920005B01E3181A798A4320210A431A7103886C +:1009300008335B01E318DB795A0644D5038860214C +:1009400008335B01E318DA798A4340210A43DA71FC +:100950000388022208335B01E31826E0038808338A +:100960005B01E3189B79DF062DD50388302108331E +:100970005B01E3181A798A4310210A431A7103882C +:1009800008335B01E318DB7999061CD503886021E5 +:1009900008335B01E318DA798A4320210A43DA71CC +:1009A0000388012208335B01E3181A710BE00B88FE +:1009B00008222868934201D80A8892B2134900237A +:1009C000FFF790FC28E0201CFFF72EFD24E0C04636 +:1009D0008C0000208100002077000020780000209B +:1009E0007C0000207E0000200203000001030000C4 +:1009F00021200000A1210000212200004C14000051 +:100A0000000000207A000020800000204400002028 +:100A1000201C0121FFF7FCFCF8BDC04610B5054BBA +:100A2000054C2360FFF7DAFB201C2168FFF7C8FBA9 +:100A3000201C10BD005000410C02002007B5054BE2 +:100A40000122019001A91868131CFFF74BFC01203B +:100A50000EBDC0460C02002013B5054B6C46073492 +:100A60001868211C0122FFF78DFC207816BDC046B6 +:100A70000C02002010B5074C201CFFF75DFB031C87 +:100A80000020834205D022684823FF33D05C012335 +:100A9000184010BD0C02002010B5054A0C1C031CA8 +:100AA000191C10680123221CFFF71CFC201C10BD20 +:100AB0000C02002070B5084C061C201C0D1CFFF712 +:100AC0003BFB0023984205D02068311C2A1CFFF70D +:100AD00059FC031C181C70BD0C020020F8B50C4C0E +:100AE000051C201C0E1CFFF727FB0023271C341CB1 +:100AF00098420AD0002C07D0291C221C3868FFF726 +:100B000041FC241A2D18F5E7331C181CF8BDC0460B +:100B10000C020020012805D1054B064A1A60064B3D +:100B2000187004E0002802D1044A014B1A60704793 +:100B30007C0200208014000089000020CC140000FA +:100B400030B51A4B85B01B78002B29D0042901D170 +:100B5000026804E0022901D1028800E0027849001D +:100B600004A843180B3B5C1AA3420BD00F20104083 +:100B7000092802D83025284300E0373018701209C0 +:100B8000013BF1E701A830230370782343700A2268 +:100B900043189A700D22DA70054B04311B6801E08E +:100BA000034B1B68DB68984705B030BD8800002008 +:100BB0007C02002072B6EFF30883044A13600368D6 +:100BC00083F30888436818477047C04680020020B6 +:100BD000F0B58FB006A9CD4A0B1C31CA31C351CA3A +:100BE00051C360CA60C3CA4CCA48A3687A255B0374 +:100BF0005B0F9B005B58C8490360A26892B25343E5 +:100C00000A60C649C64A0B6000231360C54B1D70BD +:100C1000C54BC64D1B68281C1B6940219847C44B17 +:100C200000221860C34B1D60C34BC34DC04F1A60F8 +:100C3000286839688842EBD2BE4B1B681A78FF2AB5 +:100C400000D1F7E1232A00D0CEE1BC4E3378002B4F +:100C500005D0B54BBA481B680221DB689847B14BF9 +:100C60001B78532B38D13B682A6893421ED9B14870 +:100C700001322A609A1AB34B01681B680131016086 +:100C8000B14E9A4201D2326000E03360A44832682B +:100C90000068029000F0BCFB336829685A182A608B +:100CA000A44A1668F1181160A84A13702B68013B1A +:100CB0002B60A04B1A68013A1A60A44BA14A1B781A +:100CC00011688B4206D2984A954812680068C91A82 +:100CD00092699047C04676E1522B07D1904A924BD9 +:100CE00010681B68974A5B6911686BE14F2B05D14F +:100CF0008B4B944A1B6812681A7064E1482B05D12B +:100D0000874B904A1B6812681A805CE1572B05D10B +:100D1000834B8C4A1B6812681A6054E16F2B03D115 +:100D20007F4B0121186807E0682B08D17C4B854870 +:100D30001B6802211B880360FFF702FF43E1772B4A +:100D400006D1774B7F481B6804211B680360F3E7DB +:100D5000472B13D17B4B1868FFF72CFF7C4B1B688C +:100D600083F3088862B67B4B1B78002B00D12AE105 +:100D70006D4B06201B681B68984724E1542B04D157 +:100D800001233370684B1B685CE04E2B0BD133782A +:100D9000002B05D1644B6A481B680221DB68984729 +:100DA000002333700FE1562B50D15F4D01212B688A +:100DB0006948DB6898472B680321DB6867489847D8 +:100DC000674E2B68301CDB68012198472B680D218A +:100DD000DB68644898472B68301CDB680121984722 +:100DE000544F614B544E3B60002333603A1C311C1E +:100DF0001368581C10601B780393002B03D00B68FA +:100E000001330B60F4E72B683168DB68564898477C +:100E10002B685348DB68012198470398306053489A +:100E20003860444A1368591C11601A78424B002AF2 +:100E300003D01A6801321A60F3E72A681968D36888 +:100E400098472B68DB683E480221BBE03D4A582B9F +:100E500015D1304E314D366813682A68B10093427F +:100E600008D25808E06142482080207DC507FCD5A3 +:100E70005B18F4E72C4B3F481B68DB68A1E0592B5B +:100E800033D11268264B3C49002A02D11B680B6003 +:100E900026E00868196863688025AB4392086360A0 +:100EA000002A1DD0354B2380237DDE07FCD500238F +:100EB000184D2D680095AD08AB4202D3304D25800A +:100EC00006E09342FAD09D00465901334E51EFE7B8 +:100ED000257DEE07FCD59D0049194019D21ADFE7A0 +:100EE000114B28481B68DB686BE05A2B6BD10C4B0D +:100EF00017681D680026EF19BD4245D02878311CBF +:100F000000F04AF90135061CF6E7C04660140000FF +:100F100000400041340200202C0200202802002062 +:100F200078020020240200207C02002038020020E9 +:100F30001C02002020020020300200208800002037 +:100F4000C014000084020020880200201802002043 +:100F500080020020890000209C140000C5140000BD +:100F60009E140000E8140000A0140000AC1400005F +:100F700002A5FFFFB51400008400002044A5FFFF78 +:100F800004A5FFFFB91400002E4D2F482B68012146 +:100F9000DB68984707230F223240111C3609303195 +:100FA000092A00DD07311020C0186A468154013B30 +:100FB000F1D22B6804A8DB68082198472B682348E6 +:100FC000DB6803219847224D7A232B70214B0022A6 +:100FD0001A60214B1B7893422CD01A4B01211B68BD +:100FE0001E48DB68984725E0111C3039C8B2194B00 +:100FF000092804D81E683201114319601AE0111C37 +:101000004139052903D81868373A010106E0111C57 +:101010006139052904D81D68573A29010A4308E0B7 +:101020002C2A03D10E4A1E68166001E008490A7096 +:1010300000221A600B4B1A6801321A600A4B1A68B8 +:101040000132F2E57C020020BD140000BF14000054 +:10105000240200208402002088000020C314000025 +:1010600078020020300200202002002010B51C4B26 +:1010700001201A78022402431A701A4B0F221978A1 +:101080009143197019782143197017490C7820433E +:10109000087019780A401A701A7820210A431A70C9 +:1010A000124B04211A6A0A431A62114B114A5A80E0 +:1010B0005A7852B2002AFBDBC4220F480F49920330 +:1010C000FEF7EEFF0E4A002313700E4A13700E4A0D +:1010D00013700E4A13700E4A13700E4A137010BD2F +:1010E0004A440041354400414B4400410004004063 +:1010F000000C0040144000000008004204C500003D +:101100008C020020130300208D020020900200209A +:10111000140300201103002008B5C1B20248FEF7F5 +:10112000EDFF012008BDC04600080042024B187EBA +:101130004007C00F7047C0460008004208B5FFF7DF +:10114000F5FF0028FBD00248FEF7DEFF08BDC046D1 +:101150000008004208B5FFF7E9FF0023984205D0D8 +:10116000FFF7ECFF031C233B5A425341181C08BDF8 +:1011700070B5041C0D1C4618B44204D02078FFF74B +:10118000CBFF0134F8E7281C70BD10B5041CFFF735 +:10119000D5FF2070012010BD0B0A5840034B4000C2 +:1011A000C05A0902484080B27047C046F614000099 +:1011B000F7B50024051C0F1C261CBC4220D0FFF7ED +:1011C000BDFF114BC0B21B780190002B1AD1311C0E +:1011D000FFF7E2FF0D4B061C1A88002A04D10C4AC7 +:1011E00011782A1C002907D001996A1C2970802FC8 +:1011F00002D11988013919800134A4B2151CDCE729 +:10120000301C00E00120FEBD110300208E020020F2 +:1012100012030020F0B53E4E85B0002203900C1C56 +:1012200032703C4B914201D1012201E03A490C80DD +:101230001A707F231C4201D080349C43FFF77EFF4D +:101240003378C0B2002B07D000253570FFF776FF4A +:101250003378C0B2AB4236D1432803D0712853D083 +:101260001528EBD1012300930120FFF755FF0098CB +:10127000FFF752FF00998025C843C0B2FFF74CFF2B +:10128000039B00270293244A1388002B1DD1214978 +:1012900001930978002918D10198FFF73DFF391C07 +:1012A0000198FFF779FF013D071C002DEBD1000AE3 +:1012B000C0B2FFF731FFF8B2FFF72EFFFFF73EFF96 +:1012C0003378002B0AD035701FE00299013B097872 +:1012D0001380029B019101330293DDE7C0B206281F +:1012E00007D1009B03990133DBB280310093803C2E +:1012F0000391002CB8D10420FFF70EFFFFF71EFF6B +:10130000044B01251C7000E00025281C05B0F0BD31 +:1013100011030020120300208E020020F0B5384C8B +:1013200087B0002301902370994201D1012301E08D +:10133000344A1180344A642613704320FFF7ECFED0 +:10134000324FFFF7F3FE002803D1002F03D0013FF7 +:10135000F7E7002F03D1013E002EEED14DE001252D +:10136000FFF7ECFE2378002B38D1C0B202900128A1 +:1013700005D004283DD10620FFF7CEFE39E005AEAA +:101380000221301CFFF714FF01988021FFF710FFA6 +:1013900023780390002B18D1FFF7D0FE0702FFF748 +:1013A000CDFEBFB223783F18BFB2012B0DD0039BF7 +:1013B0009F4207D13378AB4204D1EB437278DBB262 +:1013C0009A4204D01820FFF7A7FE002303E006206E +:1013D000FFF7A2FE029B2278002A02D00026267088 +:1013E0000BE0012B05D1019A6B1C8032DDB201921A +:1013F000B6E7054A002313700126301C07B0F0BD84 +:10140000110300208E0200201203002000350C0082 +:1014100010B50023934203D0CC5CC4540133F9E7E8 +:1014200010BD031C8218934202D019700133FAE7F1 +:1014300070470000F8B5C046F8BC08BC9E4670472F +:10144000F8B5C046F8BC08BC9E46704712010002C1 +:101450000200004041234D02000200000001000094 +:101460000800000010000000200000004000000004 +:1014700080000000000100000002000000040000E5 +:10148000191100003D1100002D1100007111000024 +:101490008B110000151200001D13000076002000C3 +:1014A0004E6F7620313220323031350031373A32CA +:1014B000323A323800580A0D00590A0D005A0023FA +:1014C0000A0D003E00322E30000000003D0A0000F0 +:1014D000590A0000750A0000990A0000B50A0000C8 +:1014E000990A0000DD0A00005B41726475696E6F45 +:1014F0003A58595A5D000000211042206330844060 +:10150000A550C660E770088129914AA16BB18CC1D2 +:10151000ADD1CEE1EFF13112100273325222B55249 +:101520009442F772D662399318837BB35AA3BDD322 +:101530009CC3FFF3DEE36224433420040114E66419 +:10154000C774A44485546AA54BB528850995EEE572 +:10155000CFF5ACC58DD55336722611163006D77629 +:10156000F6669556B4465BB77AA719973887DFF7C2 +:10157000FEE79DD7BCC7C448E5588668A7784008F1 +:10158000611802282338CCC9EDD98EE9AFF9488912 +:1015900069990AA92BB9F55AD44AB77A966A711A89 +:1015A000500A333A122AFDDBDCCBBFFB9EEB799B62 +:1015B000588B3BBB1AABA66C877CE44CC55C222CD9 +:1015C000033C600C411CAEED8FFDECCDCDDD2AADB2 +:1015D0000BBD688D499D977EB66ED55EF44E133E69 +:1015E000322E511E700E9FFFBEEFDDDFFCCF1BBF02 +:1015F0003AAF599F788F8891A981CAB1EBA10CD1DC +:101600002DC14EF16FE18010A100C230E3200450E3 +:10161000254046706760B9839893FBA3DAB33DC356 +:101620001CD37FE35EF3B1029012F322D232354233 +:10163000145277625672EAB5CBA5A89589856EF5E6 +:101640004FE52CD50DC5E234C324A0148104667483 +:10165000476424540544DBA7FAB79987B8975FE736 +:101660007EF71DC73CD7D326F2369106B0165766D3 +:101670007676154634564CD96DC90EF92FE9C899BE +:10168000E9898AB9ABA94458654806782768C01823 +:10169000E1088238A3287DCB5CDB3FEB1EFBF98B96 +:1016A000D89BBBAB9ABB754A545A376A167AF10A73 +:1016B000D01AB32A923A2EFD0FED6CDD4DCDAABDA6 +:1016C0008BADE89DC98D267C076C645C454CA23CC3 +:1016D000832CE01CC10C1FEF3EFF5DCF7CDF9BAF76 +:1016E000BABFD98FF89F176E367E554E745E932E13 +:0C16F000B23ED10EF01E00000000000011 +:1016FC0009024300020100803209040000010202C9 +:10170C000000052400100104240200052406000139 +:10171C000524010001070583030800FF09040100EB +:10172C00020A0000000705810240000007050202C2 +:10173C004000000000C20100000008006900000029 +:08174C00410000000000000054 +:04000003000005E90B :00000001FF diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index e645743b2..175dcf705 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -46,7 +46,6 @@ extern "C"{ // Include Atmel headers #include "sam.h" - #include "wiring_constants.h" #define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L ) @@ -97,8 +96,33 @@ void loop( void ) ; #undef abs #endif // abs -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) +#ifdef __cplusplus + template + auto min(const T& a, const L& b) -> decltype((b < a) ? b : a) + { + return (b < a) ? b : a; + } + + template + auto max(const T& a, const L& b) -> decltype((b < a) ? b : a) + { + return (a < b) ? b : a; + } +#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 +#endif + #define abs(x) ((x)>0?(x):-(x)) #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) @@ -124,10 +148,15 @@ void loop( void ) ; #define digitalPinToInterrupt(P) ( P ) #endif -// USB Device -#include "USB/USBDesc.h" -#include "USB/USBCore.h" -#include "USB/USBAPI.h" -#include "USB/USB_host.h" +// USB +#ifdef USE_TINYUSB + // Needed for declaring Serial + #include "Adafruit_USBD_CDC.h" +#else + #include "USB/USBDesc.h" + #include "USB/USBCore.h" + #include "USB/USBAPI.h" + #include "USB/USB_host.h" +#endif #endif // Arduino_h diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h index 62508e786..6180b0748 100644 --- a/cores/arduino/HardwareSerial.h +++ b/cores/arduino/HardwareSerial.h @@ -67,9 +67,9 @@ class HardwareSerial : public Stream { public: - virtual void begin(unsigned long); - virtual void begin(unsigned long baudrate, uint16_t config); - virtual void end(); + virtual void begin(unsigned long) {} + virtual void begin(unsigned long, uint16_t) {} + virtual void end() {} virtual int available(void) = 0; virtual int peek(void) = 0; virtual int read(void) = 0; diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 136329cca..ad02662c3 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -94,6 +94,28 @@ size_t Print::print(unsigned long n, int base) else return printNumber(n, base); } +size_t Print::print(long long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printULLNumber(n, 10) + t; + } + return printULLNumber(n, 10); + } else { + return printULLNumber(n, base); + } +} + +size_t Print::print(unsigned long long n, int base) +{ + if (base == 0) return write(n); + else return printULLNumber(n, base); +} + size_t Print::print(double n, int digits) { return printFloat(n, digits); @@ -172,6 +194,20 @@ size_t Print::println(unsigned long num, int base) return n; } +size_t Print::println(long long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + size_t Print::println(double num, int digits) { size_t n = print(num, digits); @@ -186,6 +222,16 @@ size_t Print::println(const Printable& x) return n; } +void Print::printf(const char format[], ...) +{ + char buf[PRINTF_BUF]; + va_list ap; + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + write(buf); + va_end(ap); +} + // Private Methods ///////////////////////////////////////////////////////////// size_t Print::printNumber(unsigned long n, uint8_t base) @@ -208,6 +254,81 @@ size_t Print::printNumber(unsigned long n, uint8_t base) return write(str); } +// REFERENCE IMPLEMENTATION FOR ULL +// size_t Print::printULLNumber(unsigned long long n, uint8_t base) +// { + // // if limited to base 10 and 16 the bufsize can be smaller + // char buf[65]; + // char *str = &buf[64]; + + // *str = '\0'; + + // // prevent crash if called with base == 1 + // if (base < 2) base = 10; + + // do { + // unsigned long long t = n / base; + // char c = n - t * base; // faster than c = n%base; + // n = t; + // *--str = c < 10 ? c + '0' : c + 'A' - 10; + // } while(n); + + // return write(str); +// } + +// FAST IMPLEMENTATION FOR ULL +size_t Print::printULLNumber(unsigned long long n64, uint8_t base) +{ + // if limited to base 10 and 16 the bufsize can be 20 + char buf[64]; + uint8_t i = 0; + uint8_t innerLoops = 0; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + // process chunks that fit in "16 bit math". + uint16_t top = 0xFFFF / base; + uint16_t th16 = 1; + while (th16 < top) + { + th16 *= base; + innerLoops++; + } + + while (n64 > th16) + { + // 64 bit math part + uint64_t q = n64 / th16; + uint16_t r = n64 - q*th16; + n64 = q; + + // 16 bit math loop to do remainder. (note buffer is filled reverse) + for (uint8_t j=0; j < innerLoops; j++) + { + uint16_t qq = r/base; + buf[i++] = r - qq*base; + r = qq; + } + } + + uint16_t n16 = n64; + while (n16 > 0) + { + uint16_t qq = n16/base; + buf[i++] = n16 - qq*base; + n16 = qq; + } + + size_t bytes = i; + for (; i > 0; i--) + write((char) (buf[i - 1] < 10 ? + '0' + buf[i - 1] : + 'A' + buf[i - 1] - 10)); + + return bytes; +} + size_t Print::printFloat(double number, uint8_t digits) { size_t n = 0; @@ -238,17 +359,18 @@ size_t Print::printFloat(double number, uint8_t digits) // Print the decimal point, but only if there are digits beyond if (digits > 0) { - n += print('.'); + n += print("."); } // Extract digits from the remainder one at a time while (digits-- > 0) { remainder *= 10.0; - unsigned int toPrint = (unsigned int)(remainder); + unsigned int toPrint = (unsigned int)remainder; n += print(toPrint); remainder -= toPrint; } return n; } + diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index dfb645cbb..43db88b3d 100644 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -21,6 +21,8 @@ #include #include // for size_t +#include // for printf +#define PRINTF_BUF 80 #include "WString.h" #include "Printable.h" @@ -28,9 +30,6 @@ #define DEC 10 #define HEX 16 #define OCT 8 -#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar -#undef BIN -#endif #define BIN 2 class Print @@ -38,6 +37,7 @@ class Print private: int write_error; size_t printNumber(unsigned long, uint8_t); + size_t printULLNumber(unsigned long long, uint8_t); size_t printFloat(double, uint8_t); protected: void setWriteError(int err = 1) { write_error = err; } @@ -70,6 +70,8 @@ class Print size_t print(unsigned int, int = DEC); size_t print(long, int = DEC); size_t print(unsigned long, int = DEC); + size_t print(long long, int = DEC); + size_t print(unsigned long long, int = DEC); size_t print(double, int = 2); size_t print(const Printable&); @@ -82,9 +84,13 @@ class Print size_t println(unsigned int, int = DEC); size_t println(long, int = DEC); size_t println(unsigned long, int = DEC); + size_t println(long long, int = DEC); + size_t println(unsigned long long, int = DEC); size_t println(double, int = 2); size_t println(const Printable&); size_t println(void); + + void printf(const char[], ...); virtual void flush() { /* Empty implementation for backward compatibility */ } }; diff --git a/cores/arduino/Reset.cpp b/cores/arduino/Reset.cpp index 053d7c5f3..9bde4a8c0 100644 --- a/cores/arduino/Reset.cpp +++ b/cores/arduino/Reset.cpp @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -28,42 +29,74 @@ extern "C" { #if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10610) extern const uint32_t __text_start__; -#define APP_START ((volatile uint32_t)(&__text_start__) + 4) +#define APP_START ((uint32_t)(&__text_start__) + 4) +#else + +#if defined(__SAMD51__) +#define APP_START 0x00004004 #else #define APP_START 0x00002004 #endif +#endif + static inline bool nvmReady(void) { +#if defined(__SAMD51__) + return NVMCTRL->STATUS.reg & NVMCTRL_STATUS_READY; +#else return NVMCTRL->INTFLAG.reg & NVMCTRL_INTFLAG_READY; +#endif } __attribute__ ((long_call, section (".ramfunc"))) static void banzai() { // Disable all interrupts __disable_irq(); + +#if defined(__SAMD51__) + //THESE MUST MATCH THE BOOTLOADER + #define DOUBLE_TAP_MAGIC 0xf01669efUL + #define BOOT_DOUBLE_TAP_ADDRESS (HSRAM_ADDR + HSRAM_SIZE - 4) + + unsigned long *a = (unsigned long *)BOOT_DOUBLE_TAP_ADDRESS; + *a = DOUBLE_TAP_MAGIC; + //NVMCTRL->ADDR.reg = APP_START; + //NVMCTRL->CTRLB.reg = NVMCTRL_CTRLB_CMD_EB | NVMCTRL_CTRLB_CMDEX_KEY; + + // Reset the device + NVIC_SystemReset() ; + while (true); +#else + // Avoid erasing the application if APP_START is < than the minimum bootloader size // This could happen if without_bootloader linker script was chosen // Minimum bootloader size in SAMD21 family is 512bytes (RM section 22.6.5) + if (APP_START < (0x200 + 4)) { goto reset; } + // Erase application while (!nvmReady()) ; + NVMCTRL->STATUS.reg |= NVMCTRL_STATUS_MASK; NVMCTRL->ADDR.reg = (uintptr_t)&NVM_MEMORY[APP_START / 4]; NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMD_ER | NVMCTRL_CTRLA_CMDEX_KEY; + while (!nvmReady()) - ; + ; reset: // Reset the device NVIC_SystemReset() ; while (true); +#endif + } static int ticks = -1; diff --git a/cores/arduino/RingBuffer.h b/cores/arduino/RingBuffer.h index e706cc4f2..deecb733c 100644 --- a/cores/arduino/RingBuffer.h +++ b/cores/arduino/RingBuffer.h @@ -27,8 +27,9 @@ // using a ring buffer (I think), in which head is the index of the location // to which to write the next incoming character and tail is the index of the // location from which to read. + #ifndef SERIAL_BUFFER_SIZE -#define SERIAL_BUFFER_SIZE 256 +#define SERIAL_BUFFER_SIZE 350 #endif template diff --git a/cores/arduino/SERCOM.cpp b/cores/arduino/SERCOM.cpp index be7962ec2..732393ebc 100644 --- a/cores/arduino/SERCOM.cpp +++ b/cores/arduino/SERCOM.cpp @@ -1,5 +1,6 @@ /* Copyright (c) 2014 Arduino. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -18,6 +19,7 @@ #include "SERCOM.h" #include "variant.h" +#include "Arduino.h" #ifndef WIRE_RISE_TIME_NANOSECONDS // Default rise time in nanoseconds, based on 4.7K ohm pull up resistors @@ -28,11 +30,29 @@ SERCOM::SERCOM(Sercom* s) { sercom = s; -} -/* ========================= - * ===== Sercom UART - * ========================= +#if defined(__SAMD51__) + // A briefly-available but now deprecated feature had the SPI clock source + // set via a compile-time setting (MAX_SPI)...problem was this affected + // ALL SERCOMs, whereas some (anything read/write, e.g. SD cards) should + // not exceed the standard 24 MHz setting. Newer code, if it needs faster + // write-only SPI (e.g. to screen), should override the SERCOM clock on a + // per-peripheral basis. Nonetheless, we check SERCOM_SPI_FREQ_REF here + // (MAX_SPI * 2) to retain compatibility with any interim projects that + // might have relied on the compile-time setting. But please, don't. + #if SERCOM_SPI_FREQ_REF == F_CPU // F_CPU clock = GCLK0 + clockSource = SERCOM_CLOCK_SOURCE_FCPU; + #elif SERCOM_SPI_FREQ_REF == 48000000 // 48 MHz clock = GCLK1 (standard) + clockSource = SERCOM_CLOCK_SOURCE_48M; + #elif SERCOM_SPI_FREQ_REF == 100000000 // 100 MHz clock = GCLK2 + clockSource = SERCOM_CLOCK_SOURCE_100M; + #endif +#endif // end __SAMD51__ +} + +/* ========================= + * ===== Sercom UART + * ========================= */ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate) { @@ -40,12 +60,12 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint resetUART(); //Setting the CTRLA register - sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(mode) | - SERCOM_USART_CTRLA_SAMPR(sampleRate); + sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(mode) | + SERCOM_USART_CTRLA_SAMPR(sampleRate); //Setting the Interrupt register - sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC | //Received complete - SERCOM_USART_INTENSET_ERROR; //All others errors + sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC | //Received complete + SERCOM_USART_INTENSET_ERROR; //All others errors if ( mode == UART_INT_CLOCK ) { @@ -60,7 +80,11 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint // Asynchronous fractional mode (Table 24-2 in datasheet) // BAUD = fref / (sampleRateValue * fbaud) // (multiply by 8, to calculate fractional piece) +#if defined(__SAMD51__) + uint32_t baudTimes8 = (SERCOM_FREQ_REF * 8) / (sampleRateValue * baudrate); +#else uint32_t baudTimes8 = (SystemCoreClock * 8) / (sampleRateValue * baudrate); +#endif sercom->USART.BAUD.FRAC.FP = (baudTimes8 % 8); sercom->USART.BAUD.FRAC.BAUD = (baudTimes8 / 8); @@ -69,20 +93,22 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits) { //Setting the CTRLA register - sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_FORM( (parityMode == SERCOM_NO_PARITY ? 0 : 1) ) | - dataOrder << SERCOM_USART_CTRLA_DORD_Pos; + sercom->USART.CTRLA.reg |= + SERCOM_USART_CTRLA_FORM((parityMode == SERCOM_NO_PARITY ? 0 : 1) ) | + dataOrder << SERCOM_USART_CTRLA_DORD_Pos; //Setting the CTRLB register - sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_CHSIZE(charSize) | - nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos | - (parityMode == SERCOM_NO_PARITY ? 0 : parityMode) << SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value + sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_CHSIZE(charSize) | + nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos | + (parityMode == SERCOM_NO_PARITY ? 0 : parityMode) << + SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value } void SERCOM::initPads(SercomUartTXPad txPad, SercomRXPad rxPad) { //Setting the CTRLA register - sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(txPad) | - SERCOM_USART_CTRLA_RXPO(rxPad); + sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(txPad) | + SERCOM_USART_CTRLA_RXPO(rxPad); // Enable Transceiver and Receiver sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ; @@ -195,26 +221,33 @@ void SERCOM::disableDataRegisterEmptyInterruptUART() sercom->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE; } -/* ========================= - * ===== Sercom SPI - * ========================= +/* ========================= + * ===== Sercom SPI + * ========================= */ void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) { resetSPI(); initClockNVIC(); +#if defined(__SAMD51__) + sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE(0x3) | // master mode + SERCOM_SPI_CTRLA_DOPO(mosi) | + SERCOM_SPI_CTRLA_DIPO(miso) | + dataOrder << SERCOM_SPI_CTRLA_DORD_Pos; +#else //Setting the CTRLA register - sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER | + sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER | SERCOM_SPI_CTRLA_DOPO(mosi) | SERCOM_SPI_CTRLA_DIPO(miso) | dataOrder << SERCOM_SPI_CTRLA_DORD_Pos; +#endif //Setting the CTRLB register sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) | - SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver. - + SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver. + while( sercom->SPI.SYNCBUSY.bit.CTRLB == 1 ); } void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) @@ -233,8 +266,8 @@ void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) cpol = 1; //Setting the CTRLA register - sercom->SPI.CTRLA.reg |= ( cpha << SERCOM_SPI_CTRLA_CPHA_Pos ) | - ( cpol << SERCOM_SPI_CTRLA_CPOL_Pos ); + sercom->SPI.CTRLA.reg |= ( cpha << SERCOM_SPI_CTRLA_CPHA_Pos ) | + ( cpol << SERCOM_SPI_CTRLA_CPOL_Pos ); //Synchronous arithmetic sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate); @@ -288,14 +321,13 @@ SercomDataOrder SERCOM::getDataOrderSPI() void SERCOM::setBaudrateSPI(uint8_t divider) { - //Can't divide by 0 - if(divider == 0) - return; - - //Register enable-protected - disableSPI(); + disableSPI(); // Register is enable-protected - sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider ); +#if defined(__SAMD51__) + sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(freqRef / divider); +#else + sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(SERCOM_SPI_FREQ_REF / divider); +#endif enableSPI(); } @@ -326,10 +358,7 @@ uint8_t SERCOM::transferDataSPI(uint8_t data) { sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register - while( sercom->SPI.INTFLAG.bit.RXC == 0 ) - { - // Waiting Complete Reception - } + while(sercom->SPI.INTFLAG.bit.RXC == 0); // Waiting Complete Reception return sercom->SPI.DATA.bit.DATA; // Reading data } @@ -347,25 +376,30 @@ bool SERCOM::isDataRegisterEmptySPI() //bool SERCOM::isTransmitCompleteSPI() //{ -// //TXC : Transmit complete -// return sercom->SPI.INTFLAG.bit.TXC; +// //TXC : Transmit complete +// return sercom->SPI.INTFLAG.bit.TXC; //} // //bool SERCOM::isReceiveCompleteSPI() //{ -// //RXC : Receive complete -// return sercom->SPI.INTFLAG.bit.RXC; +// //RXC : Receive complete +// return sercom->SPI.INTFLAG.bit.RXC; //} -uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate) -{ - return SERCOM_FREQ_REF / (2 * baudrate) - 1; +uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate) { +#if defined(__SAMD51__) + uint16_t b = freqRef / (2 * baudrate); +#else + uint16_t b = SERCOM_SPI_FREQ_REF / (2 * baudrate); +#endif + if(b > 0) b--; // Don't -1 on baud calc if already at 0 + return b; } -/* ========================= - * ===== Sercom WIRE - * ========================= +/* ========================= + * ===== Sercom WIRE + * ========================= */ void SERCOM::resetWIRE() { @@ -457,7 +491,11 @@ void SERCOM::initMasterWIRE( uint32_t baudrate ) // sercom->I2CM.INTENSET.reg = SERCOM_I2CM_INTENSET_MB | SERCOM_I2CM_INTENSET_SB | SERCOM_I2CM_INTENSET_ERROR ; // Synchronous arithmetic baudrate +#if defined(__SAMD51__) + sercom->I2CM.BAUD.bit.BAUD = SERCOM_FREQ_REF / ( 2 * baudrate) - 1 ; +#else sercom->I2CM.BAUD.bit.BAUD = SystemCoreClock / ( 2 * baudrate) - 5 - (((SystemCoreClock / 1000000) * WIRE_RISE_TIME_NANOSECONDS) / (2 * 1000)); +#endif } void SERCOM::prepareNackBitWIRE( void ) @@ -499,8 +537,18 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag // 7-bits address + 1-bits R/W address = (address << 0x1ul) | flag; - // Wait idle or owner bus mode - while ( !isBusIdleWIRE() && !isBusOwnerWIRE() ); + // If another master owns the bus or the last bus owner has not properly + // sent a stop, return failure early. This will prevent some misbehaved + // devices from deadlocking here at the cost of the caller being responsible + // for retrying the failed transmission. See SercomWireBusState for the + // possible bus states. + if(!isBusOwnerWIRE()) + { + if( isBusBusyWIRE() || (isArbLostWIRE() && !isBusIdleWIRE()) || isBusUnknownWIRE() ) + { + return false; + } + } // Send start and address sercom->I2CM.ADDR.bit.ADDR = address; @@ -508,29 +556,35 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag // Address Transmitted if ( flag == WIRE_WRITE_FLAG ) // Write mode { - while( !sercom->I2CM.INTFLAG.bit.MB ) - { + while( !sercom->I2CM.INTFLAG.bit.MB ) { // Wait transmission complete + + // If certain errors occur, the MB bit may never be set (RFTM: SAMD21 sec:28.10.6; SAMD51 sec:36.10.7). + // The data transfer errors that can occur (including BUSERR) are all + // rolled up into INTFLAG.bit.ERROR from STATUS.reg + if (sercom->I2CM.INTFLAG.bit.ERROR) { + return false; + } } } else // Read mode { - while( !sercom->I2CM.INTFLAG.bit.SB ) - { - // If the slave NACKS the address, the MB bit will be set. - // In that case, send a stop condition and return false. - if (sercom->I2CM.INTFLAG.bit.MB) { - sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition - return false; - } + while( !sercom->I2CM.INTFLAG.bit.SB ) { // Wait transmission complete + + // If the slave NACKS the address, the MB bit will be set. + // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register + // In that case, send a stop condition and return false. + if (sercom->I2CM.INTFLAG.bit.MB || sercom->I2CM.INTFLAG.bit.ERROR) { + sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition + return false; + } } // Clean the 'Slave on Bus' flag, for further usage. //sercom->I2CM.INTFLAG.bit.SB = 0x1ul; } - //ACK received (0: ACK, 1: NACK) if(sercom->I2CM.STATUS.bit.RXNACK) { @@ -549,10 +603,11 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data) //Wait transmission successful while(!sercom->I2CM.INTFLAG.bit.MB) { - - // If a bus error occurs, the MB bit may never be set. - // Check the bus error bit and bail if it's set. - if (sercom->I2CM.STATUS.bit.BUSERR) { + // If a data transfer error occurs, the MB bit may never be set. + // Check the error bit and bail if it's set. + // The data transfer errors that can occur (including BUSERR) are all + // rolled up into INTFLAG.bit.ERROR from STATUS.reg + if (sercom->I2CM.INTFLAG.bit.ERROR) { return false; } } @@ -596,6 +651,21 @@ bool SERCOM::isBusOwnerWIRE( void ) return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE; } +bool SERCOM::isBusUnknownWIRE( void ) +{ + return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_UNKNOWN_STATE; +} + +bool SERCOM::isArbLostWIRE( void ) +{ + return sercom->I2CM.STATUS.bit.ARBLOST == 1; +} + +bool SERCOM::isBusBusyWIRE( void ) +{ + return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_BUSY_STATE; +} + bool SERCOM::isDataReadyWIRE( void ) { return sercom->I2CS.INTFLAG.bit.DRDY; @@ -638,9 +708,17 @@ uint8_t SERCOM::readDataWIRE( void ) { if(isMasterWIRE()) { - while( sercom->I2CM.INTFLAG.bit.SB == 0 ) - { + while (sercom->I2CM.INTFLAG.bit.SB == 0) { // Waiting complete receive + // A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register + // In that case, send a stop condition and return false. + // readDataWIRE should really be able to indicate an error (which would never be used + // because the readDataWIRE callers (in Wire.cpp) should have checked availableWIRE() first and timed it + // out if the data never showed up + if (sercom->I2CM.INTFLAG.bit.MB || sercom->I2CM.INTFLAG.bit.ERROR) { + sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition + return 0xFF; + } } return sercom->I2CM.DATA.bit.DATA ; @@ -651,64 +729,152 @@ uint8_t SERCOM::readDataWIRE( void ) } } +#if defined(__SAMD51__) + +static const struct { + Sercom *sercomPtr; + uint8_t id_core; + uint8_t id_slow; + IRQn_Type irq[4]; +} sercomData[] = { + { SERCOM0, SERCOM0_GCLK_ID_CORE, SERCOM0_GCLK_ID_SLOW, + SERCOM0_0_IRQn, SERCOM0_1_IRQn, SERCOM0_2_IRQn, SERCOM0_3_IRQn }, + { SERCOM1, SERCOM1_GCLK_ID_CORE, SERCOM1_GCLK_ID_SLOW, + SERCOM1_0_IRQn, SERCOM1_1_IRQn, SERCOM1_2_IRQn, SERCOM1_3_IRQn }, + { SERCOM2, SERCOM2_GCLK_ID_CORE, SERCOM2_GCLK_ID_SLOW, + SERCOM2_0_IRQn, SERCOM2_1_IRQn, SERCOM2_2_IRQn, SERCOM2_3_IRQn }, + { SERCOM3, SERCOM3_GCLK_ID_CORE, SERCOM3_GCLK_ID_SLOW, + SERCOM3_0_IRQn, SERCOM3_1_IRQn, SERCOM3_2_IRQn, SERCOM3_3_IRQn }, + { SERCOM4, SERCOM4_GCLK_ID_CORE, SERCOM4_GCLK_ID_SLOW, + SERCOM4_0_IRQn, SERCOM4_1_IRQn, SERCOM4_2_IRQn, SERCOM4_3_IRQn }, + { SERCOM5, SERCOM5_GCLK_ID_CORE, SERCOM5_GCLK_ID_SLOW, + SERCOM5_0_IRQn, SERCOM5_1_IRQn, SERCOM5_2_IRQn, SERCOM5_3_IRQn }, +#if defined(SERCOM6) + { SERCOM6, SERCOM6_GCLK_ID_CORE, SERCOM6_GCLK_ID_SLOW, + SERCOM6_0_IRQn, SERCOM6_1_IRQn, SERCOM6_2_IRQn, SERCOM6_3_IRQn }, +#endif +#if defined(SERCOM7) + { SERCOM7, SERCOM7_GCLK_ID_CORE, SERCOM7_GCLK_ID_SLOW, + SERCOM7_0_IRQn, SERCOM7_1_IRQn, SERCOM7_2_IRQn, SERCOM7_3_IRQn }, +#endif +}; + +#else // end if SAMD51 (prob SAMD21) + +static const struct { + Sercom *sercomPtr; + uint8_t clock; + IRQn_Type irqn; +} sercomData[] = { + SERCOM0, GCM_SERCOM0_CORE, SERCOM0_IRQn, + SERCOM1, GCM_SERCOM1_CORE, SERCOM1_IRQn, + SERCOM2, GCM_SERCOM2_CORE, SERCOM2_IRQn, + SERCOM3, GCM_SERCOM3_CORE, SERCOM3_IRQn, +#if defined(SERCOM4) + SERCOM4, GCM_SERCOM4_CORE, SERCOM4_IRQn, +#endif +#if defined(SERCOM5) + SERCOM5, GCM_SERCOM5_CORE, SERCOM5_IRQn, +#endif +}; -void SERCOM::initClockNVIC( void ) -{ - uint8_t clockId = 0; - IRQn_Type IdNvic=PendSV_IRQn ; // Dummy init to intercept potential error later +#endif // end !SAMD51 - if(sercom == SERCOM0) - { - clockId = GCM_SERCOM0_CORE; - IdNvic = SERCOM0_IRQn; - } - else if(sercom == SERCOM1) - { - clockId = GCM_SERCOM1_CORE; - IdNvic = SERCOM1_IRQn; - } - else if(sercom == SERCOM2) - { - clockId = GCM_SERCOM2_CORE; - IdNvic = SERCOM2_IRQn; - } - else if(sercom == SERCOM3) - { - clockId = GCM_SERCOM3_CORE; - IdNvic = SERCOM3_IRQn; - } - #if defined(SERCOM4) - else if(sercom == SERCOM4) - { - clockId = GCM_SERCOM4_CORE; - IdNvic = SERCOM4_IRQn; +int8_t SERCOM::getSercomIndex(void) { + for(uint8_t i=0; i<(sizeof(sercomData) / sizeof(sercomData[0])); i++) { + if(sercom == sercomData[i].sercomPtr) return i; } - #endif // SERCOM4 - #if defined(SERCOM5) - else if(sercom == SERCOM5) - { - clockId = GCM_SERCOM5_CORE; - IdNvic = SERCOM5_IRQn; + return -1; +} + +#if defined(__SAMD51__) +// This is currently for overriding an SPI SERCOM's clock source only -- +// NOT for UART or WIRE SERCOMs, where it will have unintended consequences. +// It does not check. +// SERCOM clock source override is available only on SAMD51 (not 21). +// A dummy function for SAMD21 (compiles to nothing) is present in SERCOM.h +// so user code doesn't require a lot of conditional situations. +void SERCOM::setClockSource(int8_t idx, SercomClockSource src, bool core) { + + if(src == SERCOM_CLOCK_SOURCE_NO_CHANGE) return; + + uint8_t clk_id = core ? sercomData[idx].id_core : sercomData[idx].id_slow; + + GCLK->PCHCTRL[clk_id].bit.CHEN = 0; // Disable timer + while(GCLK->PCHCTRL[clk_id].bit.CHEN); // Wait for disable + + if(core) clockSource = src; // Save SercomClockSource value + + // From cores/arduino/startup.c: + // GCLK0 = F_CPU + // GCLK1 = 48 MHz + // GCLK2 = 100 MHz + // GCLK3 = XOSC32K + // GCLK4 = 12 MHz + if(src == SERCOM_CLOCK_SOURCE_FCPU) { + GCLK->PCHCTRL[clk_id].reg = + GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + if(core) freqRef = F_CPU; // Save clock frequency value + } else if(src == SERCOM_CLOCK_SOURCE_48M) { + GCLK->PCHCTRL[clk_id].reg = + GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + if(core) freqRef = 48000000; + } else if(src == SERCOM_CLOCK_SOURCE_100M) { + GCLK->PCHCTRL[clk_id].reg = + GCLK_PCHCTRL_GEN_GCLK2_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + if(core) freqRef = 100000000; + } else if(src == SERCOM_CLOCK_SOURCE_32K) { + GCLK->PCHCTRL[clk_id].reg = + GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + if(core) freqRef = 32768; + } else if(src == SERCOM_CLOCK_SOURCE_12M) { + GCLK->PCHCTRL[clk_id].reg = + GCLK_PCHCTRL_GEN_GCLK4_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); + if(core) freqRef = 12000000; } - #endif // SERCOM5 - if ( IdNvic == PendSV_IRQn ) - { - // We got a problem here - return ; + while(!GCLK->PCHCTRL[clk_id].bit.CHEN); // Wait for clock enable +} +#endif + +void SERCOM::initClockNVIC( void ) +{ + int8_t idx = getSercomIndex(); + if(idx < 0) return; // We got a problem here + +#if defined(__SAMD51__) + + for(uint8_t i=0; i<4; i++) { + NVIC_ClearPendingIRQ(sercomData[idx].irq[i]); + NVIC_SetPriority(sercomData[idx].irq[i], SERCOM_NVIC_PRIORITY); + NVIC_EnableIRQ(sercomData[idx].irq[i]); } + // SPI DMA speed is dictated by the "slow clock" (I think...maybe) so + // BOTH are set to the same clock source (clk_slow isn't sourced from + // XOSC32K as in prior versions of SAMD core). + // This might have power implications for sleep code. + + setClockSource(idx, clockSource, true); // true = core clock + setClockSource(idx, clockSource, false); // false = slow clock + +#else // end if SAMD51 (prob SAMD21) + + uint8_t clockId = sercomData[idx].clock; + IRQn_Type IdNvic = sercomData[idx].irqn; + // Setting NVIC + NVIC_ClearPendingIRQ(IdNvic); + NVIC_SetPriority(IdNvic, SERCOM_NVIC_PRIORITY); NVIC_EnableIRQ(IdNvic); - NVIC_SetPriority (IdNvic, SERCOM_NVIC_PRIORITY); /* set Priority */ - //Setting clock - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx) - GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source - GCLK_CLKCTRL_CLKEN ; + // Setting clock + GCLK->CLKCTRL.reg = + GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx) + GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source + GCLK_CLKCTRL_CLKEN; - while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) - { - /* Wait for synchronization */ - } + while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // Wait for synchronization + +#endif // end !SAMD51 } diff --git a/cores/arduino/SERCOM.h b/cores/arduino/SERCOM.h index 750592aee..c717e78b6 100644 --- a/cores/arduino/SERCOM.h +++ b/cores/arduino/SERCOM.h @@ -21,8 +21,19 @@ #include "sam.h" -#define SERCOM_FREQ_REF 48000000 -#define SERCOM_NVIC_PRIORITY ((1<<__NVIC_PRIO_BITS) - 1) +// SAMD51 has configurable MAX_SPI, else use peripheral clock default. +// Update: changing MAX_SPI via compiler flags is DEPRECATED, because +// this affects ALL SPI peripherals including some that should NOT be +// changed (e.g. anything using SD card). Instead, use setClockSource(). +// This is left here for compatibility w/interim MAX_SPI-dependent code: +#if defined(MAX_SPI) + #define SERCOM_SPI_FREQ_REF (MAX_SPI * 2) +#else + #define SERCOM_SPI_FREQ_REF 48000000ul +#endif +// Other SERCOM peripherals always use the 48 MHz clock +#define SERCOM_FREQ_REF 48000000ul +#define SERCOM_NVIC_PRIORITY ((1<<__NVIC_PRIO_BITS) - 1) typedef enum { @@ -80,23 +91,23 @@ typedef enum typedef enum { - UART_TX_PAD_0 = 0x0ul, // Only for UART + UART_TX_PAD_0 = 0x0ul, // Only for UART UART_TX_PAD_2 = 0x1ul, // Only for UART UART_TX_RTS_CTS_PAD_0_2_3 = 0x2ul, // Only for UART with TX on PAD0, RTS on PAD2 and CTS on PAD3 } SercomUartTXPad; typedef enum { - SAMPLE_RATE_x16 = 0x1, //Fractional - SAMPLE_RATE_x8 = 0x3, //Fractional + SAMPLE_RATE_x16 = 0x1, // Fractional + SAMPLE_RATE_x8 = 0x3, // Fractional } SercomUartSampleRate; typedef enum { - SERCOM_SPI_MODE_0 = 0, // CPOL : 0 | CPHA : 0 - SERCOM_SPI_MODE_1, // CPOL : 0 | CPHA : 1 - SERCOM_SPI_MODE_2, // CPOL : 1 | CPHA : 0 - SERCOM_SPI_MODE_3 // CPOL : 1 | CPHA : 1 + SERCOM_SPI_MODE_0 = 0, // CPOL : 0 | CPHA : 0 + SERCOM_SPI_MODE_1, // CPOL : 0 | CPHA : 1 + SERCOM_SPI_MODE_2, // CPOL : 1 | CPHA : 0 + SERCOM_SPI_MODE_3 // CPOL : 1 | CPHA : 1 } SercomSpiClockMode; typedef enum @@ -141,6 +152,19 @@ typedef enum WIRE_MASTER_NACK_ACTION } SercomMasterAckActionWire; +// SERCOM clock source override is available only on SAMD51 (not 21) +// but the enumeration is made regardless so user code doesn't need +// ifdefs or lengthy comments explaining the different situations -- +// the clock-sourcing functions just compile to nothing on SAMD21. +typedef enum { + SERCOM_CLOCK_SOURCE_FCPU, // F_CPU clock (GCLK0) + SERCOM_CLOCK_SOURCE_48M, // 48 MHz peripheral clock (GCLK1) (standard) + SERCOM_CLOCK_SOURCE_100M, // 100 MHz peripheral clock (GCLK2) + SERCOM_CLOCK_SOURCE_32K, // XOSC32K clock (GCLK3) + SERCOM_CLOCK_SOURCE_12M, // 12 MHz peripheral clock (GCLK4) + SERCOM_CLOCK_SOURCE_NO_CHANGE // Leave clock source setting unchanged +} SercomClockSource; + class SERCOM { public: @@ -171,7 +195,6 @@ class SERCOM /* ========== SPI ========== */ void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) ; void initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) ; - void resetSPI( void ) ; void enableSPI( void ) ; void disableSPI( void ) ; @@ -202,6 +225,9 @@ class SERCOM bool isSlaveWIRE( void ) ; bool isBusIdleWIRE( void ) ; bool isBusOwnerWIRE( void ) ; + bool isBusUnknownWIRE( void ) ; + bool isArbLostWIRE( void ); + bool isBusBusyWIRE( void ); bool isDataReadyWIRE( void ) ; bool isStopDetectedWIRE( void ) ; bool isRestartDetectedWIRE( void ) ; @@ -210,10 +236,30 @@ class SERCOM bool isRXNackReceivedWIRE( void ) ; int availableWIRE( void ) ; uint8_t readDataWIRE( void ) ; + int8_t getSercomIndex(void); +#if defined(__SAMD51__) + // SERCOM clock source override is only available on + // SAMD51 (not 21) ... but these functions are declared + // regardless so user code doesn't need ifdefs or lengthy + // comments explaining the different situations -- these + // just compile to nothing on SAMD21. + void setClockSource(int8_t idx, SercomClockSource src, bool core); + SercomClockSource getClockSource(void) { return clockSource; }; + uint32_t getFreqRef(void) { return freqRef; }; +#else + // The equivalent SAMD21 dummy functions... + void setClockSource(int8_t idx, SercomClockSource src, bool core) { (void)idx; (void)src; (void)core; }; + SercomClockSource getClockSource(void) { return SERCOM_CLOCK_SOURCE_FCPU; }; + uint32_t getFreqRef(void) { return F_CPU; }; +#endif private: Sercom* sercom; - uint8_t calculateBaudrateSynchronous(uint32_t baudrate) ; +#if defined(__SAMD51__) + SercomClockSource clockSource; + uint32_t freqRef; // Frequency corresponding to clockSource +#endif + uint8_t calculateBaudrateSynchronous(uint32_t baudrate); uint32_t division(uint32_t dividend, uint32_t divisor) ; void initClockNVIC( void ) ; }; diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp index d2846316d..c32f89d60 100644 --- a/cores/arduino/Stream.cpp +++ b/cores/arduino/Stream.cpp @@ -35,6 +35,7 @@ int Stream::timedRead() do { c = read(); if (c >= 0) return c; + yield(); // running TinyUSB task } while(millis() - _startMillis < _timeout); return -1; // -1 indicates timeout } @@ -47,6 +48,7 @@ int Stream::timedPeek() do { c = peek(); if (c >= 0) return c; + yield(); // running TinyUSB task } while(millis() - _startMillis < _timeout); return -1; // -1 indicates timeout } diff --git a/cores/arduino/Tone.cpp b/cores/arduino/Tone.cpp index 45b438d9b..1d4ddc406 100644 --- a/cores/arduino/Tone.cpp +++ b/cores/arduino/Tone.cpp @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,8 +20,6 @@ #include "Tone.h" #include "variant.h" -#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY); - uint32_t toneMaxFrequency = F_CPU / 2; uint32_t lastOutputPin = 0xFFFFFFFF; @@ -31,13 +30,25 @@ volatile int64_t toggleCount; volatile bool toneIsActive = false; volatile bool firstTimeRunning = false; -#define TONE_TC TC5 -#define TONE_TC_IRQn TC5_IRQn +#if defined(__SAMD51__) + #define TONE_TC TC0 + #define TONE_TC_IRQn TC0_IRQn + #define TONE_TC_GCLK_ID TC0_GCLK_ID + #define Tone_Handler TC0_Handler + + #define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.SYNCBUSY.bit.ENABLE); + +#else + #define TONE_TC TC5 + #define TONE_TC_IRQn TC5_IRQn + #define Tone_Handler TC5_Handler + + #define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY); +#endif + #define TONE_TC_TOP 0xFFFF #define TONE_TC_CHANNEL 0 -void TC5_Handler (void) __attribute__ ((weak, alias("Tone_Handler"))); - static inline void resetTC (Tc* TCx) { // Disable TCx @@ -57,6 +68,14 @@ void toneAccurateClock (uint32_t accurateSystemCoreClockFrequency) void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration) { + + // Avoid divide by zero error by calling 'noTone' instead + if (frequency == 0) + { + noTone(outputPin); + return; + } + // Configure interrupt request NVIC_DisableIRQ(TONE_TC_IRQn); NVIC_ClearPendingIRQ(TONE_TC_IRQn); @@ -65,11 +84,15 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration) { firstTimeRunning = true; - NVIC_SetPriority(TONE_TC_IRQn, 0); - + NVIC_SetPriority(TONE_TC_IRQn, 5); + +#if defined(__SAMD51__) + GCLK->PCHCTRL[TONE_TC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); +#else // Enable GCLK for TC4 and TC5 (timer counter input clock) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)); while (GCLK->STATUS.bit.SYNCBUSY); +#endif } if (toneIsActive && (outputPin != lastOutputPin)) @@ -120,7 +143,12 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration) uint16_t tmpReg = 0; tmpReg |= TC_CTRLA_MODE_COUNT16; // Set Timer counter Mode to 16 bits + +#if defined(__SAMD51__) + TONE_TC->COUNT16.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ; // Set TONE_TC mode as match frequency +#else tmpReg |= TC_CTRLA_WAVEGEN_MFRQ; // Set TONE_TC mode as match frequency +#endif tmpReg |= prescalerConfigBits; TONE_TC->COUNT16.CTRLA.reg |= tmpReg; WAIT_TC16_REGS_SYNC(TONE_TC) @@ -152,9 +180,19 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration) void noTone (uint32_t outputPin) { - resetTC(TONE_TC); - digitalWrite(outputPin, LOW); - toneIsActive = false; + /* 'tone' need to run at least once in order to enable GCLK for + * the timers used for the tone-functionality. If 'noTone' is called + * without ever calling 'tone' before then 'WAIT_TC16_REGS_SYNC(TCx)' + * will wait infinitely. The variable 'firstTimeRunning' is set the + * 1st time 'tone' is set so it can be used to detect wether or not + * 'tone' has been called before. + */ + if(firstTimeRunning) + { + resetTC(TONE_TC); + digitalWrite(outputPin, LOW); + toneIsActive = false; + } } #ifdef __cplusplus diff --git a/cores/arduino/USB/CDC.cpp b/cores/arduino/USB/CDC.cpp index c60388deb..10710417c 100644 --- a/cores/arduino/USB/CDC.cpp +++ b/cores/arduino/USB/CDC.cpp @@ -16,6 +16,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef USE_TINYUSB + #include #include // Needed for auto-reset with 1200bps port touch @@ -206,7 +208,20 @@ void Serial_::flush(void) size_t Serial_::write(const uint8_t *buffer, size_t size) { - uint32_t r = usb.send(CDC_ENDPOINT_IN, buffer, 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) + uint32_t r = 0; + if (_usbLineInfo.lineState > 0) // Problem with Windows(R) + { + r = usb.send(CDC_ENDPOINT_IN, buffer, size); + } if (r > 0) { return r; @@ -288,6 +303,8 @@ bool Serial_::rts() { return _usbLineInfo.lineState & 0x2; } -Serial_ SerialUSB(USBDevice); +Serial_ Serial(USBDevice); #endif + +#endif // USE_TINYUSB diff --git a/cores/arduino/USB/PluggableUSB.cpp b/cores/arduino/USB/PluggableUSB.cpp index 4c52c1fad..f94c5647f 100644 --- a/cores/arduino/USB/PluggableUSB.cpp +++ b/cores/arduino/USB/PluggableUSB.cpp @@ -17,6 +17,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef USE_TINYUSB + #include "USBAPI.h" #include "USBDesc.h" #include "USBCore.h" @@ -113,4 +115,6 @@ PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT) } #endif -#endif \ No newline at end of file +#endif + +#endif // USE_TINYUSB diff --git a/cores/arduino/USB/SAMD21_USBDevice.cpp b/cores/arduino/USB/SAMD21_USBDevice.cpp new file mode 100644 index 000000000..f45d256dc --- /dev/null +++ b/cores/arduino/USB/SAMD21_USBDevice.cpp @@ -0,0 +1,41 @@ +/* + * SAMD21_USBDevice.cpp + * + * Created on: Feb 21, 2018 + * Author: deanm + */ + +#ifndef USE_TINYUSB + +#include "SAMD21_USBDevice.h" + +void USBDevice_SAMD21G18x::reset() { + usb.CTRLA.bit.SWRST = 1; + memset(EP, 0, sizeof(EP)); + while (usb.SYNCBUSY.bit.SWRST || usb.SYNCBUSY.bit.ENABLE) {} + usb.DESCADD.reg = (uint32_t)(&EP); +} + +void USBDevice_SAMD21G18x::calibrate() { + // Load Pad Calibration data from non-volatile memory + uint32_t *pad_transn_p = (uint32_t *) USB_FUSES_TRANSN_ADDR; + uint32_t *pad_transp_p = (uint32_t *) USB_FUSES_TRANSP_ADDR; + uint32_t *pad_trim_p = (uint32_t *) USB_FUSES_TRIM_ADDR; + + uint32_t pad_transn = (*pad_transn_p & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; + uint32_t pad_transp = (*pad_transp_p & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; + uint32_t pad_trim = (*pad_trim_p & USB_FUSES_TRIM_Msk ) >> USB_FUSES_TRIM_Pos; + + if (pad_transn == 0x1F) // maximum value (31) + pad_transn = 5; + if (pad_transp == 0x1F) // maximum value (31) + pad_transp = 29; + if (pad_trim == 0x7) // maximum value (7) + pad_trim = 3; + + usb.PADCAL.bit.TRANSN = pad_transn; + usb.PADCAL.bit.TRANSP = pad_transp; + usb.PADCAL.bit.TRIM = pad_trim; +} + +#endif // USE_TINYUSB diff --git a/cores/arduino/USB/SAMD21_USBDevice.h b/cores/arduino/USB/SAMD21_USBDevice.h index 3296a1346..00da069db 100644 --- a/cores/arduino/USB/SAMD21_USBDevice.h +++ b/cores/arduino/USB/SAMD21_USBDevice.h @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -39,8 +40,18 @@ class USBDevice_SAMD21G18x { void reset(); // Enable - inline void enable() { usb.CTRLA.bit.ENABLE = 1; } - inline void disable() { usb.CTRLA.bit.ENABLE = 0; } + inline void enable() { + usb.CTRLA.bit.ENABLE = 1; +#if defined(__SAMD51__) + while( usb.SYNCBUSY.reg & USB_SYNCBUSY_ENABLE ); //wait for sync +#endif + } + inline void disable() { + usb.CTRLA.bit.ENABLE = 0; +#if defined(__SAMD51__) + while( usb.SYNCBUSY.reg & USB_SYNCBUSY_ENABLE ); //wait for sync +#endif + } // USB mode (device/host) inline void setUSBDeviceMode() { usb.CTRLA.bit.MODE = USB_CTRLA_MODE_DEVICE_Val; } @@ -167,35 +178,6 @@ class USBDevice_SAMD21G18x { __attribute__((__aligned__(4))) UsbDeviceDescriptor EP[USB_EPT_NUM]; }; -void USBDevice_SAMD21G18x::reset() { - usb.CTRLA.bit.SWRST = 1; - memset(EP, 0, sizeof(EP)); - while (usb.SYNCBUSY.bit.SWRST) {} - usb.DESCADD.reg = (uint32_t)(&EP); -} - -void USBDevice_SAMD21G18x::calibrate() { - // Load Pad Calibration data from non-volatile memory - uint32_t *pad_transn_p = (uint32_t *) USB_FUSES_TRANSN_ADDR; - uint32_t *pad_transp_p = (uint32_t *) USB_FUSES_TRANSP_ADDR; - uint32_t *pad_trim_p = (uint32_t *) USB_FUSES_TRIM_ADDR; - - uint32_t pad_transn = (*pad_transn_p & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; - uint32_t pad_transp = (*pad_transp_p & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; - uint32_t pad_trim = (*pad_trim_p & USB_FUSES_TRIM_Msk ) >> USB_FUSES_TRIM_Pos; - - if (pad_transn == 0x1F) // maximum value (31) - pad_transn = 5; - if (pad_transp == 0x1F) // maximum value (31) - pad_transp = 29; - if (pad_trim == 0x7) // maximum value (7) - pad_trim = 3; - - usb.PADCAL.bit.TRANSN = pad_transn; - usb.PADCAL.bit.TRANSP = pad_transp; - usb.PADCAL.bit.TRIM = pad_trim; -} - /* * Synchronization primitives. * TODO: Move into a separate header file and make an API out of it @@ -221,7 +203,6 @@ class __Guard { #define synchronized for (__Guard __guard; __guard.enter(); ) - /* * USB EP generic handlers. */ @@ -231,6 +212,8 @@ class EPHandler { virtual void handleEndpoint() = 0; virtual uint32_t recv(void *_data, uint32_t len) = 0; virtual uint32_t available() const = 0; + + virtual void init() = 0; }; class DoubleBufferedEPOutHandler : public EPHandler { @@ -258,6 +241,7 @@ class DoubleBufferedEPOutHandler : public EPHandler { free((void*)data0); free((void*)data1); } + void init() {}; virtual uint32_t recv(void *_data, uint32_t len) { @@ -402,4 +386,3 @@ class DoubleBufferedEPOutHandler : public EPHandler { volatile bool notify; }; - diff --git a/cores/arduino/USB/SAMR21_USBDevice.h b/cores/arduino/USB/SAMR21_USBDevice.h new file mode 100644 index 000000000..1da5579ac --- /dev/null +++ b/cores/arduino/USB/SAMR21_USBDevice.h @@ -0,0 +1,197 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + 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 +*/ + +#pragma once + +#include + +#include +#include +#include + +typedef uint8_t ep_t; + +class USBDevice_SAMR21G18x { +public: + USBDevice_SAMR21G18x() : usb(USB->DEVICE) { + // Empty + } + + // USB Device function mapping + // --------------------------- + + // Reset USB Device + void reset(); + + // Enable + inline void enable() { usb.CTRLA.bit.ENABLE = 1; } + inline void disable() { usb.CTRLA.bit.ENABLE = 0; } + + // USB mode (device/host) + inline void setUSBDeviceMode() { usb.CTRLA.bit.MODE = USB_CTRLA_MODE_DEVICE_Val; } + inline void setUSBHostMode() { usb.CTRLA.bit.MODE = USB_CTRLA_MODE_HOST_Val; } + + inline void runInStandby() { usb.CTRLA.bit.RUNSTDBY = 1; } + inline void noRunInStandby() { usb.CTRLA.bit.RUNSTDBY = 0; } + + // USB speed + inline void setFullSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_FS_Val; } + inline void setLowSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_LS_Val; } + inline void setHiSpeed() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_HS_Val; } + inline void setHiSpeedTestMode() { usb.CTRLB.bit.SPDCONF = USB_DEVICE_CTRLB_SPDCONF_HSTM_Val; } + + // Authorize attach if Vbus is present + inline void attach() { usb.CTRLB.bit.DETACH = 0; } + inline void detach() { usb.CTRLB.bit.DETACH = 1; } + + // USB Interrupts + inline bool isEndOfResetInterrupt() { return usb.INTFLAG.bit.EORST; } + inline void ackEndOfResetInterrupt() { usb.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST; } + inline void enableEndOfResetInterrupt() { usb.INTENSET.bit.EORST = 1; } + inline void disableEndOfResetInterrupt() { usb.INTENCLR.bit.EORST = 1; } + + inline bool isStartOfFrameInterrupt() { return usb.INTFLAG.bit.SOF; } + inline void ackStartOfFrameInterrupt() { usb.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; } + inline void enableStartOfFrameInterrupt() { usb.INTENSET.bit.SOF = 1; } + inline void disableStartOfFrameInterrupt() { usb.INTENCLR.bit.SOF = 1; } + + // USB Address + inline void setAddress(uint32_t addr) { usb.DADD.bit.DADD = addr; usb.DADD.bit.ADDEN = 1; } + inline void unsetAddress() { usb.DADD.bit.DADD = 0; usb.DADD.bit.ADDEN = 0; } + + // Frame number + inline uint16_t frameNumber() { return usb.FNUM.bit.FNUM; } + + // Load calibration values + void calibrate(); + + // USB Device Endpoints function mapping + // ------------------------------------- + + // Config + inline void epBank0SetType(ep_t ep, uint8_t type) { usb.DeviceEndpoint[ep].EPCFG.bit.EPTYPE0 = type; } + inline void epBank1SetType(ep_t ep, uint8_t type) { usb.DeviceEndpoint[ep].EPCFG.bit.EPTYPE1 = type; } + + // Interrupts + inline uint16_t epInterruptSummary() { return usb.EPINTSMRY.reg; } + + inline bool epBank0IsSetupReceived(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.RXSTP; } + inline bool epBank0IsStalled(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.STALL0; } + inline bool epBank1IsStalled(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.STALL1; } + inline bool epBank0IsTransferComplete(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT0; } + inline bool epBank1IsTransferComplete(ep_t ep) { return usb.DeviceEndpoint[ep].EPINTFLAG.bit.TRCPT1; } + + inline void epBank0AckSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_RXSTP; } + inline void epBank0AckStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL(1); } + inline void epBank1AckStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL(2); } + inline void epBank0AckTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT(1); } + inline void epBank1AckTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT(2); } + + inline void epBank0EnableSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.RXSTP = 1; } + inline void epBank0EnableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.STALL0 = 1; } + inline void epBank1EnableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.STALL1 = 1; } + inline void epBank0EnableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRCPT0 = 1; } + inline void epBank1EnableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENSET.bit.TRCPT1 = 1; } + + inline void epBank0DisableSetupReceived(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.RXSTP = 1; } + inline void epBank0DisableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.STALL0 = 1; } + inline void epBank1DisableStalled(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.STALL1 = 1; } + inline void epBank0DisableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRCPT0 = 1; } + inline void epBank1DisableTransferComplete(ep_t ep) { usb.DeviceEndpoint[ep].EPINTENCLR.bit.TRCPT1 = 1; } + + // Status + inline bool epBank0IsReady(ep_t ep) { return usb.DeviceEndpoint[ep].EPSTATUS.bit.BK0RDY; } + inline bool epBank1IsReady(ep_t ep) { return usb.DeviceEndpoint[ep].EPSTATUS.bit.BK1RDY; } + inline void epBank0SetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.BK0RDY = 1; } + inline void epBank1SetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.BK1RDY = 1; } + inline void epBank0ResetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.BK0RDY = 1; } + inline void epBank1ResetReady(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.BK1RDY = 1; } + + inline void epBank0SetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.STALLRQ0 = 1; } + inline void epBank1SetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSSET.bit.STALLRQ1 = 1; } + inline void epBank0ResetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.STALLRQ0 = 1; } + inline void epBank1ResetStallReq(ep_t ep) { usb.DeviceEndpoint[ep].EPSTATUSCLR.bit.STALLRQ1 = 1; } + + // Packet + inline uint16_t epBank0ByteCount(ep_t ep) { return EP[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT; } + inline uint16_t epBank1ByteCount(ep_t ep) { return EP[ep].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT; } + inline void epBank0SetByteCount(ep_t ep, uint16_t bc) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = bc; } + inline void epBank1SetByteCount(ep_t ep, uint16_t bc) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = bc; } + inline void epBank0SetMultiPacketSize(ep_t ep, uint16_t s) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = s; } + inline void epBank1SetMultiPacketSize(ep_t ep, uint16_t s) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = s; } + + inline void epBank0SetAddress(ep_t ep, void *addr) { EP[ep].DeviceDescBank[0].ADDR.reg = (uint32_t)addr; } + inline void epBank1SetAddress(ep_t ep, void *addr) { EP[ep].DeviceDescBank[1].ADDR.reg = (uint32_t)addr; } + inline void epBank0SetSize(ep_t ep, uint16_t size) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.SIZE = EP_PCKSIZE_SIZE(size); } + inline void epBank1SetSize(ep_t ep, uint16_t size) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.SIZE = EP_PCKSIZE_SIZE(size); } + inline uint8_t EP_PCKSIZE_SIZE(uint16_t size) { + switch (size) { + case 8: return 0; + case 16: return 1; + case 32: return 2; + case 64: return 3; + case 128: return 4; + case 256: return 5; + case 512: return 6; + case 1023: return 7; + default: return 0; + } + } + + inline void epBank0DisableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.AUTO_ZLP = 0; } + inline void epBank1DisableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = 0; } + inline void epBank0EnableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[0].PCKSIZE.bit.AUTO_ZLP = 1; } + inline void epBank1EnableAutoZLP(ep_t ep) { EP[ep].DeviceDescBank[1].PCKSIZE.bit.AUTO_ZLP = 1; } + +private: + // USB Device registers + UsbDevice &usb; + + // Endpoints descriptors table + __attribute__((__aligned__(4))) UsbDeviceDescriptor EP[USB_EPT_NUM]; +}; + +void USBDevice_SAMR21G18x::reset() { + usb.CTRLA.bit.SWRST = 1; + memset(EP, 0, sizeof(EP)); + while (usb.SYNCBUSY.bit.SWRST) {} + usb.DESCADD.reg = (uint32_t)(&EP); +} + +void USBDevice_SAMR21G18x::calibrate() { + // Load Pad Calibration data from non-volatile memory + uint32_t *pad_transn_p = (uint32_t *) USB_FUSES_TRANSN_ADDR; + uint32_t *pad_transp_p = (uint32_t *) USB_FUSES_TRANSP_ADDR; + uint32_t *pad_trim_p = (uint32_t *) USB_FUSES_TRIM_ADDR; + + uint32_t pad_transn = (*pad_transn_p & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; + uint32_t pad_transp = (*pad_transp_p & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; + uint32_t pad_trim = (*pad_trim_p & USB_FUSES_TRIM_Msk ) >> USB_FUSES_TRIM_Pos; + + if (pad_transn == 0x1F) // maximum value (31) + pad_transn = 5; + if (pad_transp == 0x1F) // maximum value (31) + pad_transp = 29; + if (pad_trim == 0x7) // maximum value (7) + pad_trim = 3; + + usb.PADCAL.bit.TRANSN = pad_transn; + usb.PADCAL.bit.TRANSP = pad_transp; + usb.PADCAL.bit.TRIM = pad_trim; +} + diff --git a/cores/arduino/USB/USBAPI.h b/cores/arduino/USB/USBAPI.h index 379f55ed3..f45051148 100644 --- a/cores/arduino/USB/USBAPI.h +++ b/cores/arduino/USB/USBAPI.h @@ -31,10 +31,17 @@ #include "Stream.h" #include "RingBuffer.h" +#ifdef __SAMR21G18A__ +#include "SAMR21_USBDevice.h" +#else +#include "SAMD21_USBDevice.h" +#endif //================================================================================ // USB +class EPHandler; + // Low level API typedef struct { union { @@ -78,7 +85,7 @@ class USBDeviceClass { uint32_t sendControl(int /* ep */, const void *data, uint32_t len) { return sendControl(data, len); } uint32_t recvControl(void *data, uint32_t len); uint32_t sendConfiguration(uint32_t maxlen); - bool sendStringDescriptor(const uint8_t *string, uint8_t maxlen); + bool sendStringDescriptor(const uint8_t *string, uint32_t maxlen); void initControl(int end); uint8_t SendInterfaces(uint32_t* total); void packMessages(bool val); @@ -86,6 +93,7 @@ class USBDeviceClass { // Generic EndPoint API void initEndpoints(void); void initEP(uint32_t ep, uint32_t type); + void setHandler(uint32_t ep, EPHandler *handler); void handleEndpoint(uint8_t ep); uint32_t send(uint32_t ep, const void *data, uint32_t len); @@ -178,7 +186,7 @@ class Serial_ : public Stream RingBuffer *_cdc_rx_buffer; bool stalled; }; -extern Serial_ SerialUSB; +extern Serial_ Serial; //================================================================================ //================================================================================ diff --git a/cores/arduino/USB/USBCore.cpp b/cores/arduino/USB/USBCore.cpp index ee7b90a44..83a3e5d32 100644 --- a/cores/arduino/USB/USBCore.cpp +++ b/cores/arduino/USB/USBCore.cpp @@ -1,5 +1,6 @@ /* Copyright (c) 2016 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -15,12 +16,18 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - +#ifndef USE_TINYUSB #if defined(USBCON) #include -#include "SAMD21_USBDevice.h" +// there are ~slight~ CMSIS differences :/ +#ifdef __SAMR21G18A__ + #include "SAMR21_USBDevice.h" +#else + #include "SAMD21_USBDevice.h" +#endif + #include "PluggableUSB.h" #include @@ -28,7 +35,12 @@ #include #include +#ifdef __SAMR21G18A__ +USBDevice_SAMR21G18x usbd; +#else USBDevice_SAMD21G18x usbd; +#endif + /** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ #define TX_RX_LED_PULSE_MS 100 @@ -98,12 +110,12 @@ static EPHandler *epHandlers[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; // Send a USB descriptor string. The string is stored as a // plain ASCII string but is sent out as UTF-16 with the // correct 2-byte prefix -bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint8_t maxlen) +bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint32_t maxlen) { if (maxlen < 2) return false; - uint8_t buffer[maxlen]; + uint8_t* buffer = (uint8_t*)malloc(maxlen); buffer[0] = strlen((const char*)string) * 2 + 2; buffer[1] = 0x03; @@ -114,7 +126,9 @@ bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint8_t maxlen) buffer[i] = 0; } - return USBDevice.sendControl(buffer, i); + bool ret = USBDevice.sendControl(buffer, i); + free(buffer); + return ret; } bool _dry_run = false; @@ -232,19 +246,24 @@ bool USBDeviceClass::sendDescriptor(USBSetup &setup) } else if (setup.wValueL == ISERIAL) { #ifdef PLUGGABLE_USB_ENABLED +#ifdef __SAMD51__ + #define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x008061FC) + #define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x00806010) + #define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x00806014) + #define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x00806018) +#else // samd21 // from section 9.3.3 of the datasheet #define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x0080A00C) #define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x0080A040) #define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x0080A044) #define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x0080A048) - +#endif char name[ISERIAL_MAX_LEN]; utox8(SERIAL_NUMBER_WORD_0, &name[0]); utox8(SERIAL_NUMBER_WORD_1, &name[8]); utox8(SERIAL_NUMBER_WORD_2, &name[16]); utox8(SERIAL_NUMBER_WORD_3, &name[24]); - - PluggableUSB().getShortName(&name[32]); + name[32] = '\0'; return sendStringDescriptor((uint8_t*)name, setup.wLength); #endif } @@ -313,9 +332,24 @@ void USBDeviceClass::init() digitalWrite(PIN_LED_RXL, HIGH); #endif - // Enable USB clock + /* Enable USB clock */ +#if defined(__SAMD51__) + MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB; + MCLK->AHBMASK.reg |= MCLK_AHBMASK_USB; + + // Set up the USB DP/DN pins + PORT->Group[0].PINCFG[PIN_PA24H_USB_DM].bit.PMUXEN = 1; + PORT->Group[0].PMUX[PIN_PA24H_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24H_USB_DM & 0x01u))); + PORT->Group[0].PMUX[PIN_PA24H_USB_DM/2].reg |= MUX_PA24H_USB_DM << (4 * (PIN_PA24H_USB_DM & 0x01u)); + PORT->Group[0].PINCFG[PIN_PA25H_USB_DP].bit.PMUXEN = 1; + PORT->Group[0].PMUX[PIN_PA25H_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25H_USB_DP & 0x01u))); + PORT->Group[0].PMUX[PIN_PA25H_USB_DP/2].reg |= MUX_PA25H_USB_DP << (4 * (PIN_PA25H_USB_DP & 0x01u)); + + + GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); +#else PM->APBBMASK.reg |= PM_APBBMASK_USB; - + // Set up the USB DP/DN pins PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1; PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u))); @@ -326,10 +360,11 @@ void USBDeviceClass::init() // Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference) GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6) | // Generic Clock Multiplexer 6 - GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source - GCLK_CLKCTRL_CLKEN; + GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source + GCLK_CLKCTRL_CLKEN; while (GCLK->STATUS.bit.SYNCBUSY) - ; + ; +#endif USB_SetHandler(&UDD_Handler); @@ -342,8 +377,20 @@ void USBDeviceClass::init() usbd.setFullSpeed(); // Configure interrupts +#if defined(__SAMD51__) + /* Attach to the USB host */ + NVIC_SetPriority(USB_0_IRQn, 0UL); + NVIC_SetPriority(USB_1_IRQn, 0UL); + NVIC_SetPriority(USB_2_IRQn, 0UL); + NVIC_SetPriority(USB_3_IRQn, 0UL); + NVIC_EnableIRQ(USB_0_IRQn); + NVIC_EnableIRQ(USB_1_IRQn); + NVIC_EnableIRQ(USB_2_IRQn); + NVIC_EnableIRQ(USB_3_IRQn); +#else NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL); NVIC_EnableIRQ((IRQn_Type) USB_IRQn); +#endif usbd.enable(); @@ -356,6 +403,7 @@ bool USBDeviceClass::attach() return false; usbd.attach(); + usbd.enableEndOfResetInterrupt(); usbd.enableStartOfFrameInterrupt(); @@ -466,6 +514,12 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config) } epHandlers[ep] = new DoubleBufferedEPOutHandler(usbd, ep, 256); } + else if (config == (USB_ENDPOINT_TYPE_INTERRUPT | USB_ENDPOINT_OUT(0))) + { + if(epHandlers[ep]){ + epHandlers[ep]->init(); + } + } else if (config == (USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(0))) { usbd.epBank1SetSize(ep, 64); @@ -497,6 +551,10 @@ void USBDeviceClass::initEP(uint32_t ep, uint32_t config) } } +void USBDeviceClass::setHandler(uint32_t ep, EPHandler *handler) { + epHandlers[ep] = handler; +} + void USBDeviceClass::flush(uint32_t ep) { if (available(ep)) { @@ -692,8 +750,8 @@ uint32_t USBDeviceClass::send(uint32_t ep, const void *data, uint32_t len) LastTransmitTimedOut[ep] = 0; - if (len >= EPX_SIZE) { - length = EPX_SIZE - 1; + if (len > EPX_SIZE) { + length = EPX_SIZE; } else { length = len; } @@ -821,6 +879,7 @@ bool USBDeviceClass::handleStandardSetup(USBSetup &setup) sendZlp(0); return true; } + return false; case SET_ADDRESS: setAddress(setup.wValueL); @@ -954,6 +1013,7 @@ void USBDeviceClass::ISRHandler() // Check if endpoint has a pending interrupt if ((ept_int & (1 << i)) != 0) { + // Endpoint Transfer Complete (0/1) Interrupt if (usbd.epBank0IsTransferComplete(i) || usbd.epBank1IsTransferComplete(i)) @@ -981,3 +1041,4 @@ void USBDeviceClass::ISRHandler() USBDeviceClass USBDevice; #endif +#endif // USE_TINYUSB diff --git a/cores/arduino/USB/USBCore.h b/cores/arduino/USB/USBCore.h index 75fd9e3d3..89fe8db63 100644 --- a/cores/arduino/USB/USBCore.h +++ b/cores/arduino/USB/USBCore.h @@ -101,7 +101,7 @@ // bMaxPower in Configuration Descriptor #define USB_CONFIG_POWER_MA(mA) ((mA)/2) #ifndef USB_CONFIG_POWER - #define USB_CONFIG_POWER (500) + #define USB_CONFIG_POWER (100) #endif #define CDC_V1_10 0x0110 diff --git a/cores/arduino/USB/samd21_host.c b/cores/arduino/USB/samd21_host.c index 1a8ae3049..7d59f9c45 100644 --- a/cores/arduino/USB/samd21_host.c +++ b/cores/arduino/USB/samd21_host.c @@ -1,5 +1,6 @@ /* Copyright (c) 2014 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,6 +17,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifndef USE_TINYUSB #include #include @@ -66,7 +68,11 @@ void UHD_Init(void) USB_SetHandler(&UHD_Handler); /* Enable USB clock */ +#if defined(__SAMD51__) + MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB; +#else PM->APBBMASK.reg |= PM_APBBMASK_USB; +#endif /* Set up the USB DP/DM pins */ pinPeripheral( PIN_USB_DM, PIO_COM ); @@ -78,9 +84,14 @@ void UHD_Init(void) // PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u))); // PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u)); + /* ---------------------------------------------------------------------------------------------- * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference) */ + +#if defined(__SAMD51__) + GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); +#else GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6) | // Generic Clock Multiplexer 6 GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source GCLK_CLKCTRL_CLKEN; @@ -89,6 +100,7 @@ void UHD_Init(void) { /* Wait for synchronization */ } +#endif /* Reset */ USB->HOST.CTRLA.bit.SWRST = 1; @@ -102,8 +114,14 @@ void UHD_Init(void) uhd_force_host_mode(); while (USB->HOST.SYNCBUSY.reg == USB_SYNCBUSY_ENABLE); + /* Load Pad Calibration */ +#if defined(__SAMD51__) + pad_transn = (*((uint32_t *)(NVMCTRL_SW0) // Non-Volatile Memory Controller +#else pad_transn = (*((uint32_t *)(NVMCTRL_OTP4) // Non-Volatile Memory Controller +#endif + + (NVM_USB_PAD_TRANSN_POS / 32)) >> (NVM_USB_PAD_TRANSN_POS % 32)) & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1); @@ -115,7 +133,11 @@ void UHD_Init(void) USB->HOST.PADCAL.bit.TRANSN = pad_transn; +#if defined(__SAMD51__) + pad_transp = (*((uint32_t *)(NVMCTRL_SW0) +#else pad_transp = (*((uint32_t *)(NVMCTRL_OTP4) +#endif + (NVM_USB_PAD_TRANSP_POS / 32)) >> (NVM_USB_PAD_TRANSP_POS % 32)) & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1); @@ -127,7 +149,11 @@ void UHD_Init(void) USB->HOST.PADCAL.bit.TRANSP = pad_transp; +#if defined(__SAMD51__) + pad_trim = (*((uint32_t *)(NVMCTRL_SW0) +#else pad_trim = (*((uint32_t *)(NVMCTRL_OTP4) +#endif + (NVM_USB_PAD_TRIM_POS / 32)) >> (NVM_USB_PAD_TRIM_POS % 32)) & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1); @@ -163,8 +189,20 @@ void UHD_Init(void) USB->HOST.CTRLB.bit.VBUSOK = 1; // Configure interrupts +#if defined(__SAMD51__) + NVIC_SetPriority((IRQn_Type)USB_0_IRQn, 0UL); + NVIC_SetPriority((IRQn_Type)USB_1_IRQn, 0UL); + NVIC_SetPriority((IRQn_Type)USB_2_IRQn, 0UL); + NVIC_SetPriority((IRQn_Type)USB_3_IRQn, 0UL); + + NVIC_EnableIRQ((IRQn_Type)USB_0_IRQn); + NVIC_EnableIRQ((IRQn_Type)USB_1_IRQn); + NVIC_EnableIRQ((IRQn_Type)USB_2_IRQn); + NVIC_EnableIRQ((IRQn_Type)USB_3_IRQn); +#else NVIC_SetPriority((IRQn_Type)USB_IRQn, 0UL); NVIC_EnableIRQ((IRQn_Type)USB_IRQn); +#endif } @@ -516,3 +554,5 @@ uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type) // } #endif // HOST_DEFINED + +#endif // USE_TINYUSB diff --git a/cores/arduino/WInterrupts.c b/cores/arduino/WInterrupts.c index c78ddf62b..85b744673 100644 --- a/cores/arduino/WInterrupts.c +++ b/cores/arduino/WInterrupts.c @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -33,6 +34,19 @@ static void __initialize() memset(ISRcallback, 0, sizeof(ISRcallback)); nints = 0; +#if defined(__SAMD51__) + ///EIC MCLK is enabled by default + for (uint32_t i = 0; i <= 15; i++) // EIC_0_IRQn = 12 ... EIC_15_IRQn = 27 + { + uint8_t irqn = EIC_0_IRQn + i; + NVIC_DisableIRQ(irqn); + NVIC_ClearPendingIRQ(irqn); + NVIC_SetPriority(irqn, 0); + NVIC_EnableIRQ(irqn); + } + + GCLK->PCHCTRL[EIC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK2_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); +#else NVIC_DisableIRQ(EIC_IRQn); NVIC_ClearPendingIRQ(EIC_IRQn); NVIC_SetPriority(EIC_IRQn, 0); @@ -40,6 +54,7 @@ static void __initialize() // Enable GCLK for IEC (External Interrupt Controller) GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_EIC)); +#endif /* Shall we do that? // Do a software reset on EIC @@ -48,8 +63,13 @@ static void __initialize() */ // Enable EIC +#if defined(__SAMD51__) + EIC->CTRLA.bit.ENABLE = 1; + while (EIC->SYNCBUSY.bit.ENABLE == 1) { } +#else EIC->CTRL.bit.ENABLE = 1; while (EIC->STATUS.bit.SYNCBUSY == 1) { } +#endif } /* @@ -58,88 +78,129 @@ static void __initialize() */ void attachInterrupt(uint32_t pin, voidFuncPtr callback, uint32_t mode) { - static int enabled = 0; - uint32_t config; - uint32_t pos; + static int enabled = 0; + uint32_t config; + uint32_t pos; -#if ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606 - EExt_Interrupts in = g_APinDescription[pin].ulExtInt; -#else - EExt_Interrupts in = digitalPinToInterrupt(pin); -#endif - if (in == NOT_AN_INTERRUPT || in == EXTERNAL_INT_NMI) - return; + #if ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606 + EExt_Interrupts in = g_APinDescription[pin].ulExtInt; + #else + EExt_Interrupts in = digitalPinToInterrupt(pin); + #endif + if (in == NOT_AN_INTERRUPT) return; - if (!enabled) { - __initialize(); - enabled = 1; - } + if (!enabled) { + __initialize(); + enabled = 1; + } + uint32_t inMask = (1UL << in); + // Enable wakeup capability on pin in case being used during sleep + #if defined(__SAMD51__) + //I believe this is done automatically + #else + EIC->WAKEUP.reg |= (1 << in); + #endif - // Enable wakeup capability on pin in case being used during sleep - uint32_t inMask = 1 << in; - EIC->WAKEUP.reg |= inMask; + // Only store when there is really an ISR to call. + // This allow for calling attachInterrupt(pin, NULL, mode), we set up all needed register + // but won't service the interrupt, this way we also don't need to check it inside the ISR. + if (callback) + { + if (in == EXTERNAL_INT_NMI) { + EIC->NMIFLAG.bit.NMI = 1; // Clear flag + switch (mode) { + case LOW: + EIC->NMICTRL.bit.NMISENSE = EIC_NMICTRL_NMISENSE_LOW; + break; - // Assign pin to EIC - pinPeripheral(pin, PIO_EXTINT); + case HIGH: + EIC->NMICTRL.bit.NMISENSE = EIC_NMICTRL_NMISENSE_HIGH; + break; - // Only store when there is really an ISR to call. - // This allow for calling attachInterrupt(pin, NULL, mode), we set up all needed register - // but won't service the interrupt, this way we also don't need to check it inside the ISR. - if (callback) - { - // Store interrupts to service in order of when they were attached - // to allow for first come first serve handler - uint32_t current = 0; - - // Check if we already have this interrupt - for (current=0; current EXTERNAL_INT_7) { - config = 1; - pos = (in - 8) << 2; - } else { - config = 0; - pos = in << 2; - } + case CHANGE: + EIC->NMICTRL.bit.NMISENSE = EIC_NMICTRL_NMISENSE_BOTH; + break; - // Configure the interrupt mode - EIC->CONFIG[config].reg &=~ (EIC_CONFIG_SENSE0_Msk << pos); // Reset sense mode, important when changing trigger mode during runtime - switch (mode) - { - case LOW: - EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_LOW_Val << pos; - break; + case FALLING: + EIC->NMICTRL.bit.NMISENSE = EIC_NMICTRL_NMISENSE_FALL; + break; - case HIGH: - EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_HIGH_Val << pos; - break; + case RISING: + EIC->NMICTRL.bit.NMISENSE = EIC_NMICTRL_NMISENSE_RISE; + break; + } - case CHANGE: - EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_BOTH_Val << pos; - break; + // Assign callback to interrupt + ISRcallback[EXTERNAL_INT_NMI] = callback; - case FALLING: - EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_FALL_Val << pos; - break; + } else { // Not NMI, is external interrupt - case RISING: - EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_RISE_Val << pos; - break; - } - } - // Enable the interrupt - EIC->INTENSET.reg = EIC_INTENSET_EXTINT(inMask); + // Assign pin to EIC + pinPeripheral(pin, PIO_EXTINT); + + // Store interrupts to service in order of when they were attached + // to allow for first come first serve handler + uint32_t current = 0; + + // Check if we already have this interrupt + for (current=0; current EXTERNAL_INT_7) { + config = 1; + pos = (in - 8) << 2; + } else { + config = 0; + pos = in << 2; + } + + #if defined (__SAMD51__) + EIC->CTRLA.bit.ENABLE = 0; + while (EIC->SYNCBUSY.bit.ENABLE == 1) { } + #endif + + EIC->CONFIG[config].reg &=~ (EIC_CONFIG_SENSE0_Msk << pos); // Reset sense mode, important when changing trigger mode during runtime + switch (mode) + { + case LOW: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_LOW_Val << pos; + break; + + case HIGH: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_HIGH_Val << pos; + break; + + case CHANGE: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_BOTH_Val << pos; + break; + + case FALLING: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_FALL_Val << pos; + break; + + case RISING: + EIC->CONFIG[config].reg |= EIC_CONFIG_SENSE0_RISE_Val << pos; + break; + } + } + // Enable the interrupt + EIC->INTENSET.reg = EIC_INTENSET_EXTINT(1 << in); + } + + #if defined (__SAMD51__) + EIC->CTRLA.bit.ENABLE = 1; + while (EIC->SYNCBUSY.bit.ENABLE == 1) { } + #endif } /* @@ -152,19 +213,26 @@ void detachInterrupt(uint32_t pin) #else EExt_Interrupts in = digitalPinToInterrupt(pin); #endif - if (in == NOT_AN_INTERRUPT || in == EXTERNAL_INT_NMI) - return; + if (in == NOT_AN_INTERRUPT) return; - uint32_t inMask = 1 << in; - EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT(inMask); + if(in == EXTERNAL_INT_NMI) { + EIC->NMICTRL.bit.NMISENSE = 0; // Turn off detection + } else { + EIC->INTENCLR.reg = EIC_INTENCLR_EXTINT(1 << in); // Disable wakeup capability on pin during sleep - EIC->WAKEUP.reg &= ~inMask; +#if defined(__SAMD51__) +//I believe this is done automatically +#else + // Disable wakeup capability on pin during sleep + EIC->WAKEUP.reg &= ~(1 << in); +#endif + } // Remove callback from the ISR list uint32_t current; for (current=0; currentINTFLAG.reg & ISRlist[i]) != 0) + { + // Call the callback function + ISRcallback[i](); + // Clear the interrupt + EIC->INTFLAG.reg = ISRlist[i]; + } + } +} + +void EIC_0_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_0); +} + +void EIC_1_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_1); +} + +void EIC_2_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_2); +} + +void EIC_3_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_3); +} + +void EIC_4_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_4); +} + +void EIC_5_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_5); +} + +void EIC_6_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_6); +} + +void EIC_7_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_7); +} + +void EIC_8_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_8); +} + +void EIC_9_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_9); +} + +void EIC_10_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_10); +} + +void EIC_11_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_11); +} + +void EIC_12_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_12); +} + +void EIC_13_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_13); +} + +void EIC_14_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_14); +} + +void EIC_15_Handler(void) +{ + InterruptHandler(EXTERNAL_INT_15); +} +#else + void EIC_Handler(void) { // Calling the routine directly from -here- takes about 1us @@ -198,3 +367,13 @@ void EIC_Handler(void) } } } + +/* + * NMI Interrupt Handler + */ +void NMI_Handler(void) +{ + if (ISRcallback[EXTERNAL_INT_NMI]) ISRcallback[EXTERNAL_INT_NMI](); + EIC->NMIFLAG.bit.NMI = 1; // Clear interrupt +} +#endif diff --git a/cores/arduino/WInterrupts.h b/cores/arduino/WInterrupts.h index 5d2b24a0d..daf02afe5 100644 --- a/cores/arduino/WInterrupts.h +++ b/cores/arduino/WInterrupts.h @@ -31,7 +31,7 @@ extern "C" { #define FALLING 3 #define RISING 4 -#define DEFAULT 1 +//#define DEFAULT 1 #define EXTERNAL 0 typedef void (*voidFuncPtr)(void); diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp index 71bbc07d1..ed4e706df 100644 --- a/cores/arduino/WString.cpp +++ b/cores/arduino/WString.cpp @@ -693,12 +693,21 @@ void String::remove(unsigned int index){ } 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; + // removes characters from the middle of a string. + if (count <= 0) { return; } // exit if nothing to remove + if (index >= len) { return; } // ensure start is within string length; thus, ensures (len-index >= 1) + if (count > len - index) { // ensure characters to remove is no larger than total length remaining + count = len - index; + } + char *writeTo = buffer + index; + char *copyFrom = buffer + index + count; len = len - count; - strncpy(writeTo, buffer + index + count,len - index); + + // strncpy() cannot be used with overlapping buffers, so copy one char at a time + unsigned int charactersToMove = len - index; // yes, uses post-adjusted length + for (unsigned int i = 0; i < charactersToMove; i++, writeTo++, copyFrom++) { + *writeTo = *copyFrom; + } buffer[len] = 0; } diff --git a/cores/arduino/WVariant.h b/cores/arduino/WVariant.h index bbe2e0c4e..8e0d473b8 100644 --- a/cores/arduino/WVariant.h +++ b/cores/arduino/WVariant.h @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,6 +21,7 @@ #include #include "sam.h" +#include #ifdef __cplusplus extern "C" { @@ -37,13 +39,13 @@ typedef enum _EAnalogChannel ADC_Channel5=5, ADC_Channel6=6, ADC_Channel7=7, -#if defined __SAMD21J18A__ +#if defined __SAMD21J18A__ || defined(__SAMD51__) ADC_Channel8=8, ADC_Channel9=9, #endif // __SAMD21J18A__ ADC_Channel10=10, ADC_Channel11=11, -#if defined __SAMD21J18A__ +#if defined __SAMD21J18A__ || defined(__SAMD51__) ADC_Channel12=12, ADC_Channel13=13, ADC_Channel14=14, @@ -54,8 +56,134 @@ typedef enum _EAnalogChannel ADC_Channel18=18, ADC_Channel19=19, DAC_Channel0, + DAC_Channel1, + ADC_Channel_Bandgap=0x1B, + ADC_Channel_PTAT=0x1C, } EAnalogChannel ; +#if defined(__SAMD51__) + +#if defined(__SAMD51G19A__) + +typedef enum _ETCChannel +{ + NOT_ON_TIMER=-1, + TCC0_CH0 = (0<<8)|(0), + TCC0_CH1 = (0<<8)|(1), + TCC0_CH2 = (0<<8)|(2), + TCC0_CH3 = (0<<8)|(3), + TCC0_CH4 = (0<<8)|(4), + TCC0_CH5 = (0<<8)|(5), + TCC1_CH0 = (1<<8)|(0), + TCC1_CH1 = (1<<8)|(1), + TCC1_CH2 = (1<<8)|(2), + TCC1_CH3 = (1<<8)|(3), + TCC2_CH0 = (2<<8)|(0), + TCC2_CH1 = (2<<8)|(1), + TCC2_CH2 = (2<<8)|(2), + TC0_CH0 = (3<<8)|(0), + TC0_CH1 = (3<<8)|(1), + TC1_CH0 = (4<<8)|(0), + TC1_CH1 = (4<<8)|(1), + TC2_CH0 = (5<<8)|(0), + TC2_CH1 = (5<<8)|(1), + TC3_CH0 = (6<<8)|(0), + TC3_CH1 = (6<<8)|(1), +} ETCChannel ; +#elif defined(__SAMD51J19A__) || defined(__SAMD51J20A__) || defined(__SAME51J19A__) + +typedef enum _ETCChannel +{ + NOT_ON_TIMER=-1, + TCC0_CH0 = (0<<8)|(0), + TCC0_CH1 = (0<<8)|(1), + TCC0_CH2 = (0<<8)|(2), + TCC0_CH3 = (0<<8)|(3), + TCC0_CH4 = (0<<8)|(4), + TCC0_CH5 = (0<<8)|(5), + TCC0_CH6 = (0<<8)|(6), + TCC0_CH7 = (0<<8)|(7), + TCC1_CH0 = (1<<8)|(0), + TCC1_CH1 = (1<<8)|(1), + TCC1_CH2 = (1<<8)|(2), + TCC1_CH3 = (1<<8)|(3), + TCC1_CH4 = (1<<8)|(4), + TCC1_CH5 = (1<<8)|(5), + TCC1_CH6 = (1<<8)|(6), + TCC1_CH7 = (1<<8)|(7), + TCC2_CH0 = (2<<8)|(0), + TCC2_CH1 = (2<<8)|(1), + TCC2_CH2 = (2<<8)|(2), + TCC3_CH0 = (3<<8)|(0), + TCC3_CH1 = (3<<8)|(1), + TCC4_CH0 = (4<<8)|(0), + TCC4_CH1 = (4<<8)|(1), + TC0_CH0 = (5<<8)|(0), + TC0_CH1 = (5<<8)|(1), + TC1_CH0 = (6<<8)|(0), + TC1_CH1 = (6<<8)|(1), + TC2_CH0 = (7<<8)|(0), + TC2_CH1 = (7<<8)|(1), + TC3_CH0 = (8<<8)|(0), + TC3_CH1 = (8<<8)|(1), + TC4_CH0 = (9<<8)|(0), + TC4_CH1 = (9<<8)|(1), + TC5_CH0 = (10<<8)|(0), + TC5_CH1 = (10<<8)|(1), + TC6_CH0 = (11<<8)|(0), + TC6_CH1 = (11<<8)|(1), + TC7_CH0 = (12<<8)|(0), + TC7_CH1 = (12<<8)|(1), +} ETCChannel ; + +#elif defined(__SAME53N20A__) || defined(__SAME53N19A__) || defined(__SAME54P20A__) || defined(__SAME54P19A__) || defined(__SAME54N20A__) || defined(__SAME54N19A__) || defined(__SAMD51P20A__) || defined(__SAMD51P19A__) || defined(__SAMD51N20A__) || defined(__SAMD51N19A__) || defined(__SAME51N20A__) || defined(__SAME51N19A__) + +typedef enum _ETCChannel +{ + NOT_ON_TIMER=-1, + TCC0_CH0 = (0<<8)|(0), + TCC0_CH1 = (0<<8)|(1), + TCC0_CH2 = (0<<8)|(2), + TCC0_CH3 = (0<<8)|(3), + TCC0_CH4 = (0<<8)|(4), + TCC0_CH5 = (0<<8)|(5), + TCC1_CH0 = (1<<8)|(0), + TCC1_CH1 = (1<<8)|(1), + TCC1_CH2 = (1<<8)|(2), + TCC1_CH3 = (1<<8)|(3), + TCC2_CH0 = (2<<8)|(0), + TCC2_CH1 = (2<<8)|(1), + TCC2_CH2 = (2<<8)|(2), + TCC3_CH0 = (3<<8)|(0), + TCC3_CH1 = (3<<8)|(1), + TCC4_CH0 = (4<<8)|(0), + TCC4_CH1 = (4<<8)|(1), + TC0_CH0 = (5<<8)|(0), + TC0_CH1 = (5<<8)|(1), + TC1_CH0 = (6<<8)|(0), + TC1_CH1 = (6<<8)|(1), + TC2_CH0 = (7<<8)|(0), + TC2_CH1 = (7<<8)|(1), + TC3_CH0 = (8<<8)|(0), + TC3_CH1 = (8<<8)|(1), + TC4_CH0 = (9<<8)|(0), + TC4_CH1 = (9<<8)|(1), + TC5_CH0 = (10<<8)|(0), + TC5_CH1 = (10<<8)|(1), + TC6_CH0 = (11<<8)|(0), + TC6_CH1 = (11<<8)|(1), + TC7_CH0 = (12<<8)|(0), + TC7_CH1 = (12<<8)|(1), +} ETCChannel ; + +#endif + +typedef ETCChannel EPWMChannel; +extern const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM]; + +#define NOT_ON_PWM NOT_ON_TIMER + +#else // Definitions for TC channels typedef enum _ETCChannel { @@ -82,20 +210,14 @@ typedef enum _ETCChannel TC4_CH1 = (4<<8)|(1), TC5_CH0 = (5<<8)|(0), TC5_CH1 = (5<<8)|(1), -#if defined __SAMD21J18A__ - TC6_CH0 = (6<<8)|(0), - TC6_CH1 = (6<<8)|(1), - TC7_CH0 = (7<<8)|(0), - TC7_CH1 = (7<<8)|(1), -#endif // __SAMD21J18A__ + #if defined (__SAMD21J18A__) + TC6_CH0 = (6<<8)|(0), + TC6_CH1 = (6<<8)|(1), + TC7_CH0 = (7<<8)|(0), + TC7_CH1 = (7<<8)|(1), + #endif // __SAMD21J18A__ } ETCChannel ; -extern const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM] ; - -#define GetTCNumber( x ) ( (x) >> 8 ) -#define GetTCChannelNumber( x ) ( (x) & 0xff ) -#define GetTC( x ) ( g_apTCInstances[(x) >> 8] ) - // Definitions for PWM channels typedef enum _EPWMChannel { @@ -122,7 +244,7 @@ typedef enum _EPWMChannel PWM4_CH1=TC4_CH1, PWM5_CH0=TC5_CH0, PWM5_CH1=TC5_CH1, -#if defined __SAMD21J18A__ +#if defined(__SAMD21J18A__) PWM6_CH0=TC6_CH0, PWM6_CH1=TC6_CH1, PWM7_CH0=TC7_CH0, @@ -130,14 +252,25 @@ typedef enum _EPWMChannel #endif // __SAMD21J18A__ } EPWMChannel ; +#endif + +extern const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM] ; + +#define GetTCNumber( x ) ( (x) >> 8 ) +#define GetTCChannelNumber( x ) ( (x) & 0xff ) +#define GetTC( x ) ( g_apTCInstances[(x) >> 8] ) + typedef enum _EPortType { NOT_A_PORT=-1, PORTA=0, PORTB=1, PORTC=2, + PORTD=3, } EPortType ; +#define PIN_NOT_A_PIN (UINT_MAX) + typedef enum { EXTERNAL_INT_0 = 0, @@ -174,8 +307,19 @@ typedef enum _EPioType PIO_SERCOM_ALT, /* The pin is controlled by the associated signal of peripheral D. */ PIO_TIMER, /* The pin is controlled by the associated signal of peripheral E. */ PIO_TIMER_ALT, /* The pin is controlled by the associated signal of peripheral F. */ +#if defined(__SAMD51__) + PIO_TCC_PDEC, /* The pin is controlled by the associated signal of peripheral G. */ + PIO_COM, /* The pin is controlled by the associated signal of peripheral H. */ + PIO_SDHC, /* The pin is controlled by the associated signal of peripheral I. */ + PIO_I2S, /* The pin is controlled by the associated signal of peripheral J. */ + PIO_PCC, /* The pin is controlled by the associated signal of peripheral K. */ + PIO_GMAC, /* The pin is controlled by the associated signal of peripheral L. */ + PIO_AC_CLK, /* The pin is controlled by the associated signal of peripheral M. */ + PIO_CCL, /* The pin is controlled by the associated signal of peripheral N. */ +#else PIO_COM, /* The pin is controlled by the associated signal of peripheral G. */ PIO_AC_CLK, /* The pin is controlled by the associated signal of peripheral H. */ +#endif PIO_DIGITAL, /* The pin is controlled by PORT. */ PIO_INPUT, /* The pin is controlled by PORT and is an input. */ PIO_INPUT_PULLUP, /* The pin is controlled by PORT and is an input with internal pull-up resistor enabled. */ @@ -192,10 +336,19 @@ typedef enum _EPioType #define PIN_ATTR_COMBO (1UL<<0) #define PIN_ATTR_ANALOG (1UL<<1) #define PIN_ATTR_DIGITAL (1UL<<2) -#define PIN_ATTR_PWM (1UL<<3) #define PIN_ATTR_TIMER (1UL<<4) #define PIN_ATTR_TIMER_ALT (1UL<<5) #define PIN_ATTR_EXTINT (1UL<<6) +#define PIN_ATTR_ANALOG_ALT (1UL<<7) + +#if defined(__SAMD51__) +// these correspond to the mux table +#define PIN_ATTR_PWM_E (1UL<<3) +#define PIN_ATTR_PWM_F (1UL<<8) +#define PIN_ATTR_PWM_G (1UL<<9) +#else +#define PIN_ATTR_PWM (1UL<<3) +#endif /* Types used for the table below */ typedef struct _PinDescription diff --git a/cores/arduino/avr/io.h b/cores/arduino/avr/io.h index 33d20cdd2..5c395fd26 100644 --- a/cores/arduino/avr/io.h +++ b/cores/arduino/avr/io.h @@ -25,8 +25,14 @@ #ifndef _IO_H_ #define _IO_H_ -#define RAMSTART (HMCRAMC0_ADDR) -#define RAMSIZE (HMCRAMC0_SIZE) +#ifdef __SAMD51__ + #define RAMSTART (HSRAM_ADDR) + #define RAMSIZE (HSRAM_SIZE) +#else + #define RAMSTART (HMCRAMC0_ADDR) + #define RAMSIZE (HMCRAMC0_SIZE) +#endif + #define RAMEND (RAMSTART + RAMSIZE - 1) #endif diff --git a/cores/arduino/cortex_handlers.c b/cores/arduino/cortex_handlers.c index a910d0889..953d1a6e1 100644 --- a/cores/arduino/cortex_handlers.c +++ b/cores/arduino/cortex_handlers.c @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -34,6 +35,332 @@ void Dummy_Handler(void) for (;;) { } } +#if defined(__SAMD51__) + +/* Cortex-M4 processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void MemManage_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void BusFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void UsageFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SVC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DebugMon_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PendSV_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void MCLK_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void OSCCTRL_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void OSCCTRL_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void OSCCTRL_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void OSCCTRL_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void OSCCTRL_4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void OSC32KCTRL_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SUPC_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SUPC_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void WDT_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void RTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_6_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_7_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_8_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_9_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_10_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_11_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_12_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_13_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_14_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_15_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void FREQM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void NVMCTRL_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void NVMCTRL_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EVSYS_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EVSYS_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EVSYS_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EVSYS_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EVSYS_4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TAL_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TAL_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void RAMECC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM0_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM0_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM0_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM0_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM1_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM1_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM1_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM1_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM2_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM2_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM2_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM2_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM3_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM3_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM3_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM3_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM4_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM4_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM4_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM4_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM5_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM5_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM5_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM5_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM6_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM6_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM6_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM6_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM7_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM7_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM7_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM7_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void CAN0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void CAN1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void USB_0_Handler ( void ) __attribute__ ((weak)); +void USB_1_Handler ( void ) __attribute__ ((weak)); +void USB_2_Handler ( void ) __attribute__ ((weak)); +void USB_3_Handler ( void ) __attribute__ ((weak)); +void GMAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC0_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC0_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC0_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC0_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC0_4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC0_5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC0_6_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC1_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC1_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC1_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC1_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC1_4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC2_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC2_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC2_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC2_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC3_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC3_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC3_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC4_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC4_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC4_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC2_Handler ( void ) __attribute__ ((weak)); //used in Tone.cpp +void TC3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC6_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC7_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PDEC_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PDEC_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PDEC_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ADC0_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ADC0_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ADC1_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ADC1_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void AC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DAC_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DAC_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DAC_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DAC_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DAC_4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void I2S_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PCC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void AES_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TRNG_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ICM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PUKCC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void QSPI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SDHC0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SDHC1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); + +/* Initialize segments */ +extern uint32_t __etext; +extern uint32_t __data_start__; +extern uint32_t __data_end__; +extern uint32_t __bss_start__; +extern uint32_t __bss_end__; +extern uint32_t __StackTop; + +/* Exception Table */ +__attribute__ ((used)) +__attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table = +{ + /* Configure Initial Stack Pointer, using linker-generated symbols */ + (void*) (&__StackTop), + + /* Cortex-M handlers */ + (void*) Reset_Handler, + (void*) NMI_Handler, + (void*) HardFault_Handler, + (void*) MemManage_Handler, + (void*) BusFault_Handler, + (void*) UsageFault_Handler, + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) SVC_Handler, + (void*) DebugMon_Handler, + (void*) (0UL), /* Reserved */ + (void*) PendSV_Handler, + (void*) SysTick_Handler, + + /* Peripheral handlers */ + (void*) PM_Handler, /* 0 Power Manager */ + (void*) MCLK_Handler, /* 1 Main Clock */ + (void*) OSCCTRL_0_Handler, /* 2 Oscillators Control IRQ 0 */ + (void*) OSCCTRL_1_Handler, /* 3 Oscillators Control IRQ 1 */ + (void*) OSCCTRL_2_Handler, /* 4 Oscillators Control IRQ 2 */ + (void*) OSCCTRL_3_Handler, /* 5 Oscillators Control IRQ 3 */ + (void*) OSCCTRL_4_Handler, /* 6 Oscillators Control IRQ 4 */ + (void*) OSC32KCTRL_Handler, /* 7 32kHz Oscillators Control */ + (void*) SUPC_0_Handler, /* 8 Supply Controller IRQ 0 */ + (void*) SUPC_1_Handler, /* 9 Supply Controller IRQ 1 */ + (void*) WDT_Handler, /* 10 Watchdog Timer */ + (void*) RTC_Handler, /* 11 Real-Time Counter */ + (void*) EIC_0_Handler, /* 12 External Interrupt Controller IRQ 0 */ + (void*) EIC_1_Handler, /* 13 External Interrupt Controller IRQ 1 */ + (void*) EIC_2_Handler, /* 14 External Interrupt Controller IRQ 2 */ + (void*) EIC_3_Handler, /* 15 External Interrupt Controller IRQ 3 */ + (void*) EIC_4_Handler, /* 16 External Interrupt Controller IRQ 4 */ + (void*) EIC_5_Handler, /* 17 External Interrupt Controller IRQ 5 */ + (void*) EIC_6_Handler, /* 18 External Interrupt Controller IRQ 6 */ + (void*) EIC_7_Handler, /* 19 External Interrupt Controller IRQ 7 */ + (void*) EIC_8_Handler, /* 20 External Interrupt Controller IRQ 8 */ + (void*) EIC_9_Handler, /* 21 External Interrupt Controller IRQ 9 */ + (void*) EIC_10_Handler, /* 22 External Interrupt Controller IRQ 10 */ + (void*) EIC_11_Handler, /* 23 External Interrupt Controller IRQ 11 */ + (void*) EIC_12_Handler, /* 24 External Interrupt Controller IRQ 12 */ + (void*) EIC_13_Handler, /* 25 External Interrupt Controller IRQ 13 */ + (void*) EIC_14_Handler, /* 26 External Interrupt Controller IRQ 14 */ + (void*) EIC_15_Handler, /* 27 External Interrupt Controller IRQ 15 */ + (void*) FREQM_Handler, /* 28 Frequency Meter */ + (void*) NVMCTRL_0_Handler, /* 29 Non-Volatile Memory Controller IRQ 0 */ + (void*) NVMCTRL_1_Handler, /* 30 Non-Volatile Memory Controller IRQ 1 */ + (void*) DMAC_0_Handler, /* 31 Direct Memory Access Controller IRQ 0 */ + (void*) DMAC_1_Handler, /* 32 Direct Memory Access Controller IRQ 1 */ + (void*) DMAC_2_Handler, /* 33 Direct Memory Access Controller IRQ 2 */ + (void*) DMAC_3_Handler, /* 34 Direct Memory Access Controller IRQ 3 */ + (void*) DMAC_4_Handler, /* 35 Direct Memory Access Controller IRQ 4 */ + (void*) EVSYS_0_Handler, /* 36 Event System Interface IRQ 0 */ + (void*) EVSYS_1_Handler, /* 37 Event System Interface IRQ 1 */ + (void*) EVSYS_2_Handler, /* 38 Event System Interface IRQ 2 */ + (void*) EVSYS_3_Handler, /* 39 Event System Interface IRQ 3 */ + (void*) EVSYS_4_Handler, /* 40 Event System Interface IRQ 4 */ + (void*) PAC_Handler, /* 41 Peripheral Access Controller */ + (void*) TAL_0_Handler, /* 42 Trigger Allocator IRQ 0 */ + (void*) TAL_1_Handler, /* 43 Trigger Allocator IRQ 1 */ + (void*) (0UL), + (void*) RAMECC_Handler, /* 45 RAM ECC */ + (void*) SERCOM0_0_Handler, /* 46 Serial Communication Interface 0 IRQ 0 */ + (void*) SERCOM0_1_Handler, /* 47 Serial Communication Interface 0 IRQ 1 */ + (void*) SERCOM0_2_Handler, /* 48 Serial Communication Interface 0 IRQ 2 */ + (void*) SERCOM0_3_Handler, /* 49 Serial Communication Interface 0 IRQ 3 */ + (void*) SERCOM1_0_Handler, /* 50 Serial Communication Interface 1 IRQ 0 */ + (void*) SERCOM1_1_Handler, /* 51 Serial Communication Interface 1 IRQ 1 */ + (void*) SERCOM1_2_Handler, /* 52 Serial Communication Interface 1 IRQ 2 */ + (void*) SERCOM1_3_Handler, /* 53 Serial Communication Interface 1 IRQ 3 */ + (void*) SERCOM2_0_Handler, /* 54 Serial Communication Interface 2 IRQ 0 */ + (void*) SERCOM2_1_Handler, /* 55 Serial Communication Interface 2 IRQ 1 */ + (void*) SERCOM2_2_Handler, /* 56 Serial Communication Interface 2 IRQ 2 */ + (void*) SERCOM2_3_Handler, /* 57 Serial Communication Interface 2 IRQ 3 */ + (void*) SERCOM3_0_Handler, /* 58 Serial Communication Interface 3 IRQ 0 */ + (void*) SERCOM3_1_Handler, /* 59 Serial Communication Interface 3 IRQ 1 */ + (void*) SERCOM3_2_Handler, /* 60 Serial Communication Interface 3 IRQ 2 */ + (void*) SERCOM3_3_Handler, /* 61 Serial Communication Interface 3 IRQ 3 */ + (void*) SERCOM4_0_Handler, /* 62 Serial Communication Interface 4 IRQ 0 */ + (void*) SERCOM4_1_Handler, /* 63 Serial Communication Interface 4 IRQ 1 */ + (void*) SERCOM4_2_Handler, /* 64 Serial Communication Interface 4 IRQ 2 */ + (void*) SERCOM4_3_Handler, /* 65 Serial Communication Interface 4 IRQ 3 */ + (void*) SERCOM5_0_Handler, /* 66 Serial Communication Interface 5 IRQ 0 */ + (void*) SERCOM5_1_Handler, /* 67 Serial Communication Interface 5 IRQ 1 */ + (void*) SERCOM5_2_Handler, /* 68 Serial Communication Interface 5 IRQ 2 */ + (void*) SERCOM5_3_Handler, /* 69 Serial Communication Interface 5 IRQ 3 */ + (void*) SERCOM6_0_Handler, /* 70 Serial Communication Interface 6 IRQ 0 */ + (void*) SERCOM6_1_Handler, /* 71 Serial Communication Interface 6 IRQ 1 */ + (void*) SERCOM6_2_Handler, /* 72 Serial Communication Interface 6 IRQ 2 */ + (void*) SERCOM6_3_Handler, /* 73 Serial Communication Interface 6 IRQ 3 */ + (void*) SERCOM7_0_Handler, /* 74 Serial Communication Interface 7 IRQ 0 */ + (void*) SERCOM7_1_Handler, /* 75 Serial Communication Interface 7 IRQ 1 */ + (void*) SERCOM7_2_Handler, /* 76 Serial Communication Interface 7 IRQ 2 */ + (void*) SERCOM7_3_Handler, /* 77 Serial Communication Interface 7 IRQ 3 */ + (void*) CAN0_Handler, /* 78 Control Area Network 0 (SAM E5x) */ + (void*) CAN1_Handler, /* 79 Control Area Network 0 (SAM E5x) */ + (void*) USB_0_Handler, /* 80 Universal Serial Bus IRQ 0 */ + (void*) USB_1_Handler, /* 81 Universal Serial Bus IRQ 1 */ + (void*) USB_2_Handler, /* 82 Universal Serial Bus IRQ 2 */ + (void*) USB_3_Handler, /* 83 Universal Serial Bus IRQ 3 */ + (void*) GMAC_Handler, /* 84 Ethernet MAC */ + (void*) TCC0_0_Handler, /* 85 Timer Counter Control 0 IRQ 0 */ + (void*) TCC0_1_Handler, /* 86 Timer Counter Control 0 IRQ 1 */ + (void*) TCC0_2_Handler, /* 87 Timer Counter Control 0 IRQ 2 */ + (void*) TCC0_3_Handler, /* 88 Timer Counter Control 0 IRQ 3 */ + (void*) TCC0_4_Handler, /* 89 Timer Counter Control 0 IRQ 4 */ + (void*) TCC0_5_Handler, /* 90 Timer Counter Control 0 IRQ 5 */ + (void*) TCC0_6_Handler, /* 91 Timer Counter Control 0 IRQ 6 */ + (void*) TCC1_0_Handler, /* 92 Timer Counter Control 1 IRQ 0 */ + (void*) TCC1_1_Handler, /* 93 Timer Counter Control 1 IRQ 1 */ + (void*) TCC1_2_Handler, /* 94 Timer Counter Control 1 IRQ 2 */ + (void*) TCC1_3_Handler, /* 95 Timer Counter Control 1 IRQ 3 */ + (void*) TCC1_4_Handler, /* 96 Timer Counter Control 1 IRQ 4 */ + (void*) TCC2_0_Handler, /* 97 Timer Counter Control 2 IRQ 0 */ + (void*) TCC2_1_Handler, /* 98 Timer Counter Control 2 IRQ 1 */ + (void*) TCC2_2_Handler, /* 99 Timer Counter Control 2 IRQ 2 */ + (void*) TCC2_3_Handler, /* 100 Timer Counter Control 2 IRQ 3 */ + (void*) TCC3_0_Handler, /* 101 Timer Counter Control 3 IRQ 0 */ + (void*) TCC3_1_Handler, /* 102 Timer Counter Control 3 IRQ 1 */ + (void*) TCC3_2_Handler, /* 103 Timer Counter Control 3 IRQ 2 */ + (void*) TCC4_0_Handler, /* 104 Timer Counter Control 4 IRQ 0 */ + (void*) TCC4_1_Handler, /* 105 Timer Counter Control 4 IRQ 1 */ + (void*) TCC4_2_Handler, /* 106 Timer Counter Control 4 IRQ 2 */ + (void*) TC0_Handler, /* 107 Basic Timer Counter 0 */ + (void*) TC1_Handler, /* 108 Basic Timer Counter 1 */ + (void*) TC2_Handler, /* 109 Basic Timer Counter 2 */ + (void*) TC3_Handler, /* 110 Basic Timer Counter 3 */ + (void*) TC4_Handler, /* 111 Basic Timer Counter 4 */ + (void*) TC5_Handler, /* 112 Basic Timer Counter 5 */ + (void*) TC6_Handler, /* 113 Basic Timer Counter 6 */ + (void*) TC7_Handler, /* 114 Basic Timer Counter 7 */ + (void*) PDEC_0_Handler, /* 115 Quadrature Decodeur IRQ 0 */ + (void*) PDEC_1_Handler, /* 116 Quadrature Decodeur IRQ 1 */ + (void*) PDEC_2_Handler, /* 117 Quadrature Decodeur IRQ 2 */ + (void*) ADC0_0_Handler, /* 118 Analog Digital Converter 0 IRQ 0 */ + (void*) ADC0_1_Handler, /* 119 Analog Digital Converter 0 IRQ 1 */ + (void*) ADC1_0_Handler, /* 120 Analog Digital Converter 1 IRQ 0 */ + (void*) ADC1_1_Handler, /* 121 Analog Digital Converter 1 IRQ 1 */ + (void*) AC_Handler, /* 122 Analog Comparators */ + (void*) DAC_0_Handler, /* 123 Digital-to-Analog Converter IRQ 0 */ + (void*) DAC_1_Handler, /* 124 Digital-to-Analog Converter IRQ 1 */ + (void*) DAC_2_Handler, /* 125 Digital-to-Analog Converter IRQ 2 */ + (void*) DAC_3_Handler, /* 126 Digital-to-Analog Converter IRQ 3 */ + (void*) DAC_4_Handler, /* 127 Digital-to-Analog Converter IRQ 4 */ + (void*) I2S_Handler, /* 128 Inter-IC Sound Interface */ + (void*) PCC_Handler, /* 129 Parallel Capture Controller */ + (void*) AES_Handler, /* 130 Advanced Encryption Standard */ + (void*) TRNG_Handler, /* 131 True Random Generator */ + (void*) ICM_Handler, /* 132 Integrity Check Monitor */ + (void*) PUKCC_Handler, /* 133 PUblic-Key Cryptography Controller */ + (void*) QSPI_Handler, /* 134 Quad SPI interface */ + (void*) SDHC0_Handler, /* 135 SD/MMC Host Controller 0 */ + (void*) SDHC1_Handler, /* 136 SD/MMC Host Controller 1 */ +}; + +#else + /* Cortex-M0+ core handlers */ void HardFault_Handler(void) __attribute__ ((weak, alias("Dummy_Handler"))); void Reset_Handler (void); @@ -81,6 +408,7 @@ extern uint32_t __bss_end__; extern uint32_t __StackTop; /* Exception Table */ +__attribute__ ((used)) __attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table = { /* Configure Initial Stack Pointer, using linker-generated symbols */ @@ -134,6 +462,8 @@ __attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table = (void*) (0UL), /* Reserved */ }; +#endif + extern int main(void); /* This is called on processor reset to initialize the device and call main() */ @@ -156,6 +486,13 @@ void Reset_Handler(void) *pDest = 0; } +#if defined(__FPU_USED) && defined(__SAMD51__) + /* Enable FPU */ + SCB->CPACR |= (0xFu << 20); + __DSB(); + __ISB(); +#endif + SystemInit(); main(); @@ -176,11 +513,34 @@ void SysTick_Handler(void) static void (*usb_isr)(void) = NULL; +#if defined(__SAMD51__) +void USB_0_Handler(void) +{ + if (usb_isr) + usb_isr(); +} +void USB_1_Handler(void) +{ + if (usb_isr) + usb_isr(); +} +void USB_2_Handler(void) +{ + if (usb_isr) + usb_isr(); +} +void USB_3_Handler(void) +{ + if (usb_isr) + usb_isr(); +} +#else void USB_Handler(void) { if (usb_isr) usb_isr(); } +#endif void USB_SetHandler(void (*new_usb_isr)(void)) { diff --git a/cores/arduino/delay.c b/cores/arduino/delay.c index 84c8ea7e4..773ce39e9 100644 --- a/cores/arduino/delay.c +++ b/cores/arduino/delay.c @@ -61,6 +61,33 @@ unsigned long micros( void ) // a runtime multiplication and shift, saving a few cycles } +#ifdef __SAMD51__ +/* + * On SAMD51, use the (32bit) cycle count maintained by the DWT unit, + * and count exact number of cycles elapsed, rather than guessing how + * many cycles a loop takes, which is dangerous in the presence of + * cache. The overhead of the call and internal code is "about" 20 + * cycles. (at 120MHz, that's about 1/6 us) + */ +void delayMicroseconds(unsigned int us) +{ + uint32_t start, elapsed; + uint32_t count; + + if (us == 0) + return; + + count = us * (VARIANT_MCK / 1000000) - 20; // convert us to cycles. + start = DWT->CYCCNT; //CYCCNT is 32bits, takes 37s or so to wrap. + while (1) { + elapsed = DWT->CYCCNT - start; + if (elapsed >= count) + return; + } +} +#endif + + void delay( unsigned long ms ) { if (ms == 0) @@ -90,6 +117,17 @@ void SysTick_DefaultHandler(void) tickReset(); } +#if defined(USE_TINYUSB) + +// run TinyUSB background task when yield() +void yield(void) +{ + TinyUSB_Device_Task(); + TinyUSB_Device_FlushCDC(); +} + +#endif + #ifdef __cplusplus } #endif diff --git a/cores/arduino/delay.h b/cores/arduino/delay.h index 64f39b13f..3d3a6d195 100644 --- a/cores/arduino/delay.h +++ b/cores/arduino/delay.h @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -60,6 +61,9 @@ extern void delay( unsigned long dwMs ) ; * * \param dwUs the number of microseconds to pause (uint32_t) */ +#if defined(__SAMD51__) +extern void delayMicroseconds( unsigned int ); +#else static __inline__ void delayMicroseconds( unsigned int ) __attribute__((always_inline, unused)) ; static __inline__ void delayMicroseconds( unsigned int usec ) { @@ -67,7 +71,6 @@ static __inline__ void delayMicroseconds( unsigned int usec ) { return ; } - /* * The following loop: * @@ -85,6 +88,7 @@ static __inline__ void delayMicroseconds( unsigned int usec ) // VARIANT_MCK / 1000000 == cycles needed to delay 1uS // 3 == cycles used in a loop uint32_t n = usec * (VARIANT_MCK / 1000000) / 3; + __asm__ __volatile__( "1: \n" " sub %0, #1 \n" // substract 1 from %0 (n) @@ -96,6 +100,7 @@ static __inline__ void delayMicroseconds( unsigned int usec ) // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile } +#endif #ifdef __cplusplus } diff --git a/cores/arduino/hooks.c b/cores/arduino/hooks.c index f87c20444..d3272504f 100644 --- a/cores/arduino/hooks.c +++ b/cores/arduino/hooks.c @@ -28,6 +28,7 @@ static void __empty() { // Empty } + void yield(void) __attribute__ ((weak, alias("__empty"))); /** diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 49ebc27f5..3ea8ad3b3 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -39,7 +39,10 @@ int main( void ) initVariant(); delay(1); -#if defined(USBCON) + +#if defined(USE_TINYUSB) + TinyUSB_Device_Init(0); +#elif defined(USBCON) USBDevice.init(); USBDevice.attach(); #endif @@ -49,6 +52,8 @@ int main( void ) for (;;) { loop(); + yield(); // yield run usb background task + if (serialEventRun) serialEventRun(); } diff --git a/cores/arduino/math_helper.c b/cores/arduino/math_helper.c new file mode 100644 index 000000000..60887c708 --- /dev/null +++ b/cores/arduino/math_helper.c @@ -0,0 +1,459 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2012 ARM Limited. All rights reserved. +* +* $Date: 17. January 2013 +* $Revision: V1.4.0 +* +* Project: CMSIS DSP Library +* +* Title: math_helper.c +* +* Description: Definition of all helper functions required. +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- +* Include standard header files +* -------------------------------------------------------------------- */ +#include + +/* ---------------------------------------------------------------------- +* Include project header files +* -------------------------------------------------------------------- */ +#include "math_helper.h" + +/** + * @brief Caluclation of SNR + * @param float* Pointer to the reference buffer + * @param float* Pointer to the test buffer + * @param uint32_t total number of samples + * @return float SNR + * The function Caluclates signal to noise ratio for the reference output + * and test output + */ + +float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize) +{ + float EnergySignal = 0.0, EnergyError = 0.0; + uint32_t i; + float SNR; + int temp; + int *test; + + for (i = 0; i < buffSize; i++) + { + /* Checking for a NAN value in pRef array */ + test = (int *)(&pRef[i]); + temp = *test; + + if(temp == 0x7FC00000) + { + return(0); + } + + /* Checking for a NAN value in pTest array */ + test = (int *)(&pTest[i]); + temp = *test; + + if(temp == 0x7FC00000) + { + return(0); + } + EnergySignal += pRef[i] * pRef[i]; + EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]); + } + + /* Checking for a NAN value in EnergyError */ + test = (int *)(&EnergyError); + temp = *test; + + if(temp == 0x7FC00000) + { + return(0); + } + + + SNR = 10 * log10 (EnergySignal / EnergyError); + + return (SNR); + +} + + +/** + * @brief Provide guard bits for Input buffer + * @param q15_t* Pointer to input buffer + * @param uint32_t blockSize + * @param uint32_t guard_bits + * @return none + * The function Provides the guard bits for the buffer + * to avoid overflow + */ + +void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize, + uint32_t guard_bits) +{ + uint32_t i; + + for (i = 0; i < blockSize; i++) + { + input_buf[i] = input_buf[i] >> guard_bits; + } +} + +/** + * @brief Converts float to fixed in q12.20 format + * @param uint32_t number of samples in the buffer + * @return none + * The function converts floating point values to fixed point(q12.20) values + */ + +void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples) +{ + uint32_t i; + + for (i = 0; i < numSamples; i++) + { + /* 1048576.0f corresponds to pow(2, 20) */ + pOut[i] = (q31_t) (pIn[i] * 1048576.0f); + + pOut[i] += pIn[i] > 0 ? 0.5 : -0.5; + + if (pIn[i] == (float) 1.0) + { + pOut[i] = 0x000FFFFF; + } + } +} + +/** + * @brief Compare MATLAB Reference Output and ARM Test output + * @param q15_t* Pointer to Ref buffer + * @param q15_t* Pointer to Test buffer + * @param uint32_t number of samples in the buffer + * @return none + */ + +uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples) +{ + uint32_t i; + int32_t diff; + uint32_t diffCrnt = 0; + uint32_t maxDiff = 0; + + for (i = 0; i < numSamples; i++) + { + diff = pIn[i] - pOut[i]; + diffCrnt = (uint32_t)( (diff > 0) ? diff : -diff ); + + if(diffCrnt > maxDiff) + { + maxDiff = diffCrnt; + } + } + + return(maxDiff); +} + +/** + * @brief Compare MATLAB Reference Output and ARM Test output + * @param q31_t* Pointer to Ref buffer + * @param q31_t* Pointer to Test buffer + * @param uint32_t number of samples in the buffer + * @return none + */ + +uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples) +{ + uint32_t i; + int32_t diff; + uint32_t diffCrnt = 0; + uint32_t maxDiff = 0; + + for (i = 0; i < numSamples; i++) + { + diff = pIn[i] - pOut[i]; + diffCrnt = (uint32_t)( (diff > 0) ? diff : -diff ); + + if(diffCrnt > maxDiff) + { + maxDiff = diffCrnt; + } + } + + return(maxDiff); +} + +/** + * @brief Provide guard bits for Input buffer + * @param q31_t* Pointer to input buffer + * @param uint32_t blockSize + * @param uint32_t guard_bits + * @return none + * The function Provides the guard bits for the buffer + * to avoid overflow + */ + +void arm_provide_guard_bits_q31 (q31_t * input_buf, + uint32_t blockSize, + uint32_t guard_bits) +{ + uint32_t i; + + for (i = 0; i < blockSize; i++) + { + input_buf[i] = input_buf[i] >> guard_bits; + } +} + +/** + * @brief Provide guard bits for Input buffer + * @param q31_t* Pointer to input buffer + * @param uint32_t blockSize + * @param uint32_t guard_bits + * @return none + * The function Provides the guard bits for the buffer + * to avoid overflow + */ + +void arm_provide_guard_bits_q7 (q7_t * input_buf, + uint32_t blockSize, + uint32_t guard_bits) +{ + uint32_t i; + + for (i = 0; i < blockSize; i++) + { + input_buf[i] = input_buf[i] >> guard_bits; + } +} + + + +/** + * @brief Caluclates number of guard bits + * @param uint32_t number of additions + * @return none + * The function Caluclates the number of guard bits + * depending on the numtaps + */ + +uint32_t arm_calc_guard_bits (uint32_t num_adds) +{ + uint32_t i = 1, j = 0; + + if (num_adds == 1) + { + return (0); + } + + while (i < num_adds) + { + i = i * 2; + j++; + } + + return (j); +} + +/** + * @brief Converts Q15 to floating-point + * @param uint32_t number of samples in the buffer + * @return none + */ + +void arm_apply_guard_bits (float32_t * pIn, + uint32_t numSamples, + uint32_t guard_bits) +{ + uint32_t i; + + for (i = 0; i < numSamples; i++) + { + pIn[i] = pIn[i] * arm_calc_2pow(guard_bits); + } +} + +/** + * @brief Calculates pow(2, numShifts) + * @param uint32_t number of shifts + * @return pow(2, numShifts) + */ +uint32_t arm_calc_2pow(uint32_t numShifts) +{ + + uint32_t i, val = 1; + + for (i = 0; i < numShifts; i++) + { + val = val * 2; + } + + return(val); +} + + + +/** + * @brief Converts float to fixed q14 + * @param uint32_t number of samples in the buffer + * @return none + * The function converts floating point values to fixed point values + */ + +void arm_float_to_q14 (float *pIn, q15_t * pOut, + uint32_t numSamples) +{ + uint32_t i; + + for (i = 0; i < numSamples; i++) + { + /* 16384.0f corresponds to pow(2, 14) */ + pOut[i] = (q15_t) (pIn[i] * 16384.0f); + + pOut[i] += pIn[i] > 0 ? 0.5 : -0.5; + + if (pIn[i] == (float) 2.0) + { + pOut[i] = 0x7FFF; + } + + } + +} + + +/** + * @brief Converts float to fixed q30 format + * @param uint32_t number of samples in the buffer + * @return none + * The function converts floating point values to fixed point values + */ + +void arm_float_to_q30 (float *pIn, q31_t * pOut, + uint32_t numSamples) +{ + uint32_t i; + + for (i = 0; i < numSamples; i++) + { + /* 1073741824.0f corresponds to pow(2, 30) */ + pOut[i] = (q31_t) (pIn[i] * 1073741824.0f); + + pOut[i] += pIn[i] > 0 ? 0.5 : -0.5; + + if (pIn[i] == (float) 2.0) + { + pOut[i] = 0x7FFFFFFF; + } + } +} + +/** + * @brief Converts float to fixed q30 format + * @param uint32_t number of samples in the buffer + * @return none + * The function converts floating point values to fixed point values + */ + +void arm_float_to_q29 (float *pIn, q31_t * pOut, + uint32_t numSamples) +{ + uint32_t i; + + for (i = 0; i < numSamples; i++) + { + /* 1073741824.0f corresponds to pow(2, 30) */ + pOut[i] = (q31_t) (pIn[i] * 536870912.0f); + + pOut[i] += pIn[i] > 0 ? 0.5 : -0.5; + + if (pIn[i] == (float) 4.0) + { + pOut[i] = 0x7FFFFFFF; + } + } +} + + +/** + * @brief Converts float to fixed q28 format + * @param uint32_t number of samples in the buffer + * @return none + * The function converts floating point values to fixed point values + */ + +void arm_float_to_q28 (float *pIn, q31_t * pOut, + uint32_t numSamples) +{ + uint32_t i; + + for (i = 0; i < numSamples; i++) + { + /* 268435456.0f corresponds to pow(2, 28) */ + pOut[i] = (q31_t) (pIn[i] * 268435456.0f); + + pOut[i] += pIn[i] > 0 ? 0.5 : -0.5; + + if (pIn[i] == (float) 8.0) + { + pOut[i] = 0x7FFFFFFF; + } + } +} + +/** + * @brief Clip the float values to +/- 1 + * @param pIn input buffer + * @param numSamples number of samples in the buffer + * @return none + * The function converts floating point values to fixed point values + */ + +void arm_clip_f32 (float *pIn, uint32_t numSamples) +{ + uint32_t i; + + for (i = 0; i < numSamples; i++) + { + if(pIn[i] > 1.0f) + { + pIn[i] = 1.0; + } + else if( pIn[i] < -1.0f) + { + pIn[i] = -1.0; + } + + } +} + + + diff --git a/cores/arduino/math_helper.h b/cores/arduino/math_helper.h new file mode 100644 index 000000000..866c55374 --- /dev/null +++ b/cores/arduino/math_helper.h @@ -0,0 +1,63 @@ + +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2013 ARM Limited. All rights reserved. +* +* $Date: 17. January 2013 +* $Revision: V1.4.0 +* +* Project: CMSIS DSP Library +* +* Title: math_helper.h +* +* Description: Prototypes of all helper functions required. +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + + +#include "arm_math.h" + +#ifndef MATH_HELPER_H +#define MATH_HELPER_H + +float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize); +void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples); +void arm_provide_guard_bits_q15(q15_t *input_buf, uint32_t blockSize, uint32_t guard_bits); +void arm_provide_guard_bits_q31(q31_t *input_buf, uint32_t blockSize, uint32_t guard_bits); +void arm_float_to_q14(float *pIn, q15_t *pOut, uint32_t numSamples); +void arm_float_to_q29(float *pIn, q31_t *pOut, uint32_t numSamples); +void arm_float_to_q28(float *pIn, q31_t *pOut, uint32_t numSamples); +void arm_float_to_q30(float *pIn, q31_t *pOut, uint32_t numSamples); +void arm_clip_f32(float *pIn, uint32_t numSamples); +uint32_t arm_calc_guard_bits(uint32_t num_adds); +void arm_apply_guard_bits (float32_t * pIn, uint32_t numSamples, uint32_t guard_bits); +uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples); +uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t *pOut, uint32_t numSamples); +uint32_t arm_calc_2pow(uint32_t guard_bits); +#endif diff --git a/cores/arduino/pulse.c b/cores/arduino/pulse.c index 2dd03bf47..6ead704dd 100644 --- a/cores/arduino/pulse.c +++ b/cores/arduino/pulse.c @@ -34,6 +34,36 @@ uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout) uint32_t bit = 1 << p.ulPin; uint32_t stateMask = state ? bit : 0; +#if defined(__SAMD51__) + /* + * The SAMD51 is fast enough to use really obvious code (similar to + * what was used to produce pulse_asm.S, but using micros() for timing. + * No assembly required, no conversion of loop counts to times (which is + * worrisome in the presence of cache.) + */ + const volatile uint32_t *port = &(PORT->Group[p.ulPort].IN.reg); + uint32_t usCallStart; // microseconds at start of call, for timeout. + uint32_t usPulseStart; // microseconds at start of measured pulse. + usCallStart = usPulseStart = micros(); + // wait for any previous pulse to end + while ((*port & bit) == stateMask) { + if (micros() - usCallStart > timeout) + return -1; + } + // wait for the pulse to start + while ((*port & bit) != stateMask) { + usPulseStart = micros(); + if (usPulseStart - usCallStart > timeout) + return -2; + } + + // wait for the pulse to stop + while ((*port & bit) == stateMask) { + if (micros() - usCallStart > timeout) + return -3; + } + return micros() - usPulseStart; +#else // convert the timeout from microseconds to a number of times through // the initial loop; it takes (roughly) 13 clock cycles per iteration. uint32_t maxloops = microsecondsToClockCycles(timeout) / 13; @@ -48,5 +78,6 @@ uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout) return clockCyclesToMicroseconds(width * 13 + 16); else return 0; +#endif // SAMD51 } diff --git a/cores/arduino/startup.c b/cores/arduino/startup.c index d66bfa8e6..c493b1af9 100644 --- a/cores/arduino/startup.c +++ b/cores/arduino/startup.c @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,23 +22,29 @@ #include -/** - * \brief SystemInit() configures the needed clocks and according Flash Read Wait States. - * At reset: - * - OSC8M clock source is enabled with a divider by 8 (1MHz). - * - Generic Clock Generator 0 (GCLKMAIN) is using OSC8M as source. - * We need to: - * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator), will be used as DFLL48M reference. - * 2) Put XOSC32K as source of Generic Clock Generator 1 - * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) - * 4) Enable DFLL48M clock - * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. - * 6) Modify PRESCaler value of OSCM to have 8MHz - * 7) Put OSC8M as source for Generic Clock Generator 3 - */ // Constants for Clock generators #define GENERIC_CLOCK_GENERATOR_MAIN (0u) + +#if defined(__SAMD51__) +#define GENERIC_CLOCK_GENERATOR_XOSC32K (3u) +#define GENERIC_CLOCK_GENERATOR_48M (1u) +#define GENERIC_CLOCK_GENERATOR_48M_SYNC GCLK_SYNCBUSY_GENCTRL1 +#define GENERIC_CLOCK_GENERATOR_100M (2u) +#define GENERIC_CLOCK_GENERATOR_100M_SYNC GCLK_SYNCBUSY_GENCTRL2 +#define GENERIC_CLOCK_GENERATOR_12M (4u) +#define GENERIC_CLOCK_GENERATOR_12M_SYNC GCLK_SYNCBUSY_GENCTRL4 + +//USE DPLL0 for 120MHZ +#define MAIN_CLOCK_SOURCE GCLK_GENCTRL_SRC_DPLL0 + +#define GENERIC_CLOCK_GENERATOR_1M (5u) +//#define CRYSTALLESS + +#else + #define GENERIC_CLOCK_GENERATOR_XOSC32K (1u) +#endif + #define GENERIC_CLOCK_GENERATOR_OSC32K (1u) #define GENERIC_CLOCK_GENERATOR_OSCULP32K (2u) /* Initialized at reset for WDT */ #define GENERIC_CLOCK_GENERATOR_OSC8M (3u) @@ -46,256 +53,527 @@ void SystemInit( void ) { - /* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */ - NVMCTRL->CTRLB.bit.RWS = NVMCTRL_CTRLB_RWS_HALF_Val ; - - /* Turn on the digital interface clock */ - PM->APBAMASK.reg |= PM_APBAMASK_GCLK ; - - -#if defined(CRYSTALLESS) - - /* ---------------------------------------------------------------------------------------------- - * 1) Enable OSC32K clock (Internal 32.768Hz oscillator) - */ - - uint32_t calib = (*((uint32_t *) FUSES_OSC32K_CAL_ADDR) & FUSES_OSC32K_CAL_Msk) >> FUSES_OSC32K_CAL_Pos; - - SYSCTRL->OSC32K.reg = SYSCTRL_OSC32K_CALIB(calib) | - SYSCTRL_OSC32K_STARTUP( 0x6u ) | // cf table 15.10 of product datasheet in chapter 15.8.6 - SYSCTRL_OSC32K_EN32K | - SYSCTRL_OSC32K_ENABLE; - - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC32KRDY) == 0 ); // Wait for oscillator stabilization - -#else // has crystal +//***************** SAMD51 ************************// +#if defined(__SAMD51__) + NVMCTRL->CTRLA.reg |= NVMCTRL_CTRLA_RWS(0); + + #ifndef CRYSTALLESS /* ---------------------------------------------------------------------------------------------- * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator) */ - SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP( 0x6u ) | /* cf table 15.10 of product datasheet in chapter 15.8.6 */ - SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K ; - SYSCTRL->XOSC32K.bit.ENABLE = 1 ; /* separate call, as described in chapter 15.6.3 */ - - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY) == 0 ) - { - /* Wait for oscillator stabilization */ + + OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_EN1K | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_CGM_XT | OSC32KCTRL_XOSC32K_XTALEN; + + while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){ + /* Wait for oscillator to be ready */ } -#endif - - /* Software reset the module to ensure it is re-initialized correctly */ - /* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete. - * CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1 - */ - GCLK->CTRL.reg = GCLK_CTRL_SWRST ; + #endif //CRYSTALLESS - while ( (GCLK->CTRL.reg & GCLK_CTRL_SWRST) && (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) ) - { - /* Wait for reset to complete */ + //software reset + + GCLK->CTRLA.bit.SWRST = 1; + while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_SWRST ){ + /* wait for reset to complete */ } + #ifndef CRYSTALLESS /* ---------------------------------------------------------------------------------------------- - * 2) Put XOSC32K as source of Generic Clock Generator 1 + * 2) Put XOSC32K as source of Generic Clock Generator 3 */ - GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) ; // Generic Clock Generator 1 - - while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) - { - /* Wait for synchronization */ - } - - /* Write Generic Clock Generator 1 configuration */ - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC32K ) | // Generic Clock Generator 1 -#if defined(CRYSTALLESS) - GCLK_GENCTRL_SRC_OSC32K | // Selected source is Internal 32KHz Oscillator -#else - GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator -#endif -// GCLK_GENCTRL_OE | // Output clock to a pin for tests - GCLK_GENCTRL_GENEN ; - - while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) - { - /* Wait for synchronization */ - } - + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_XOSC32K].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_XOSC32K) | //generic clock gen 3 + GCLK_GENCTRL_GENEN; + #else /* ---------------------------------------------------------------------------------------------- - * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) + * 2) Put OSCULP32K as source of Generic Clock Generator 3 */ - GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GENERIC_CLOCK_MULTIPLEXER_DFLL48M ) | // Generic Clock Multiplexer 0 - GCLK_CLKCTRL_GEN_GCLK1 | // Generic Clock Generator 1 is source - GCLK_CLKCTRL_CLKEN ; + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_XOSC32K].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN; //generic clock gen 3 + #endif + - while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) - { + while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL3 ){ /* Wait for synchronization */ } - + + /* ---------------------------------------------------------------------------------------------- + * 3) Put OSCULP32K as source for Generic Clock Generator 0 + */ + GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN; + /* ---------------------------------------------------------------------------------------------- * 4) Enable DFLL48M clock */ - /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */ - - /* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */ - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; - - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) - { - /* Wait for synchronization */ - } - - SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value - SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value - SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK + VARIANT_MAINOSC/2) / VARIANT_MAINOSC ) ; // External 32KHz is the reference - - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) - { - /* Wait for synchronization */ - } - -#if defined(CRYSTALLESS) - - #define NVM_SW_CALIB_DFLL48M_COARSE_VAL 58 - - // Turn on DFLL - uint32_t coarse =( *((uint32_t *)(NVMCTRL_OTP4) + (NVM_SW_CALIB_DFLL48M_COARSE_VAL / 32)) >> (NVM_SW_CALIB_DFLL48M_COARSE_VAL % 32) ) - & ((1 << 6) - 1); - if (coarse == 0x3f) { - coarse = 0x1f; - } - // TODO(tannewt): Load this value from memory we've written previously. There - // isn't a value from the Atmel factory. - uint32_t fine = 0x1ff; - - SYSCTRL->DFLLVAL.bit.COARSE = coarse; - SYSCTRL->DFLLVAL.bit.FINE = fine; - /* Write full configuration to DFLL control register */ - SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 0x1f / 4 ) | // Coarse step is 31, half of the max value - SYSCTRL_DFLLMUL_FSTEP( 10 ) | - SYSCTRL_DFLLMUL_MUL( (48000) ) ; - - SYSCTRL->DFLLCTRL.reg = 0; - - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) - { + while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL0 ){ /* Wait for synchronization */ } - SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_MODE | - SYSCTRL_DFLLCTRL_CCDIS | - SYSCTRL_DFLLCTRL_USBCRM | /* USB correction */ - SYSCTRL_DFLLCTRL_BPLCKC; - - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) - { + /* DFLL Configuration in Open Loop mode */ + + OSCCTRL->DFLLCTRLA.reg = 0; + //GCLK->PCHCTRL[OSCCTRL_GCLK_ID_DFLL48].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK3_Val); + + OSCCTRL->DFLLMUL.reg = OSCCTRL_DFLLMUL_CSTEP( 0x1 ) | + OSCCTRL_DFLLMUL_FSTEP( 0x1 ) | + OSCCTRL_DFLLMUL_MUL( 0 ); + + while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLMUL ) + { + /* Wait for synchronization */ + } + + OSCCTRL->DFLLCTRLB.reg = 0; + while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_DFLLCTRLB ) + { + /* Wait for synchronization */ + } + + OSCCTRL->DFLLCTRLA.reg |= OSCCTRL_DFLLCTRLA_ENABLE; + while ( OSCCTRL->DFLLSYNC.reg & OSCCTRL_DFLLSYNC_ENABLE ) + { + /* Wait for synchronization */ + } + + OSCCTRL->DFLLVAL.reg = OSCCTRL->DFLLVAL.reg; + while( OSCCTRL->DFLLSYNC.bit.DFLLVAL ); + + OSCCTRL->DFLLCTRLB.reg = OSCCTRL_DFLLCTRLB_WAITLOCK | + OSCCTRL_DFLLCTRLB_CCDIS | OSCCTRL_DFLLCTRLB_USBCRM ; + + while ( !OSCCTRL->STATUS.bit.DFLLRDY ) + { + /* Wait for synchronization */ + } + + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_1M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(48u); + + while ( GCLK->SYNCBUSY.bit.GENCTRL5 ){ /* Wait for synchronization */ } - - /* Enable the DFLL */ - SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE ; - -#else // has crystal - - /* Write full configuration to DFLL control register */ - SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */ - SYSCTRL_DFLLCTRL_WAITLOCK | - SYSCTRL_DFLLCTRL_QLDIS ; /* Disable Quick lock */ - - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) - { - /* Wait for synchronization */ - } - - /* Enable the DFLL */ - SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE ; - - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) == 0 || - (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF) == 0 ) - { - /* Wait for locks flags */ - } - + + + /* ------------------------------------------------------------------------ + * Set up the PLLs + */ + + //PLL0 is 120MHz + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val); + + // This rounds to nearest full-MHz increment; not currently using frac + OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR((F_CPU - 500000) / 1000000); + + while(OSCCTRL->Dpll[0].DPLLSYNCBUSY.bit.DPLLRATIO); + + //MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51 + OSCCTRL->Dpll[0].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK | OSCCTRL_DPLLCTRLB_LBYPASS; + + OSCCTRL->Dpll[0].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; + + while( OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK == 0 ); + + //PLL1 is 100MHz + GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val); + + OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(99); //100 Mhz + + while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.DPLLRATIO); + + //MUST USE LBYPASS DUE TO BUG IN REV A OF SAMD51 + OSCCTRL->Dpll[1].DPLLCTRLB.reg = OSCCTRL_DPLLCTRLB_REFCLK_GCLK | OSCCTRL_DPLLCTRLB_LBYPASS; + + OSCCTRL->Dpll[1].DPLLCTRLA.reg = OSCCTRL_DPLLCTRLA_ENABLE; + + while( OSCCTRL->Dpll[1].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[1].DPLLSTATUS.bit.LOCK == 0 ); + + + /* ------------------------------------------------------------------------ + * Set up the peripheral clocks + */ + + //48MHZ CLOCK FOR USB AND STUFF + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_48M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | + GCLK_GENCTRL_IDC | + //GCLK_GENCTRL_OE | + GCLK_GENCTRL_GENEN; + + while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_48M_SYNC) + { + /* Wait for synchronization */ + } + + //100MHZ CLOCK FOR OTHER PERIPHERALS + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_100M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DPLL1_Val) | + GCLK_GENCTRL_IDC | + //GCLK_GENCTRL_OE | + GCLK_GENCTRL_GENEN; + + while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_100M_SYNC) + { + /* Wait for synchronization */ + } + + //12MHZ CLOCK FOR DAC + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_12M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | + GCLK_GENCTRL_IDC | + GCLK_GENCTRL_DIV(4) | + //GCLK_GENCTRL_DIVSEL | + //GCLK_GENCTRL_OE | + GCLK_GENCTRL_GENEN; + + while ( GCLK->SYNCBUSY.reg & GENERIC_CLOCK_GENERATOR_12M_SYNC) + { + /* Wait for synchronization */ + } + + /*--------------------------------------------------------------------- + * Set up main clock + */ + + GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_MAIN].reg = GCLK_GENCTRL_SRC(MAIN_CLOCK_SOURCE) | + GCLK_GENCTRL_IDC | + //GCLK_GENCTRL_OE | + GCLK_GENCTRL_GENEN; + + + while ( GCLK->SYNCBUSY.reg & GCLK_SYNCBUSY_GENCTRL0 ) + { + /* Wait for synchronization */ + } + + MCLK->CPUDIV.reg = MCLK_CPUDIV_DIV_DIV1; + + /* Use the LDO regulator by default */ + SUPC->VREG.bit.SEL = 0; + + + /* If desired, enable cache! */ +#if defined(ENABLE_CACHE) + __disable_irq(); + CMCC->CTRL.reg = 1; + __enable_irq(); #endif - while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) - { - /* Wait for synchronization */ - } - - /* ---------------------------------------------------------------------------------------------- - * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + /*--------------------------------------------------------------------- + * Start up the "Debug Watchpoint and Trace" unit, so that we can use + * it's 32bit cycle counter for timing. */ - GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_MAIN ) ; // Generic Clock Generator 0 - - while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) - { - /* Wait for synchronization */ - } - - /* Write Generic Clock Generator 0 configuration */ - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0 - GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz -// GCLK_GENCTRL_OE | // Output clock to a pin for tests - GCLK_GENCTRL_IDC | // Set 50/50 duty cycle - GCLK_GENCTRL_GENEN ; - - while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) - { - /* Wait for synchronization */ - } + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; /* ---------------------------------------------------------------------------------------------- - * 6) Modify PRESCaler value of OSC8M to have 8MHz + * 5) Load AC factory calibration values */ - SYSCTRL->OSC8M.bit.PRESC = SYSCTRL_OSC8M_PRESC_0_Val ; //CMSIS 4.5 changed the prescaler defines - SYSCTRL->OSC8M.bit.ONDEMAND = 0 ; + + uint32_t bias0 = (*((uint32_t *)AC_FUSES_BIAS0_ADDR) & AC_FUSES_BIAS0_Msk) >> AC_FUSES_BIAS0_Pos; + AC->CALIB.reg = AC_CALIB_BIAS0(bias0); /* ---------------------------------------------------------------------------------------------- - * 7) Put OSC8M as source for Generic Clock Generator 3 + * 6) Load ADC factory calibration values */ - GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) ; // Generic Clock Generator 3 - /* Write Generic Clock Generator 3 configuration */ - GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3 - GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset) -// GCLK_GENCTRL_OE | // Output clock to a pin for tests - GCLK_GENCTRL_GENEN ; + // ADC0 Bias Calibration + uint32_t biascomp = (*((uint32_t *)ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos; + uint32_t biasr2r = (*((uint32_t *)ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos; + uint32_t biasref = (*((uint32_t *)ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos; - while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) - { - /* Wait for synchronization */ - } + ADC0->CALIB.reg = ADC_CALIB_BIASREFBUF(biasref) + | ADC_CALIB_BIASR2R(biasr2r) + | ADC_CALIB_BIASCOMP(biascomp); - /* - * Now that all system clocks are configured, we can set CPU and APBx BUS clocks. - * There values are normally the one present after Reset. - */ - PM->CPUSEL.reg = PM_CPUSEL_CPUDIV_DIV1 ; - PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val ; - PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val ; - PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val ; + // ADC1 Bias Calibration + biascomp = (*((uint32_t *)ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos; + biasr2r = (*((uint32_t *)ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos; + biasref = (*((uint32_t *)ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos; - SystemCoreClock=VARIANT_MCK ; + ADC1->CALIB.reg = ADC_CALIB_BIASREFBUF(biasref) + | ADC_CALIB_BIASR2R(biasr2r) + | ADC_CALIB_BIASCOMP(biascomp); /* ---------------------------------------------------------------------------------------------- - * 8) Load ADC factory calibration values + * 7) Load USB factory calibration values */ - // ADC Bias Calibration - uint32_t bias = (*((uint32_t *) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; + //USB Calibration + uint32_t usbtransn = (*((uint32_t *)USB_FUSES_TRANSN_ADDR) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos; + uint32_t usbtransp = (*((uint32_t *)USB_FUSES_TRANSP_ADDR) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos; + uint32_t usbtrim = (*((uint32_t *)USB_FUSES_TRIM_ADDR) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos; + USB->DEVICE.PADCAL.reg = USB_PADCAL_TRIM(usbtrim) + | USB_PADCAL_TRANSN(usbtransn) + | USB_PADCAL_TRANSP(usbtransp); - // ADC Linearity bits 4:0 - uint32_t linearity = (*((uint32_t *) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos; +//*************** END SAMD51 *************************// + +#else +//********************** SAMD21 *********************// - // ADC Linearity bits 7:5 - linearity |= ((*((uint32_t *) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5; + /** + * \brief SystemInit() configures the needed clocks and according Flash Read Wait States. + * At reset: + * - OSC8M clock source is enabled with a divider by 8 (1MHz). + * - Generic Clock Generator 0 (GCLKMAIN) is using OSC8M as source. + * We need to: + * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator), will be used as DFLL48M reference. + * 2) Put XOSC32K as source of Generic Clock Generator 1 + * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) + * 4) Enable DFLL48M clock + * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + * 6) Modify PRESCaler value of OSCM to have 8MHz + * 7) Put OSC8M as source for Generic Clock Generator 3 + */ - ADC->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | ADC_CALIB_LINEARITY_CAL(linearity); + + /* Set 1 Flash Wait State for 48MHz, cf tables 20.9 and 35.27 in SAMD21 Datasheet */ + NVMCTRL->CTRLB.bit.RWS = NVMCTRL_CTRLB_RWS_HALF_Val ; + + /* Turn on the digital interface clock */ + PM->APBAMASK.reg |= PM_APBAMASK_GCLK ; + + + #if defined(CRYSTALLESS) + + /* ---------------------------------------------------------------------------------------------- + * 1) Enable OSC32K clock (Internal 32.768Hz oscillator) + */ - /* - * 9) Disable automatic NVM write operations - */ - NVMCTRL->CTRLB.bit.MANW = 1; + uint32_t calib = (*((uint32_t *) FUSES_OSC32K_CAL_ADDR) & FUSES_OSC32K_CAL_Msk) >> FUSES_OSC32K_CAL_Pos; + + SYSCTRL->OSC32K.reg = SYSCTRL_OSC32K_CALIB(calib) | + SYSCTRL_OSC32K_STARTUP( 0x6u ) | // cf table 15.10 of product datasheet in chapter 15.8.6 + SYSCTRL_OSC32K_EN32K | + SYSCTRL_OSC32K_ENABLE; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC32KRDY) == 0 ); // Wait for oscillator stabilization + + #else // has crystal + + /* ---------------------------------------------------------------------------------------------- + * 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator) + */ + SYSCTRL->XOSC32K.reg = SYSCTRL_XOSC32K_STARTUP( 0x6u ) | /* cf table 15.10 of product datasheet in chapter 15.8.6 */ + SYSCTRL_XOSC32K_XTALEN | SYSCTRL_XOSC32K_EN32K ; + SYSCTRL->XOSC32K.bit.ENABLE = 1 ; /* separate call, as described in chapter 15.6.3 */ + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_XOSC32KRDY) == 0 ) + { + /* Wait for oscillator stabilization */ + } + + #endif + + /* Software reset the module to ensure it is re-initialized correctly */ + /* Note: Due to synchronization, there is a delay from writing CTRL.SWRST until the reset is complete. + * CTRL.SWRST and STATUS.SYNCBUSY will both be cleared when the reset is complete, as described in chapter 13.8.1 + */ + GCLK->CTRL.reg = GCLK_CTRL_SWRST ; + + while ( (GCLK->CTRL.reg & GCLK_CTRL_SWRST) && (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) ) + { + /* Wait for reset to complete */ + } + + /* ---------------------------------------------------------------------------------------------- + * 2) Put XOSC32K as source of Generic Clock Generator 1 + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_XOSC32K ) ; // Generic Clock Generator 1 + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* Write Generic Clock Generator 1 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC32K ) | // Generic Clock Generator 1 + #if defined(CRYSTALLESS) + GCLK_GENCTRL_SRC_OSC32K | // Selected source is Internal 32KHz Oscillator + #else + GCLK_GENCTRL_SRC_XOSC32K | // Selected source is External 32KHz Oscillator + #endif + // GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_GENEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 3) Put Generic Clock Generator 1 as source for Generic Clock Multiplexer 0 (DFLL48M reference) + */ + GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GENERIC_CLOCK_MULTIPLEXER_DFLL48M ) | // Generic Clock Multiplexer 0 + GCLK_CLKCTRL_GEN_GCLK1 | // Generic Clock Generator 1 is source + GCLK_CLKCTRL_CLKEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 4) Enable DFLL48M clock + */ + + /* DFLL Configuration in Closed Loop mode, cf product datasheet chapter 15.6.7.1 - Closed-Loop Operation */ + + /* Remove the OnDemand mode, Bug http://avr32.icgroup.norway.atmel.com/bugzilla/show_bug.cgi?id=9905 */ + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_ENABLE; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value + SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value + SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK + VARIANT_MAINOSC/2) / VARIANT_MAINOSC ) ; // External 32KHz is the reference + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + #if defined(CRYSTALLESS) + + #define NVM_SW_CALIB_DFLL48M_COARSE_VAL 58 + + // Turn on DFLL + uint32_t coarse =( *((uint32_t *)(NVMCTRL_OTP4) + (NVM_SW_CALIB_DFLL48M_COARSE_VAL / 32)) >> (NVM_SW_CALIB_DFLL48M_COARSE_VAL % 32) ) + & ((1 << 6) - 1); + if (coarse == 0x3f) { + coarse = 0x1f; + } + // TODO(tannewt): Load this value from memory we've written previously. There + // isn't a value from the Atmel factory. + uint32_t fine = 0x1ff; + + SYSCTRL->DFLLVAL.bit.COARSE = coarse; + SYSCTRL->DFLLVAL.bit.FINE = fine; + /* Write full configuration to DFLL control register */ + SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 0x1f / 4 ) | // Coarse step is 31, half of the max value + SYSCTRL_DFLLMUL_FSTEP( 10 ) | + SYSCTRL_DFLLMUL_MUL( (48000) ) ; + + SYSCTRL->DFLLCTRL.reg = 0; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + SYSCTRL->DFLLCTRL.reg = SYSCTRL_DFLLCTRL_MODE | + SYSCTRL_DFLLCTRL_CCDIS | + SYSCTRL_DFLLCTRL_USBCRM | /* USB correction */ + SYSCTRL_DFLLCTRL_BPLCKC; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* Enable the DFLL */ + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE ; + + #else // has crystal + + /* Write full configuration to DFLL control register */ + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_MODE | /* Enable the closed loop mode */ + SYSCTRL_DFLLCTRL_WAITLOCK | + SYSCTRL_DFLLCTRL_QLDIS ; /* Disable Quick lock */ + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* Enable the DFLL */ + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE ; + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKC) == 0 || + (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLLCKF) == 0 ) + { + /* Wait for locks flags */ + } + + #endif + + while ( (SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY) == 0 ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 5) Switch Generic Clock Generator 0 to DFLL48M. CPU will run at 48MHz. + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_MAIN ) ; // Generic Clock Generator 0 + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* Write Generic Clock Generator 0 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_MAIN ) | // Generic Clock Generator 0 + GCLK_GENCTRL_SRC_DFLL48M | // Selected source is DFLL 48MHz + // GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_IDC | // Set 50/50 duty cycle + GCLK_GENCTRL_GENEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* ---------------------------------------------------------------------------------------------- + * 6) Modify PRESCaler value of OSC8M to have 8MHz + */ + SYSCTRL->OSC8M.bit.PRESC = SYSCTRL_OSC8M_PRESC_0_Val ; //CMSIS 4.5 changed the prescaler defines + SYSCTRL->OSC8M.bit.ONDEMAND = 0 ; + + /* ---------------------------------------------------------------------------------------------- + * 7) Put OSC8M as source for Generic Clock Generator 3 + */ + GCLK->GENDIV.reg = GCLK_GENDIV_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) ; // Generic Clock Generator 3 + + /* Write Generic Clock Generator 3 configuration */ + GCLK->GENCTRL.reg = GCLK_GENCTRL_ID( GENERIC_CLOCK_GENERATOR_OSC8M ) | // Generic Clock Generator 3 + GCLK_GENCTRL_SRC_OSC8M | // Selected source is RC OSC 8MHz (already enabled at reset) + // GCLK_GENCTRL_OE | // Output clock to a pin for tests + GCLK_GENCTRL_GENEN ; + + while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY ) + { + /* Wait for synchronization */ + } + + /* + * Now that all system clocks are configured, we can set CPU and APBx BUS clocks. + * There values are normally the one present after Reset. + */ + PM->CPUSEL.reg = PM_CPUSEL_CPUDIV_DIV1 ; + PM->APBASEL.reg = PM_APBASEL_APBADIV_DIV1_Val ; + PM->APBBSEL.reg = PM_APBBSEL_APBBDIV_DIV1_Val ; + PM->APBCSEL.reg = PM_APBCSEL_APBCDIV_DIV1_Val ; + + SystemCoreClock=VARIANT_MCK ; + + /* ---------------------------------------------------------------------------------------------- + * 8) Load ADC factory calibration values + */ + + // ADC Bias Calibration + uint32_t bias = (*((uint32_t *) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos; + + // ADC Linearity bits 4:0 + uint32_t linearity = (*((uint32_t *) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos; + + // ADC Linearity bits 7:5 + linearity |= ((*((uint32_t *) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5; + + ADC->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | ADC_CALIB_LINEARITY_CAL(linearity); + + /* + * 9) Disable automatic NVM write operations + */ + NVMCTRL->CTRLB.bit.MANW = 1; + #endif } diff --git a/cores/arduino/wiring.c b/cores/arduino/wiring.c index c52a6e1dc..ad6c7982d 100644 --- a/cores/arduino/wiring.c +++ b/cores/arduino/wiring.c @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -22,11 +23,16 @@ extern "C" { #endif + +#if defined(__SAMD51__) +uint32_t SystemCoreClock=F_CPU; +#else /* * System Core Clock is at 1MHz (8MHz/8) at Reset. * It is switched to 48MHz in the Reset Handler (startup.c) */ uint32_t SystemCoreClock=1000000ul ; +#endif /* void calibrateADC() @@ -71,23 +77,88 @@ void init( void ) // // Clock EIC for I/O interrupts // PM->APBAMASK.reg |= PM_APBAMASK_EIC ; +#if defined(__SAMD51__) + MCLK->APBAMASK.reg |= MCLK_APBAMASK_SERCOM0 | MCLK_APBAMASK_SERCOM1 | MCLK_APBAMASK_TC0 | MCLK_APBAMASK_TC1; + + MCLK->APBBMASK.reg |= MCLK_APBBMASK_SERCOM2 | MCLK_APBBMASK_SERCOM3 | MCLK_APBBMASK_TCC0 | MCLK_APBBMASK_TCC1 | MCLK_APBBMASK_TC3 | MCLK_APBBMASK_TC2; + + MCLK->APBCMASK.reg |= MCLK_APBCMASK_TCC2 | MCLK_APBCMASK_TCC3 | MCLK_APBCMASK_TC4 | MCLK_APBCMASK_TC5; + + MCLK->APBDMASK.reg |= MCLK_APBDMASK_DAC | MCLK_APBDMASK_SERCOM4 | MCLK_APBDMASK_SERCOM5 | MCLK_APBDMASK_ADC0 | MCLK_APBDMASK_ADC1 | MCLK_APBDMASK_TCC4 + | MCLK_APBDMASK_TC6 | MCLK_APBDMASK_TC7 | MCLK_APBDMASK_SERCOM6 | MCLK_APBDMASK_SERCOM7; + +#else // Clock SERCOM for Serial PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 | PM_APBCMASK_SERCOM1 | PM_APBCMASK_SERCOM2 | PM_APBCMASK_SERCOM3 | PM_APBCMASK_SERCOM4 | PM_APBCMASK_SERCOM5 ; // Clock TC/TCC for Pulse and Analog - PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 ; + PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 | PM_APBCMASK_TC6 | PM_APBCMASK_TC7; - // Clock ADC/DAC for Analog - PM->APBCMASK.reg |= PM_APBCMASK_ADC | PM_APBCMASK_DAC ; + // ATSAMR, for example, doesn't have a DAC + #ifdef PM_APBCMASK_DAC + // Clock ADC/DAC for Analog + PM->APBCMASK.reg |= PM_APBCMASK_ADC | PM_APBCMASK_DAC ; + #endif +#endif +/* + Commented out to leave pins in default tri-state. This is + aimed at avoiding power consumption in DeepSleep. + // Setup all pins (digital and analog) in INPUT mode (default is nothing) for (uint32_t ul = 0 ; ul < NUM_DIGITAL_PINS ; ul++ ) { pinMode( ul, INPUT ) ; } +*/ // Initialize Analog Controller // Setting clock +#if defined(__SAMD51__) + //set to 1/(1/(48000000/32) * 6) = 250000 SPS + GCLK->PCHCTRL[ADC0_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); //use clock generator 1 (48Mhz) + GCLK->PCHCTRL[ADC1_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); //use clock generator 1 (48Mhz) + Adc *adcs[] = {ADC0, ADC1}; + for(int i=0; i<2; i++){ + + adcs[i]->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV32_Val; + adcs[i]->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; + + while( adcs[i]->SYNCBUSY.reg & ADC_SYNCBUSY_CTRLB ); //wait for sync + + adcs[i]->SAMPCTRL.reg = 5; // sampling Time Length + + while( adcs[i]->SYNCBUSY.reg & ADC_SYNCBUSY_SAMPCTRL ); //wait for sync + + adcs[i]->INPUTCTRL.reg = ADC_INPUTCTRL_MUXNEG_GND; // No Negative input (Internal Ground) + + while( adcs[i]->SYNCBUSY.reg & ADC_SYNCBUSY_INPUTCTRL ); //wait for sync + + // Averaging (see datasheet table in AVGCTRL register description) + adcs[i]->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1 | // 1 sample only (no oversampling nor averaging) + ADC_AVGCTRL_ADJRES(0x0ul); // Adjusting result by 0 + + while( adcs[i]->SYNCBUSY.reg & ADC_SYNCBUSY_AVGCTRL ); //wait for sync + } + + analogReference( AR_DEFAULT ) ; // Analog Reference is AREF pin (3.3v) + + GCLK->PCHCTRL[DAC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK4_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); //use clock generator 4 (12mhz) + while (GCLK->PCHCTRL[DAC_GCLK_ID].bit.CHEN == 0); + + while ( DAC->SYNCBUSY.bit.SWRST == 1 ); // Wait for synchronization of registers between the clock domains + DAC->CTRLA.bit.SWRST = 1; + while ( DAC->SYNCBUSY.bit.SWRST == 1 ); // Wait for synchronization of registers between the clock domains + + DAC->CTRLB.reg = DAC_CTRLB_REFSEL_VREFPU; // TODO: fix this once silicon bug is fixed + + //set refresh rates + DAC->DACCTRL[0].bit.REFRESH = 2; + DAC->DACCTRL[1].bit.REFRESH = 2; + +#else + //set to 1/(1/(48000000/32) * 6) = 250000 SPS + while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( GCM_ADC ) | // Generic Clock ADC @@ -96,10 +167,10 @@ void init( void ) while( ADC->STATUS.bit.SYNCBUSY == 1 ); // Wait for synchronization of registers between the clock domains - ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV512 | // Divide Clock by 512. + ADC->CTRLB.reg = ADC_CTRLB_PRESCALER_DIV32 | // Divide Clock by 32. ADC_CTRLB_RESSEL_10BIT; // 10 bits resolution as default - ADC->SAMPCTRL.reg = 0x3f; // Set max Sampling Time Length + ADC->SAMPCTRL.reg = 5; // Sampling Time Length while( ADC->STATUS.bit.SYNCBUSY == 1 ); // Wait for synchronization of registers between the clock domains @@ -118,9 +189,15 @@ void init( void ) GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source GCLK_CLKCTRL_CLKEN ; + // ATSAMR, for example, doesn't have a DAC + #ifdef DAC while ( DAC->STATUS.bit.SYNCBUSY == 1 ); // Wait for synchronization of registers between the clock domains DAC->CTRLB.reg = DAC_CTRLB_REFSEL_AVCC | // Using the 3.3V reference DAC_CTRLB_EOEN ; // External Output Enable (Vout) + #endif + + +#endif //SAMD51 } #ifdef __cplusplus diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index b58509c06..40f5a6424 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -1,5 +1,6 @@ /* Copyright (c) 2014 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,8 +26,17 @@ extern "C" { static int _readResolution = 10; static int _ADCResolution = 10; + +#if defined(__SAMD51__) +static int _writeResolution = 12; +static int _dacResolution = 12; +#else static int _writeResolution = 8; +//static int _dacResolution = 10; +#endif + +#if !defined(__SAMD51__) // Wait for synchronization of registers between the clock domains static __inline__ void syncADC() __attribute__((always_inline, unused)); static void syncADC() { @@ -34,12 +44,15 @@ static void syncADC() { ; } + // ATSAMR, for example, doesn't have a DAC +#ifdef DAC // Wait for synchronization of registers between the clock domains static __inline__ void syncDAC() __attribute__((always_inline, unused)); static void syncDAC() { while (DAC->STATUS.bit.SYNCBUSY == 1) ; } +#endif // Wait for synchronization of registers between the clock domains static __inline__ void syncTC_16(Tc* TCx) __attribute__((always_inline, unused)); @@ -53,20 +66,47 @@ static void syncTCC(Tcc* TCCx) { while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK); } +#else +static bool dacEnabled[2]; +#endif + void analogReadResolution(int res) { _readResolution = res; - if (res > 10) { - ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val; - _ADCResolution = 12; - } else if (res > 8) { - ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; - _ADCResolution = 10; - } else { - ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val; - _ADCResolution = 8; - } +#if defined(__SAMD51__) + + if (res > 10) { + ADC0->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val; + ADC1->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val; + _ADCResolution = 12; + } else if (res > 8) { + ADC0->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; + ADC1->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; + _ADCResolution = 10; + } else { + ADC0->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val; + ADC1->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val; + _ADCResolution = 8; + } + + + while(ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_CTRLB); //wait for sync + while(ADC1->SYNCBUSY.reg & ADC_SYNCBUSY_CTRLB); //wait for sync +#else + + if (res > 10) { + ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val; + _ADCResolution = 12; + } else if (res > 8) { + ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; + _ADCResolution = 10; + } else { + ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val; + _ADCResolution = 8; + } + syncADC(); +#endif } void analogWriteResolution(int res) @@ -93,10 +133,101 @@ static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) */ void analogReference(eAnalogReference mode) { +#if defined(__SAMD51__) + while(ADC0->SYNCBUSY.reg & ADC_SYNCBUSY_REFCTRL); //wait for sync + while(ADC1->SYNCBUSY.reg & ADC_SYNCBUSY_REFCTRL); //wait for sync + + //TODO: fix gains + switch (mode) + { + case AR_INTERNAL1V0: + //ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection + SUPC->VREF.bit.SEL = SUPC_VREF_SEL_1V0_Val; // select 1.0V + SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // + break; + + case AR_INTERNAL1V1: + //ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection + SUPC->VREF.bit.SEL = SUPC_VREF_SEL_1V1_Val; // select 1.1V + SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // + break; + + case AR_INTERNAL1V2: + //ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection + SUPC->VREF.bit.SEL = SUPC_VREF_SEL_1V2_Val; // select 1V2 + SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // + break; + + case AR_INTERNAL1V25: + //ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection + SUPC->VREF.bit.SEL = SUPC_VREF_SEL_1V25_Val; // select 1.25V + SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // + break; + + case AR_INTERNAL2V0: + //ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection + SUPC->VREF.bit.SEL = SUPC_VREF_SEL_2V0_Val; // select 2.0V + SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // + break; + + case AR_INTERNAL2V2: + //ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection + SUPC->VREF.bit.SEL = SUPC_VREF_SEL_2V2_Val; // select 2.2V + SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // + break; + + case AR_INTERNAL2V4: + //ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection + SUPC->VREF.bit.SEL = SUPC_VREF_SEL_2V4_Val; // select 2.4V + SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // + break; + + case AR_INTERNAL2V5: + //ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection + SUPC->VREF.bit.SEL = SUPC_VREF_SEL_2V5_Val; // select 2.5V + SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // + break; + + case AR_EXTERNAL: + //ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val; // AREF is jumpered to VCC, so 3.3V + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val; + break; + + case AR_INTERNAL1V65: + //ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val; + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/2 VDDANA = 1.65 + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // + break; + + case AR_DEFAULT: + default: + //ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val; + ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // VDDANA = 3V3 + ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // + break; + } + +#else syncADC(); switch (mode) { - case AR_INTERNAL: case AR_INTERNAL2V23: ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297 @@ -123,29 +254,108 @@ void analogReference(eAnalogReference mode) ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V break; } +#endif } uint32_t analogRead(uint32_t pin) { uint32_t valueRead = 0; - if (pin < A0) { +#if defined(PIN_A6) + if (pin == 6) { + pin = PIN_A6; + } else +#endif +#if defined(PIN_A7) + if (pin == 7) { + pin = PIN_A7; + } else +#endif + if (pin <= 5) { pin += A0; } pinPeripheral(pin, PIO_ANALOG); + //ATSAMR, for example, doesn't have a DAC +#ifdef DAC + + #if defined(__SAMD51__) + if (pin == PIN_DAC0 || pin == PIN_DAC1) { // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled + uint8_t channel = (pin == PIN_DAC0 ? 0 : 1); + + if(dacEnabled[channel]){ + dacEnabled[channel] = false; + + while (DAC->SYNCBUSY.bit.ENABLE || DAC->SYNCBUSY.bit.SWRST); + DAC->CTRLA.bit.ENABLE = 0; // disable DAC + + while (DAC->SYNCBUSY.bit.ENABLE || DAC->SYNCBUSY.bit.SWRST); + DAC->DACCTRL[channel].bit.ENABLE = 0; + + while (DAC->SYNCBUSY.bit.ENABLE || DAC->SYNCBUSY.bit.SWRST); + DAC->CTRLA.bit.ENABLE = 1; // enable DAC + } + + while (DAC->SYNCBUSY.bit.ENABLE); + #else + if (pin == PIN_DAC0) { // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled + syncDAC(); + + DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC + //DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off. + syncDAC(); + #endif + } - // Disable DAC, if analogWrite() was used previously to enable the DAC - if ((g_APinDescription[pin].ulADCChannelNumber == ADC_Channel0) || (g_APinDescription[pin].ulADCChannelNumber == DAC_Channel0)) { - syncDAC(); - DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC - //DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off. - syncDAC(); - } +#endif + +#if defined(__SAMD51__) + Adc *adc; + if(g_APinDescription[pin].ulPinAttribute & PIN_ATTR_ANALOG) adc = ADC0; + else if(g_APinDescription[pin].ulPinAttribute & PIN_ATTR_ANALOG_ALT) adc = ADC1; + else return 0; + while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_INPUTCTRL ); //wait for sync + adc->INPUTCTRL.bit.MUXPOS = g_APinDescription[pin].ulADCChannelNumber; // Selection for the positive ADC input + + // Control A + /* + * Bit 1 ENABLE: Enable + * 0: The ADC is disabled. + * 1: The ADC is enabled. + * Due to synchronization, there is a delay from writing CTRLA.ENABLE until the peripheral is enabled/disabled. The + * value written to CTRL.ENABLE will read back immediately and the Synchronization Busy bit in the Status register + * (STATUS.SYNCBUSY) will be set. STATUS.SYNCBUSY will be cleared when the operation is complete. + * + * Before enabling the ADC, the asynchronous clock source must be selected and enabled, and the ADC reference must be + * configured. The first conversion after the reference is changed must not be used. + */ + while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync + adc->CTRLA.bit.ENABLE = 0x01; // Enable ADC + + // Start conversion + while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync + + adc->SWTRIG.bit.START = 1; + + // Clear the Data Ready flag + adc->INTFLAG.reg = ADC_INTFLAG_RESRDY; + + // Start conversion again, since The first conversion after the reference is changed must not be used. + adc->SWTRIG.bit.START = 1; + + // Store the value + while (adc->INTFLAG.bit.RESRDY == 0); // Waiting for conversion to complete + valueRead = adc->RESULT.reg; + + while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync + adc->CTRLA.bit.ENABLE = 0x00; // Disable ADC + while( adc->SYNCBUSY.reg & ADC_SYNCBUSY_ENABLE ); //wait for sync + +#else syncADC(); ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[pin].ulADCChannelNumber; // Selection for the positive ADC input - + // Control A /* * Bit 1 ENABLE: Enable @@ -165,6 +375,9 @@ uint32_t analogRead(uint32_t pin) syncADC(); ADC->SWTRIG.bit.START = 1; + // Waiting for the 1st conversion to complete + while (ADC->INTFLAG.bit.RESRDY == 0); + // Clear the Data Ready flag ADC->INTFLAG.reg = ADC_INTFLAG_RESRDY; @@ -179,6 +392,7 @@ uint32_t analogRead(uint32_t pin) syncADC(); ADC->CTRLA.bit.ENABLE = 0x00; // Disable ADC syncADC(); +#endif return mapResolution(valueRead, _ADCResolution, _readResolution); } @@ -193,115 +407,273 @@ void analogWrite(uint32_t pin, uint32_t value) PinDescription pinDesc = g_APinDescription[pin]; uint32_t attr = pinDesc.ulPinAttribute; - if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) - { - // DAC handling code + // ATSAMR, for example, doesn't have a DAC +#ifdef DAC + if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) + { + // DAC handling code +#if defined(__SAMD51__) + if (pin == PIN_DAC0 || pin == PIN_DAC1) { // 2 DACs on A0 (PA02) and A1 (PA05) +#else + if (pin == PIN_DAC0) { // Only 1 DAC on A0 (PA02) +#endif - if ((pinDesc.ulADCChannelNumber != ADC_Channel0) && (pinDesc.ulADCChannelNumber != DAC_Channel0)) { // Only 1 DAC on AIN0 / PA02 - return; - } +#if defined(__SAMD51__) - value = mapResolution(value, _writeResolution, 10); + value = mapResolution(value, _writeResolution, _dacResolution); - syncDAC(); - DAC->DATA.reg = value & 0x3FF; // DAC on 10 bits. - syncDAC(); - DAC->CTRLA.bit.ENABLE = 0x01; // Enable DAC - syncDAC(); - return; - } + + uint8_t channel = (pin == PIN_DAC0 ? 0 : 1); + + pinPeripheral(pin, PIO_ANALOG); + + if(!dacEnabled[channel]){ + dacEnabled[channel] = true; + + while (DAC->SYNCBUSY.bit.ENABLE || DAC->SYNCBUSY.bit.SWRST); + DAC->CTRLA.bit.ENABLE = 0; // disable DAC + + while (DAC->SYNCBUSY.bit.ENABLE || DAC->SYNCBUSY.bit.SWRST); + DAC->DACCTRL[channel].bit.ENABLE = 1; + + while (DAC->SYNCBUSY.bit.ENABLE || DAC->SYNCBUSY.bit.SWRST); + DAC->CTRLA.bit.ENABLE = 1; // enable DAC + + if(channel == 0){ + + while ( !DAC->STATUS.bit.READY0 ); + + while (DAC->SYNCBUSY.bit.DATA0); + DAC->DATA[0].reg = value; + } + else if(channel == 1){ + while ( !DAC->STATUS.bit.READY1 ); + + while (DAC->SYNCBUSY.bit.DATA1); + DAC->DATA[1].reg = value; + } + + delayMicroseconds(10000); + } + + //ERROR! + while(!DAC->DACCTRL[channel].bit.ENABLE); + + if(channel == 0){ + + while ( !DAC->STATUS.bit.READY0 ); + + while (DAC->SYNCBUSY.bit.DATA0); + DAC->DATA[0].reg = value; // DAC on 10 bits. + } + else if(channel == 1){ + while ( !DAC->STATUS.bit.READY1 ); + + while (DAC->SYNCBUSY.bit.DATA1); + DAC->DATA[1].reg = value; // DAC on 10 bits. + } + + +#else + syncDAC(); + DAC->DATA.reg = value & 0x3FF; // DAC on 10 bits. + syncDAC(); + DAC->CTRLA.bit.ENABLE = 0x01; // Enable DAC + syncDAC(); +#endif // __SAMD51__ + return; + } + } +#endif // DAC + +#if defined(__SAMD51__) + if(attr & (PIN_ATTR_PWM_E|PIN_ATTR_PWM_F|PIN_ATTR_PWM_G)){ + + uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel); + uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel); + static bool tcEnabled[TCC_INST_NUM+TC_INST_NUM]; + + if(attr & PIN_ATTR_PWM_E) + pinPeripheral(pin, PIO_TIMER); + else if(attr & PIN_ATTR_PWM_F) + pinPeripheral(pin, PIO_TIMER_ALT); + else if(attr & PIN_ATTR_PWM_G) + pinPeripheral(pin, PIO_TCC_PDEC); + + if (!tcEnabled[tcNum]) { + tcEnabled[tcNum] = true; + GCLK->PCHCTRL[GCLK_CLKCTRL_IDs[tcNum]].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos); //use clock generator 0 + + // Set PORT + if (tcNum >= TCC_INST_NUM) { + // -- Configure TC + Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); + + //reset + TCx->COUNT8.CTRLA.bit.SWRST = 1; + while (TCx->COUNT8.SYNCBUSY.bit.SWRST); + + // Disable TCx + TCx->COUNT8.CTRLA.bit.ENABLE = 0; + while (TCx->COUNT8.SYNCBUSY.bit.ENABLE); + // Set Timer counter Mode to 8 bits, normal PWM, prescaler 1/256 + TCx->COUNT8.CTRLA.reg = TC_CTRLA_MODE_COUNT8 | TC_CTRLA_PRESCALER_DIV256; + TCx->COUNT8.WAVE.reg = TC_WAVE_WAVEGEN_NPWM; + + while (TCx->COUNT8.SYNCBUSY.bit.CC0); + // Set the initial value + TCx->COUNT8.CC[tcChannel].reg = (uint8_t) value; + while (TCx->COUNT8.SYNCBUSY.bit.CC0); + // Set PER to maximum counter value (resolution : 0xFF) + TCx->COUNT8.PER.reg = 0xFF; + while (TCx->COUNT8.SYNCBUSY.bit.PER); + // Enable TCx + TCx->COUNT8.CTRLA.bit.ENABLE = 1; + while (TCx->COUNT8.SYNCBUSY.bit.ENABLE); + } else { + // -- Configure TCC + Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); + + TCCx->CTRLA.bit.SWRST = 1; + while (TCCx->SYNCBUSY.bit.SWRST); + + // Disable TCCx + TCCx->CTRLA.bit.ENABLE = 0; + while (TCCx->SYNCBUSY.bit.ENABLE); + // Set prescaler to 1/256 + TCCx->CTRLA.reg = TCC_CTRLA_PRESCALER_DIV256 | TCC_CTRLA_PRESCSYNC_GCLK; + + // Set TCx as normal PWM + TCCx->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM; + while ( TCCx->SYNCBUSY.bit.WAVE ); + + while (TCCx->SYNCBUSY.bit.CC0 || TCCx->SYNCBUSY.bit.CC1); + // Set the initial value + TCCx->CC[tcChannel].reg = (uint32_t) value; + while (TCCx->SYNCBUSY.bit.CC0 || TCCx->SYNCBUSY.bit.CC1); + // Set PER to maximum counter value (resolution : 0xFF) + TCCx->PER.reg = 0xFF; + while (TCCx->SYNCBUSY.bit.PER); + // Enable TCCx + TCCx->CTRLA.bit.ENABLE = 1; + while (TCCx->SYNCBUSY.bit.ENABLE); + } + } + else { + if (tcNum >= TCC_INST_NUM) { + Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); + TCx->COUNT8.CC[tcChannel].reg = (uint8_t) value; + while (TCx->COUNT8.SYNCBUSY.bit.CC0 || TCx->COUNT8.SYNCBUSY.bit.CC1); + } else { + Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); + while (TCCx->SYNCBUSY.bit.CTRLB); + while (TCCx->SYNCBUSY.bit.CC0 || TCCx->SYNCBUSY.bit.CC1); + TCCx->CCBUF[tcChannel].reg = (uint32_t) value; + while (TCCx->SYNCBUSY.bit.CC0 || TCCx->SYNCBUSY.bit.CC1); + TCCx->CTRLBCLR.bit.LUPD = 1; + while (TCCx->SYNCBUSY.bit.CTRLB); + } + } + + return; + } + +#else if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) - { - value = mapResolution(value, _writeResolution, 16); - - uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel); - uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel); - static bool tcEnabled[TCC_INST_NUM+TC_INST_NUM]; - - if (attr & PIN_ATTR_TIMER) { - #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603) - // Compatibility for cores based on SAMD core <=1.6.2 - if (pinDesc.ulPinType == PIO_TIMER_ALT) { - pinPeripheral(pin, PIO_TIMER_ALT); - } else - #endif - { - pinPeripheral(pin, PIO_TIMER); - } - } else { - // We suppose that attr has PIN_ATTR_TIMER_ALT bit set... - pinPeripheral(pin, PIO_TIMER_ALT); - } - - if (!tcEnabled[tcNum]) { - tcEnabled[tcNum] = true; - - uint16_t GCLK_CLKCTRL_IDs[] = { - GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC0 - GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC1 - GCLK_CLKCTRL_ID(GCM_TCC2_TC3), // TCC2 - GCLK_CLKCTRL_ID(GCM_TCC2_TC3), // TC3 - GCLK_CLKCTRL_ID(GCM_TC4_TC5), // TC4 - GCLK_CLKCTRL_ID(GCM_TC4_TC5), // TC5 - GCLK_CLKCTRL_ID(GCM_TC6_TC7), // TC6 - GCLK_CLKCTRL_ID(GCM_TC6_TC7), // TC7 - }; - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_IDs[tcNum]); - while (GCLK->STATUS.bit.SYNCBUSY == 1); - - // Set PORT - if (tcNum >= TCC_INST_NUM) { - // -- Configure TC - Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); - // Disable TCx - TCx->COUNT16.CTRLA.bit.ENABLE = 0; - syncTC_16(TCx); - // Set Timer counter Mode to 16 bits, normal PWM - TCx->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_NPWM; - syncTC_16(TCx); - // Set the initial value - TCx->COUNT16.CC[tcChannel].reg = (uint32_t) value; - syncTC_16(TCx); - // Enable TCx - TCx->COUNT16.CTRLA.bit.ENABLE = 1; - syncTC_16(TCx); - } else { - // -- Configure TCC - Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); - // Disable TCCx - TCCx->CTRLA.bit.ENABLE = 0; - syncTCC(TCCx); - // Set TCCx as normal PWM - TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; - syncTCC(TCCx); - // Set the initial value - TCCx->CC[tcChannel].reg = (uint32_t) value; - syncTCC(TCCx); - // Set PER to maximum counter value (resolution : 0xFFFF) - TCCx->PER.reg = 0xFFFF; - syncTCC(TCCx); - // Enable TCCx - TCCx->CTRLA.bit.ENABLE = 1; - syncTCC(TCCx); - } - } else { - if (tcNum >= TCC_INST_NUM) { - Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); - TCx->COUNT16.CC[tcChannel].reg = (uint32_t) value; - syncTC_16(TCx); - } else { - Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); - TCCx->CTRLBSET.bit.LUPD = 1; - syncTCC(TCCx); - TCCx->CCB[tcChannel].reg = (uint32_t) value; - syncTCC(TCCx); - TCCx->CTRLBCLR.bit.LUPD = 1; - syncTCC(TCCx); - } - } - return; + { + value = mapResolution(value, _writeResolution, 16); + + uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel); + uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel); + static bool tcEnabled[TCC_INST_NUM+TC_INST_NUM]; + + if (attr & PIN_ATTR_TIMER) { +#if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603) + // Compatibility for cores based on SAMD core <=1.6.2 + if (pinDesc.ulPinType == PIO_TIMER_ALT) { + pinPeripheral(pin, PIO_TIMER_ALT); + } else +#endif + { + pinPeripheral(pin, PIO_TIMER); + } + } else if ((attr & PIN_ATTR_TIMER_ALT) == PIN_ATTR_TIMER_ALT){ + //this is on an alt timer + pinPeripheral(pin, PIO_TIMER_ALT); + } + else{ + return; + } + + if (!tcEnabled[tcNum]) { + tcEnabled[tcNum] = true; + uint16_t GCLK_CLKCTRL_IDs[] = { + GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC0 + GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC1 + GCLK_CLKCTRL_ID(GCM_TCC2_TC3), // TCC2 + GCLK_CLKCTRL_ID(GCM_TCC2_TC3), // TC3 + GCLK_CLKCTRL_ID(GCM_TC4_TC5), // TC4 + GCLK_CLKCTRL_ID(GCM_TC4_TC5), // TC5 + GCLK_CLKCTRL_ID(GCM_TC6_TC7), // TC6 + GCLK_CLKCTRL_ID(GCM_TC6_TC7), // TC7 + }; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_IDs[tcNum]); + while (GCLK->STATUS.bit.SYNCBUSY == 1); + + // Set PORT + if (tcNum >= TCC_INST_NUM) { + // -- Configure TC + Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); + // Disable TCx + TCx->COUNT16.CTRLA.bit.ENABLE = 0; + syncTC_16(TCx); + // Set Timer counter Mode to 16 bits, normal PWM + TCx->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_NPWM; + syncTC_16(TCx); + // Set the initial value + TCx->COUNT16.CC[tcChannel].reg = (uint32_t) value; + syncTC_16(TCx); + // Enable TCx + TCx->COUNT16.CTRLA.bit.ENABLE = 1; + syncTC_16(TCx); + } else { + // -- Configure TCC + Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); + // Disable TCCx + TCCx->CTRLA.bit.ENABLE = 0; + syncTCC(TCCx); + // Set TCCx as normal PWM + TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; + syncTCC(TCCx); + // Set the initial value + TCCx->CC[tcChannel].reg = (uint32_t) value; + syncTCC(TCCx); + // Set PER to maximum counter value (resolution : 0xFFFF) + TCCx->PER.reg = 0xFFFF; + syncTCC(TCCx); + // Enable TCCx + TCCx->CTRLA.bit.ENABLE = 1; + syncTCC(TCCx); + } + } else { + if (tcNum >= TCC_INST_NUM) { + Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); + TCx->COUNT16.CC[tcChannel].reg = (uint32_t) value; + syncTC_16(TCx); + } else { + Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); + TCCx->CTRLBSET.bit.LUPD = 1; + syncTCC(TCCx); + TCCx->CCB[tcChannel].reg = (uint32_t) value; + syncTCC(TCCx); + TCCx->CTRLBCLR.bit.LUPD = 1; + syncTCC(TCCx); + } + } + return; } +#endif // -- Defaults to digital write pinMode(pin, OUTPUT); diff --git a/cores/arduino/wiring_analog.h b/cores/arduino/wiring_analog.h index cca46359c..d8dce7335 100644 --- a/cores/arduino/wiring_analog.h +++ b/cores/arduino/wiring_analog.h @@ -27,14 +27,21 @@ extern "C" { /* * \brief SAMD products have only one reference for ADC */ + // add internal voltages for ATSAMD51 SUPC VREF register typedef enum _eAnalogReference { AR_DEFAULT, - AR_INTERNAL, - AR_EXTERNAL, AR_INTERNAL1V0, + AR_INTERNAL1V1, + AR_INTERNAL1V2, + AR_INTERNAL1V25, + AR_INTERNAL2V0, + AR_INTERNAL2V2, + AR_INTERNAL2V23, + AR_INTERNAL2V4, + AR_INTERNAL2V5, AR_INTERNAL1V65, - AR_INTERNAL2V23 + AR_EXTERNAL } eAnalogReference ; diff --git a/cores/arduino/wiring_digital.c b/cores/arduino/wiring_digital.c index 026af80df..c62fdebfb 100644 --- a/cores/arduino/wiring_digital.c +++ b/cores/arduino/wiring_digital.c @@ -30,44 +30,48 @@ void pinMode( uint32_t ulPin, uint32_t ulMode ) return ; } + EPortType port = g_APinDescription[ulPin].ulPort; + uint32_t pin = g_APinDescription[ulPin].ulPin; + uint32_t pinMask = (1ul << pin); + // Set pin mode according to chapter '22.6.3 I/O Pin Configuration' switch ( ulMode ) { case INPUT: // Set pin to input mode - PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN) ; - PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN); + PORT->Group[port].DIRCLR.reg = pinMask; + break; case INPUT_PULLUP: // Set pin to input mode with pull-up resistor enabled - PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ; - PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN); + PORT->Group[port].DIRCLR.reg = pinMask; // Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.7 Data Output Value Set') - PORT->Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (uint32_t)(1<Group[port].OUTSET.reg = pinMask; + break; case INPUT_PULLDOWN: // Set pin to input mode with pull-down resistor enabled - PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ; - PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN); + PORT->Group[port].DIRCLR.reg = pinMask; // Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.6 Data Output Value Clear') - PORT->Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (uint32_t)(1<Group[port].OUTCLR.reg = pinMask; + break; case OUTPUT: // enable input, to support reading back values, with pullups disabled - PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN) ; + PORT->Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_DRVSTR); // Set pin to output mode - PORT->Group[g_APinDescription[ulPin].ulPort].DIRSET.reg = (uint32_t)(1<Group[port].DIRSET.reg = pinMask; + break; default: // do nothing - break ; + break; } } diff --git a/cores/arduino/wiring_digital.h b/cores/arduino/wiring_digital.h index 9895390f2..d7dff21df 100644 --- a/cores/arduino/wiring_digital.h +++ b/cores/arduino/wiring_digital.h @@ -25,6 +25,8 @@ #include "WVariant.h" +typedef int PinStatus; + /** * \brief Configures the specified pin to behave either as an input or an output. See the description of digital pins for details. * diff --git a/cores/arduino/wiring_private.c b/cores/arduino/wiring_private.c index a5aaba42c..954f854af 100644 --- a/cores/arduino/wiring_private.c +++ b/cores/arduino/wiring_private.c @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -67,8 +68,19 @@ int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral ) case PIO_TIMER: case PIO_TIMER_ALT: case PIO_EXTINT: +#if defined(__SAMD51__) + case PIO_TCC_PDEC: case PIO_COM: + case PIO_SDHC: + case PIO_I2S: + case PIO_PCC: + case PIO_GMAC: case PIO_AC_CLK: + case PIO_CCL: +#else + case PIO_COM: + case PIO_AC_CLK: +#endif #if 0 // Is the pio pin in the lower 16 ones? // The WRCONFIG register allows update of only 16 pin max out of 32 @@ -95,7 +107,7 @@ int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral ) // Set new muxing PORT->Group[g_APinDescription[ulPin].ulPort].PMUX[g_APinDescription[ulPin].ulPin >> 1].reg = temp|PORT_PMUX_PMUXO( ulPeripheral ) ; // Enable port mux - PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg |= PORT_PINCFG_PMUXEN ; + PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg |= PORT_PINCFG_PMUXEN | PORT_PINCFG_DRVSTR; } else // even pin { @@ -103,7 +115,7 @@ int pinPeripheral( uint32_t ulPin, EPioType ulPeripheral ) temp = (PORT->Group[g_APinDescription[ulPin].ulPort].PMUX[g_APinDescription[ulPin].ulPin >> 1].reg) & PORT_PMUX_PMUXO( 0xF ) ; PORT->Group[g_APinDescription[ulPin].ulPort].PMUX[g_APinDescription[ulPin].ulPin >> 1].reg = temp|PORT_PMUX_PMUXE( ulPeripheral ) ; - PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg |= PORT_PINCFG_PMUXEN ; // Enable port mux + PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg |= PORT_PINCFG_PMUXEN | PORT_PINCFG_DRVSTR ; // Enable port mux } #endif break ; diff --git a/drivers/prewin10/adafruit_circuit_playground_express.cat b/drivers/prewin10/adafruit_circuit_playground_express.cat index 1a54878e4..92f460109 100644 Binary files a/drivers/prewin10/adafruit_circuit_playground_express.cat and b/drivers/prewin10/adafruit_circuit_playground_express.cat differ diff --git a/drivers/prewin10/adafruit_circuit_playground_express.inf b/drivers/prewin10/adafruit_circuit_playground_express.inf index 248caec08..110b9b738 100644 --- a/drivers/prewin10/adafruit_circuit_playground_express.inf +++ b/drivers/prewin10/adafruit_circuit_playground_express.inf @@ -46,6 +46,14 @@ StartType=3 ErrorControl=1 ServiceBinary=%12%\%DRIVERFILENAME%.sys +[NullInstall.nt] +; nothing to do for a null driver + +[NullInstall.nt.Services] +; null driver has no service and no service name +AddService=, 0x00000002 + + ;------------------------------------------------------------------------------ ; Vista-64bit Sections ;------------------------------------------------------------------------------ @@ -73,6 +81,13 @@ StartType=3 ErrorControl=1 ServiceBinary=%12%\%DRIVERFILENAME%.sys +[NullInstall.NTamd64] +; nothing to do for a null driver + +[NullInstall.NTamd64.Services] +; null driver has no service and no service name +AddService=, 0x00000002 + ;------------------------------------------------------------------------------ ; Vendor and Product ID Definitions @@ -87,14 +102,14 @@ ServiceBinary=%12%\%DRIVERFILENAME%.sys [SourceDisksNames] [DeviceList] "%DESCRIPTION% UF2 Bootloader (0018:00) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00 -"%DESCRIPTION% UF2 WebUSB dummy (0018:04) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00 +"%DESCRIPTION% UF2 WebUSB dummy (0018:04) BSP"=NullInstall, USB\VID_239A&PID_0018&MI_04 "%DESCRIPTION% (0019:00) BSP"=DriverInstall, USB\VID_239A&PID_0019&MI_00 "%DESCRIPTION% Arduino (8018:00) BSP"=DriverInstall, USB\VID_239A&PID_8018&MI_00 "%DESCRIPTION% CircuitPython (8019:00) BSP"=DriverInstall, USB\VID_239A&PID_8019&MI_00 [DeviceList.NTamd64] "%DESCRIPTION% UF2 Bootloader (0018:00) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00 -"%DESCRIPTION% UF2 WebUSB dummy (0018:04) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00 +"%DESCRIPTION% UF2 WebUSB dummy (0018:04) BSP"=NullInstall, USB\VID_239A&PID_0018&MI_04 "%DESCRIPTION% (0019:00) BSP"=DriverInstall, USB\VID_239A&PID_0019&MI_00 "%DESCRIPTION% Arduino (8018:00) BSP"=DriverInstall, USB\VID_239A&PID_8018&MI_00 "%DESCRIPTION% CircuitPython (8019:00) BSP"=DriverInstall, USB\VID_239A&PID_8019&MI_00 diff --git a/libraries/Adafruit_TinyUSB_Arduino b/libraries/Adafruit_TinyUSB_Arduino new file mode 160000 index 000000000..c953968c4 --- /dev/null +++ b/libraries/Adafruit_TinyUSB_Arduino @@ -0,0 +1 @@ +Subproject commit c953968c468218d8968138b5ed8482fa565373df diff --git a/libraries/Adafruit_ZeroDMA b/libraries/Adafruit_ZeroDMA new file mode 160000 index 000000000..acc5dadb4 --- /dev/null +++ b/libraries/Adafruit_ZeroDMA @@ -0,0 +1 @@ +Subproject commit acc5dadb458b2c329757a61dc4f18dda945a0c36 diff --git a/libraries/CI_Tests/CI_Tests.h b/libraries/CI_Tests/CI_Tests.h new file mode 100644 index 000000000..2cfb22acd --- /dev/null +++ b/libraries/CI_Tests/CI_Tests.h @@ -0,0 +1 @@ +// fake empty header file to make Arduino IDE happy diff --git a/libraries/CI_Tests/examples/test_cmsis_fast_rfft/test_cmsis_fast_rfft.ino b/libraries/CI_Tests/examples/test_cmsis_fast_rfft/test_cmsis_fast_rfft.ino new file mode 100644 index 000000000..45c8c08db --- /dev/null +++ b/libraries/CI_Tests/examples/test_cmsis_fast_rfft/test_cmsis_fast_rfft.ino @@ -0,0 +1,12 @@ +#include + +arm_rfft_fast_instance_f32 plan; + +void setup() { + arm_rfft_fast_init_f32(&plan, 256); +} + +void loop() { + float in[256] = { 0 }, out[256] = { 0 }; + arm_rfft_fast_f32(&plan, in, out, 0); +} diff --git a/libraries/I2S/examples/InputSerialPlotter/.metro_m0.test.only b/libraries/I2S/examples/InputSerialPlotter/.metro_m0.test.only new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/I2S/examples/SimpleTone/.metro_m0.test.only b/libraries/I2S/examples/SimpleTone/.metro_m0.test.only new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/I2S/src/I2S.cpp b/libraries/I2S/src/I2S.cpp index 9f86a4138..00837e202 100644 --- a/libraries/I2S/src/I2S.cpp +++ b/libraries/I2S/src/I2S.cpp @@ -20,12 +20,29 @@ #include #include "utility/DMA.h" + +#if defined(__SAMD51__) + +#include "utility/SAMD51_I2SDevice.h" + +static I2SDevice_SAMD51 i2sd(*I2S); + +#else + #include "utility/SAMD21_I2SDevice.h" static I2SDevice_SAMD21G18x i2sd(*I2S); +#endif + #include "I2S.h" +#ifdef USE_TINYUSB +// For Serial when selecting TinyUSB +#include +#endif + + int I2SClass::_beginCount = 0; I2SClass::I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, uint8_t sckPin, uint8_t fsPin) : @@ -98,7 +115,11 @@ int I2SClass::begin(int mode, long sampleRate, int bitsPerSample, bool driveCloc if (_beginCount == 0) { // enable the I2S interface +#if defined(__SAMD51__) + MCLK->APBDMASK.reg |= MCLK_APBDMASK_I2S; +#else PM->APBCMASK.reg |= PM_APBCMASK_I2S; +#endif // reset the device i2sd.reset(); @@ -176,7 +197,11 @@ void I2SClass::end() i2sd.disable(); // disable the I2S interface +#if defined(__SAMD51__) + MCLK->APBDMASK.reg &= ~(MCLK_APBDMASK_I2S); +#else PM->APBCMASK.reg &= ~PM_APBCMASK_I2S; +#endif } } diff --git a/libraries/I2S/src/utility/DMA.cpp b/libraries/I2S/src/utility/DMA.cpp index 74eb58d48..45b166650 100644 --- a/libraries/I2S/src/utility/DMA.cpp +++ b/libraries/I2S/src/utility/DMA.cpp @@ -39,9 +39,14 @@ DMAClass::~DMAClass() void DMAClass::begin() { if (_beginCount == 0) { + +#if defined(__SAMD51__) + MCLK->AHBMASK.bit.DMAC_ = 1; +#else // enable the DMA interface PM->AHBMASK.bit.DMAC_ = 1; PM->APBBMASK.bit.DMAC_ = 1; +#endif // perform a reset DMAC->CTRL.bit.SWRST = 1; @@ -57,9 +62,35 @@ void DMAClass::begin() DMAC->CTRL.bit.LVLEN3 = 1; DMAC->CTRL.bit.DMAENABLE = 1; - // enable the interrupt at lowest priority +#if defined(__SAMD51__) + NVIC_DisableIRQ(DMAC_0_IRQn); + NVIC_ClearPendingIRQ(DMAC_0_IRQn); + NVIC_EnableIRQ(DMAC_0_IRQn); + NVIC_SetPriority(DMAC_0_IRQn, (1 << __NVIC_PRIO_BITS) - 1); + + NVIC_DisableIRQ(DMAC_1_IRQn); + NVIC_ClearPendingIRQ(DMAC_1_IRQn); + NVIC_EnableIRQ(DMAC_1_IRQn); + NVIC_SetPriority(DMAC_1_IRQn, (1 << __NVIC_PRIO_BITS) - 1); + + NVIC_DisableIRQ(DMAC_2_IRQn); + NVIC_ClearPendingIRQ(DMAC_2_IRQn); + NVIC_EnableIRQ(DMAC_2_IRQn); + NVIC_SetPriority(DMAC_2_IRQn, (1 << __NVIC_PRIO_BITS) - 1); + + NVIC_DisableIRQ(DMAC_3_IRQn); + NVIC_ClearPendingIRQ(DMAC_3_IRQn); + NVIC_EnableIRQ(DMAC_3_IRQn); + NVIC_SetPriority(DMAC_3_IRQn, (1 << __NVIC_PRIO_BITS) - 1); + + NVIC_DisableIRQ(DMAC_4_IRQn); + NVIC_ClearPendingIRQ(DMAC_4_IRQn); + NVIC_EnableIRQ(DMAC_4_IRQn); + NVIC_SetPriority(DMAC_4_IRQn, (1 << __NVIC_PRIO_BITS) - 1); +#else NVIC_EnableIRQ(DMAC_IRQn); NVIC_SetPriority(DMAC_IRQn, (1 << __NVIC_PRIO_BITS) - 1); +#endif } _beginCount++; @@ -71,14 +102,27 @@ void DMAClass::end() if (_beginCount == 0) { // disable the interrupt +#if defined(__SAMD51__) + NVIC_DisableIRQ(DMAC_0_IRQn); + NVIC_DisableIRQ(DMAC_1_IRQn); + NVIC_DisableIRQ(DMAC_2_IRQn); + NVIC_DisableIRQ(DMAC_3_IRQn); + NVIC_DisableIRQ(DMAC_4_IRQn); +#else NVIC_DisableIRQ(DMAC_IRQn); +#endif // disable DMAC->CTRL.bit.DMAENABLE = 0; // disable the DMA interface - PM->APBBMASK.bit.DMAC_ = 0; +#if defined(__SAMD51__) + MCLK->AHBMASK.bit.DMAC_ = 0; +#else + // enable the DMA interface PM->AHBMASK.bit.DMAC_ = 0; + PM->APBBMASK.bit.DMAC_ = 0; +#endif } } @@ -96,9 +140,14 @@ int DMAClass::allocateChannel() memset((void*)&_descriptors[i], 0x00, sizeof(_descriptors[i])); // select the channel and reset it +#if defined(__SAMD51__) + DMAC->Channel[i].CHCTRLA.bit.ENABLE = 0; + DMAC->Channel[i].CHCTRLA.bit.SWRST = 1; +#else DMAC->CHID.bit.ID = i; DMAC->CHCTRLA.bit.ENABLE = 0; DMAC->CHCTRLA.bit.SWRST = 1; +#endif channel = i; break; @@ -111,8 +160,12 @@ int DMAClass::allocateChannel() void DMAClass::freeChannel(int channel) { // select the channel and disable it - DMAC->CHID.bit.ID = channel; - DMAC->CHCTRLA.bit.ENABLE = 0; +#if defined(__SAMD51__) + DMAC->Channel[channel].CHCTRLA.bit.ENABLE = 0; +#else + DMAC->CHID.bit.ID = channel; + DMAC->CHCTRLA.bit.ENABLE = 0; +#endif _channelMask &= ~(1 << channel); } @@ -120,12 +173,21 @@ void DMAClass::freeChannel(int channel) void DMAClass::setPriorityLevel(int channel, int level) { // select the channel and set priority level - DMAC->CHID.bit.ID = channel; - DMAC->CHCTRLB.bit.LVL = level; +#if defined(__SAMD51__) + + DMAC->Channel[channel].CHPRILVL.reg = level; +#else + DMAC->CHID.bit.ID = channel; + DMAC->CHCTRLB.bit.LVL = level; +#endif } void DMAClass::setTriggerSource(int channel, int source) { +#if defined(__SAMD51__) + DMAC->Channel[channel].CHCTRLA.bit.TRIGSRC = source; + DMAC->Channel[channel].CHCTRLA.bit.TRIGACT = DMAC_CHCTRLA_TRIGACT_BLOCK_Val; +#else // select the channel and set a trigger source DMAC->CHID.bit.ID = channel; DMAC->CHCTRLB.bit.TRIGSRC = source; @@ -136,6 +198,7 @@ void DMAClass::setTriggerSource(int channel, int source) } else { DMAC->CHCTRLB.bit.TRIGACT = DMAC_CHCTRLB_TRIGACT_BLOCK_Val; } +#endif } void DMAClass::setTransferWidth(int channel, int transferWidth) @@ -178,8 +241,11 @@ int DMAClass::transfer(int channel, void* src, void* dst, uint16_t size) return 1; } + +#if !defined(__SAMD51__) // select the channel DMAC->CHID.bit.ID = channel; +#endif // disable event output generation and block actions _descriptors[channel].BTCTRL.bit.EVOSEL = DMAC_BTCTRL_EVOSEL_DISABLE_Val; @@ -223,16 +289,26 @@ int DMAClass::transfer(int channel, void* src, void* dst, uint16_t size) // validate the descriptor _descriptors[channel].BTCTRL.bit.VALID = 1; +#if defined(__SAMD51__) + DMAC->Channel[channel].CHINTENSET.bit.TERR = 1; + DMAC->Channel[channel].CHINTENSET.bit.TCMPL = 1; + DMAC->Channel[channel].CHCTRLA.bit.ENABLE = 1; + + if (DMAC->Channel[channel].CHCTRLA.bit.TRIGSRC == 0) { + // uses software trigger, so trigger it + DMAC->SWTRIGCTRL.reg |= (1 << channel); + } +#else // enable channel and transfer error + complete interrupts DMAC->CHINTENSET.bit.TERR = 1; DMAC->CHINTENSET.bit.TCMPL = 1; DMAC->CHCTRLA.bit.ENABLE = 1; - if (DMAC->CHCTRLB.bit.TRIGSRC == 0) { // uses software trigger, so trigger it DMAC->SWTRIGCTRL.reg |= (1 << channel); } +#endif return 0; } @@ -251,11 +327,32 @@ void DMAClass::onService() { // get the channel and select it int channel = DMAC->INTPEND.bit.ID; +#if !defined(__SAMD51__) DMAC->CHID.bit.ID = channel; +#endif // invalidate the channel _descriptors[channel].BTCTRL.bit.VALID = 0; +#if defined(__SAMD51__) + if (DMAC->Channel[channel].CHINTFLAG.bit.TERR) { + // clear the error interrupt and call the error callback if there is one + DMAC->Channel[channel].CHINTFLAG.bit.TERR = 1; + + if (_transferErrorCallbacks[channel]) { + _transferErrorCallbacks[channel](channel); + } + } + + if (DMAC->Channel[channel].CHINTFLAG.bit.TCMPL) { + // clear the complete interrupt and call the callback if there is one + DMAC->Channel[channel].CHINTFLAG.bit.TCMPL = 1; + + if (_transferCompleteCallbacks[channel]) { + _transferCompleteCallbacks[channel](channel); + } + } +#else if (DMAC->CHINTFLAG.bit.TERR) { // clear the error interrupt and call the error callback if there is one DMAC->CHINTFLAG.bit.TERR = 1; @@ -273,12 +370,55 @@ void DMAClass::onService() _transferCompleteCallbacks[channel](channel); } } +#endif } extern "C" { +#if defined(__SAMD51__) + static void _dmac_handler(void) +{ + DMA.onService(); +} +/** +* \brief DMAC interrupt handler +*/ +void DMAC_0_Handler(void) +{ + _dmac_handler(); +} +/** +* \brief DMAC interrupt handler +*/ +void DMAC_1_Handler(void) +{ + _dmac_handler(); +} +/** +* \brief DMAC interrupt handler +*/ +void DMAC_2_Handler(void) +{ + _dmac_handler(); +} +/** +* \brief DMAC interrupt handler +*/ +void DMAC_3_Handler(void) +{ + _dmac_handler(); +} +/** +* \brief DMAC interrupt handler +*/ +void DMAC_4_Handler(void) +{ + _dmac_handler(); +} +#else void DMAC_Handler() { DMA.onService(); } +#endif } DMAClass DMA; diff --git a/libraries/I2S/src/utility/DMA.h b/libraries/I2S/src/utility/DMA.h index 19b7b6250..4368eeae1 100644 --- a/libraries/I2S/src/utility/DMA.h +++ b/libraries/I2S/src/utility/DMA.h @@ -17,7 +17,11 @@ */ #pragma once +#if defined(__SAMD51__) +#define NUM_DMA_CHANNELS 4 +#else #define NUM_DMA_CHANNELS 1 +#endif /* WARNING: The API for this class may change and it's not intended for public use! diff --git a/libraries/I2S/src/utility/SAMD51_I2SDevice.h b/libraries/I2S/src/utility/SAMD51_I2SDevice.h new file mode 100644 index 000000000..ba0320afe --- /dev/null +++ b/libraries/I2S/src/utility/SAMD51_I2SDevice.h @@ -0,0 +1,229 @@ +/* + Copyright (c) 2016 Arduino LLC. 2017 Adafruit All right reserved. + + 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 +*/ + +#pragma once + +#include + +class I2SDevice_SAMD51 { +public: + I2SDevice_SAMD51(I2s& _i2s) : + i2s(_i2s) + { + // Empty + } + + inline void reset() { + while(i2s.SYNCBUSY.bit.SWRST); + i2s.CTRLA.bit.SWRST = 1; + } + + inline void disable() { + while(i2s.SYNCBUSY.bit.ENABLE); + i2s.CTRLA.bit.ENABLE = 0; + } + + inline void enable() { + while(i2s.SYNCBUSY.bit.ENABLE); + i2s.CTRLA.bit.ENABLE = 1; + } + + inline int glckId(int index) { + return (index == 0) ? I2S_GCLK_ID_0 : I2S_GCLK_ID_1; + } + + inline void setSerialClockSelectMasterClockDiv(int index) { + i2s.CLKCTRL[index].bit.SCKSEL = I2S_CLKCTRL_SCKSEL_MCKDIV_Val; + } + + inline void setSerialClockSelectPin(int index) { + i2s.CLKCTRL[index].bit.SCKSEL = I2S_CLKCTRL_SCKSEL_SCKPIN_Val; + } + + inline void setFrameSyncSelectSerialClockDiv(int index) { + i2s.CLKCTRL[index].bit.FSSEL = I2S_CLKCTRL_FSSEL_SCKDIV_Val; + } + + inline void setFrameSyncSelectPin(int index) { + i2s.CLKCTRL[index].bit.FSSEL = I2S_CLKCTRL_FSSEL_FSPIN_Val; + } + + inline void set0BitDelay(int index) { + i2s.CLKCTRL[index].bit.BITDELAY = I2S_CLKCTRL_BITDELAY_LJ_Val; + } + + inline void set1BitDelay(int index) { + i2s.CLKCTRL[index].bit.BITDELAY = I2S_CLKCTRL_BITDELAY_I2S_Val; + } + + inline void setNumberOfSlots(int index, int nbslots) { + i2s.CLKCTRL[index].bit.NBSLOTS = nbslots; + } + + inline void setSlotSize(int index, int size) { + switch (size) { + case 32: + i2s.CLKCTRL[index].bit.SLOTSIZE = I2S_CLKCTRL_SLOTSIZE_32_Val; + break; + + case 24: + i2s.CLKCTRL[index].bit.SLOTSIZE = I2S_CLKCTRL_SLOTSIZE_24_Val; + break; + + case 16: + i2s.CLKCTRL[index].bit.SLOTSIZE = I2S_CLKCTRL_SLOTSIZE_16_Val; + break; + + case 8: + i2s.CLKCTRL[index].bit.SLOTSIZE = I2S_CLKCTRL_SLOTSIZE_8_Val; + break; + } + } + + inline void setDataSize(int index, int size) { + switch (size) { + case 32: + i2s.RXCTRL.bit.DATASIZE = I2S_RXCTRL_DATASIZE_32_Val; + i2s.TXCTRL.bit.DATASIZE = I2S_TXCTRL_DATASIZE_32_Val; + break; + + case 24: + i2s.RXCTRL.bit.DATASIZE = I2S_RXCTRL_DATASIZE_24_Val; + i2s.TXCTRL.bit.DATASIZE = I2S_TXCTRL_DATASIZE_24_Val; + break; + + case 16: + i2s.RXCTRL.bit.DATASIZE = I2S_RXCTRL_DATASIZE_16_Val; + i2s.TXCTRL.bit.DATASIZE = I2S_TXCTRL_DATASIZE_16_Val; + break; + + case 8: + i2s.RXCTRL.bit.DATASIZE = I2S_RXCTRL_DATASIZE_8_Val; + i2s.TXCTRL.bit.DATASIZE = I2S_TXCTRL_DATASIZE_8_Val; + break; + } + } + + inline void setSlotAdjustedRight(int index) { + i2s.RXCTRL.bit.SLOTADJ = I2S_RXCTRL_SLOTADJ_RIGHT_Val; + i2s.TXCTRL.bit.SLOTADJ = I2S_TXCTRL_SLOTADJ_RIGHT_Val; + } + + inline void setSlotAdjustedLeft(int index) { + i2s.RXCTRL.bit.SLOTADJ = I2S_RXCTRL_SLOTADJ_LEFT_Val; + i2s.TXCTRL.bit.SLOTADJ = I2S_TXCTRL_SLOTADJ_LEFT_Val; + } + + inline void setClockUnit(int index) { + i2s.RXCTRL.bit.CLKSEL = (index == 0) ? I2S_RXCTRL_CLKSEL_CLK0_Val : I2S_RXCTRL_CLKSEL_CLK1_Val; + } + + inline void setTxMode(int index) { + i2s.RXCTRL.bit.SERMODE = 0x01; + i2s.TXCTRL.reg &= ~(0x03); //TODO: why is this not in CMSIS... + i2s.TXCTRL.reg |= 0x01; + } + + inline void setRxMode(int index) { + i2s.RXCTRL.bit.SERMODE = 0x00; + i2s.TXCTRL.reg &= ~(0x03); //TODO: why is this not in CMSIS... + i2s.TXCTRL.reg |= 0x00; + } + + inline void enableClockUnit(int index) { + if (index == 0) { + while(i2s.SYNCBUSY.bit.CKEN0); + i2s.CTRLA.bit.CKEN0 = 1; + } else { + while(i2s.SYNCBUSY.bit.CKEN1); + i2s.CTRLA.bit.CKEN1 = 1; + } + } + + inline void disableClockUnit(int index) { + if (index == 0) { + while(i2s.SYNCBUSY.bit.CKEN0); + i2s.CTRLA.bit.CKEN0 = 0; + } else { + while(i2s.SYNCBUSY.bit.CKEN1); + i2s.CTRLA.bit.CKEN1 = 0; + } + } + + inline void enableSerializer(int index) { + i2s.CTRLA.bit.RXEN = 1; + i2s.CTRLA.bit.TXEN = 1; + } + + inline void disableSerializer(int index) { + i2s.CTRLA.bit.RXEN = 0; + i2s.CTRLA.bit.TXEN = 0; + } + + inline int dmaTriggerSource(int index) { + /* + if (i2s.SERCTRL[index].bit.SERMODE == I2S_SERCTRL_SERMODE_TX_Val) { + return (index == 0) ? I2S_DMAC_ID_TX_0 : I2S_DMAC_ID_TX_1; + } else { + return (index == 0) ? I2S_DMAC_ID_RX_0 : I2S_DMAC_ID_RX_1; + } + */ + } + + inline int txReady(int index) { + return (index == 0) ? i2s.INTFLAG.bit.TXRDY0 :i2s.INTFLAG.bit.TXRDY1; + } + + inline void writeData(int index, int32_t value) { + while (i2s.SYNCBUSY.bit.TXDATA); + + i2s.TXDATA.bit.DATA = value; + } + + inline void clearTxReady(int index) { + if (index == 0) { + i2s.INTFLAG.bit.TXRDY0 = 1; + } else { + i2s.INTFLAG.bit.TXRDY1 = 1; + } + } + + inline int rxReady(int index) { + return (index == 0) ? i2s.INTFLAG.bit.RXRDY0 :i2s.INTFLAG.bit.RXRDY1; + } + + inline int32_t readData(int index) { + while(i2s.SYNCBUSY.bit.RXDATA) + return i2s.RXDATA.bit.DATA; + } + + inline void clearRxReady(int index) { + if (index == 0) { + i2s.INTFLAG.bit.RXRDY0 = 1; + } else { + i2s.INTFLAG.bit.RXRDY1 = 1; + } + } + + inline void* data(int index) { + return (void*)&i2s.RXDATA.reg; + } + +private: + volatile I2s &i2s; +}; diff --git a/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp b/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp index 1681b0a43..e39ab43e3 100644 --- a/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp +++ b/libraries/SAMD_AnalogCorrection/src/SAMD_AnalogCorrection.cpp @@ -1,5 +1,6 @@ /* Copyright (c) 2015 Arduino LLC. All right reserved. + SAMD51 support added by Adafruit - Copyright (c) 2018 Dean Miller for Adafruit Industries This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -18,14 +19,30 @@ #include "SAMD_AnalogCorrection.h" +#ifdef USE_TINYUSB +// For Serial when selecting TinyUSB +#include +#endif + void analogReadCorrection (int offset, uint16_t gain) { + Adc *adc; +#if defined (__SAMD51__) +adc = ADC0; +#else +adc = ADC; +#endif // Set correction values - ADC->OFFSETCORR.reg = ADC_OFFSETCORR_OFFSETCORR(offset); - ADC->GAINCORR.reg = ADC_GAINCORR_GAINCORR(gain); + adc->OFFSETCORR.reg = ADC_OFFSETCORR_OFFSETCORR(offset); + adc->GAINCORR.reg = ADC_GAINCORR_GAINCORR(gain); // Enable digital correction logic - ADC->CTRLB.bit.CORREN = 1; - while(ADC->STATUS.bit.SYNCBUSY); + adc->CTRLB.bit.CORREN = 1; + +#if defined (__SAMD51__) + while(adc->SYNCBUSY.bit.OFFSETCORR || adc->SYNCBUSY.bit.GAINCORR); +#else + while(adc->STATUS.bit.SYNCBUSY); +#endif } diff --git a/libraries/SDU/examples/Usage/.metro_m0.test.only b/libraries/SDU/examples/Usage/.metro_m0.test.only new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/SDU/extras/SDUBoot/.metro_m0.test.only b/libraries/SDU/extras/SDUBoot/.metro_m0.test.only new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/SPI/SPI.cpp b/libraries/SPI/SPI.cpp index d154e3671..0393752d7 100644 --- a/libraries/SPI/SPI.cpp +++ b/libraries/SPI/SPI.cpp @@ -22,6 +22,11 @@ #include #include +#ifdef USE_TINYUSB +// For Serial when selecting TinyUSB +#include +#endif + #define SPI_IMODE_NONE 0 #define SPI_IMODE_EXTINT 1 #define SPI_IMODE_GLOBAL 2 @@ -46,7 +51,16 @@ SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint void SPIClass::begin() { - init(); + if(!initialized) { + interruptMode = SPI_IMODE_NONE; + interruptSave = 0; + interruptMask = 0; + initialized = true; + } + + if(!use_dma) { + dmaAllocate(); + } // PIO init pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType); @@ -56,16 +70,6 @@ void SPIClass::begin() config(DEFAULT_SPI_SETTINGS); } -void SPIClass::init() -{ - if (initialized) - return; - interruptMode = SPI_IMODE_NONE; - interruptSave = 0; - interruptMask = 0; - initialized = true; -} - void SPIClass::config(SPISettings settings) { _p_sercom->disableSPI(); @@ -80,6 +84,7 @@ void SPIClass::end() { _p_sercom->resetSPI(); initialized = false; + // Add DMA deallocation here } #ifndef interruptsStatus @@ -198,7 +203,7 @@ void SPIClass::setDataMode(uint8_t mode) void SPIClass::setClockDivider(uint8_t div) { - if (div < SPI_MIN_CLOCK_DIVIDER) { + if(div < SPI_MIN_CLOCK_DIVIDER) { _p_sercom->setBaudrateSPI(SPI_MIN_CLOCK_DIVIDER); } else { _p_sercom->setBaudrateSPI(div); @@ -235,6 +240,239 @@ void SPIClass::transfer(void *buf, size_t count) } } +// DMA-based SPI transfer() function --------------------------------------- + +// IMPORTANT: references to 65535 throughout the DMA code are INTENTIONAL. +// DO NOT try to 'fix' by changing to 65536, or large transfers will fail! +// The BTCNT value of a DMA descriptor is an unsigned 16-bit value with a +// max of 65535. Larger transfers are handled by linked descriptors. + +// Pointer to SPIClass object, one per DMA channel. This allows the +// DMA callback (which has to exist outside the class context) to have +// a reference back to the originating SPIClass object. +static SPIClass *spiPtr[DMAC_CH_NUM] = { 0 }; // Legit inits list to NULL + +void SPIClass::dmaCallback(Adafruit_ZeroDMA *dma) { + // dmaCallback() receives an Adafruit_ZeroDMA object. From this we can get + // a channel number (0 to DMAC_CH_NUM-1, always unique per ZeroDMA object), + // then locate the originating SPIClass object using array lookup, setting + // the dma_busy element 'false' to indicate end of transfer. Doesn't matter + // if it's a read or write transfer...both channels get pointers to it. + spiPtr[dma->getChannel()]->dma_busy = false; +} + +// For read-only and read+write transfers, a callback is assigned only +// to the read channel to indicate end-of-transfer, and the write channel's +// callback is assigned to this nonsense function (for reasons I'm not +// entirely sure of, setting the callback to NULL doesn't work). +static void dmaDoNothingCallback(Adafruit_ZeroDMA *dma) { (void)dma; } + +// This could've gone in begin(), but for the sake of organization... +void SPIClass::dmaAllocate(void) { + // In order to support fully non-blocking SPI transfers, DMA descriptor + // lists must be created for the input and/or output data. Rather than + // do this dynamically with every transfer, the lists are allocated once + // on SPI init. Maximum list size is finite and knowable -- transfers to + // or from RAM or from flash memory will never exceed the corresponding + // memory size (if they do, you have bigger problems). Descriptors + // aren't large and there's usually only a handful to a dozen, so this + // isn't an excessive burden in exchange for big non-blocking transfers. + uint32_t maxWriteBytes = FLASH_SIZE; // Writes can't exceed all of flash +#if defined(__SAMD51__) + uint32_t maxReadBytes = HSRAM_SIZE; // Reads can't exceed all of RAM +#else + uint32_t maxReadBytes = HMCRAMC0_SIZE; +#endif + if(maxReadBytes > maxWriteBytes) { // I don't think any SAMD devices + maxWriteBytes = maxReadBytes; // have RAM > flash, but just in case + } + + // VITAL to alloc read channel first, assigns it a higher DMA priority! + if(readChannel.allocate() == DMA_STATUS_OK) { + if(writeChannel.allocate() == DMA_STATUS_OK) { + + // Both DMA channels (read and write) allocated successfully, + // set up transfer triggers and other basics... + + // readChannel callback only needs to be set up once. + // Unlike the write callback which may get switched on or off, + // read callback stays put. In certain cases the read DMA job + // just isn't started and the callback is a non-issue then. + readChannel.setTrigger(getDMAC_ID_RX()); + readChannel.setAction(DMA_TRIGGER_ACTON_BEAT); + readChannel.setCallback(dmaCallback); + spiPtr[readChannel.getChannel()] = this; + + writeChannel.setTrigger(getDMAC_ID_TX()); + writeChannel.setAction(DMA_TRIGGER_ACTON_BEAT); + spiPtr[writeChannel.getChannel()] = this; + + // One descriptor per channel has already been allocated + // in Adafruit_ZeroDMA, this just gets pointers to them... + firstReadDescriptor = readChannel.addDescriptor( + (void *)getDataRegister(), // Source address (SPI data reg) + NULL, // Dest address (set later) + 0, // Count (set later) + DMA_BEAT_SIZE_BYTE, // Bytes/hwords/words + false, // Don't increment source address + true); // Increment dest address + firstWriteDescriptor = writeChannel.addDescriptor( + NULL, // Source address (set later) + (void *)getDataRegister(), // Dest (SPI data register) + 0, // Count (set later) + DMA_BEAT_SIZE_BYTE, // Bytes/hwords/words + true, // Increment source address + false); // Don't increment dest address + // This is the number of EXTRA descriptors beyond the first. + int numReadDescriptors = ((maxReadBytes + 65534) / 65535) - 1; + int numWriteDescriptors = ((maxWriteBytes + 65534) / 65535) - 1; + int totalDescriptors = numReadDescriptors + numWriteDescriptors; + + if(totalDescriptors <= 0) { // Don't need extra descriptors, + use_dma = true; // channels are allocated, we're good. + } else { // Else allocate extra descriptor lists... + // Although DMA descriptors are technically a linked list, we just + // allocate a chunk all at once, and finesse the pointers later. + if((extraReadDescriptors = (DmacDescriptor *)malloc( + totalDescriptors * sizeof(DmacDescriptor)))) { + use_dma = true; // Everything allocated successfully + extraWriteDescriptors = &extraReadDescriptors[numReadDescriptors]; + + // Initialize descriptors (copy from first ones) + // cast to void* to suppress warning: with no trivial copy-assignment [-Wclass-memaccess] + for(int i=0; i 65535) { // Limit each descriptor + bytesThisDescriptor = 65535; // to 65535 (not 65536) bytes + } + rDesc->BTCNT.reg = wDesc->BTCNT.reg = bytesThisDescriptor; + if(rxbuf) { // Read-only or read+write + // Auto-inc addresses in DMA descriptors must point to END of data. + // Buf pointers would advance at end of loop anyway, do it now... + rxbuf8 += bytesThisDescriptor; + rDesc->DSTADDR.reg = (uint32_t)rxbuf8; + } + if(txbuf) { // Write-only or read+write + txbuf8 += bytesThisDescriptor; // Same as above + wDesc->SRCADDR.reg = (uint32_t)txbuf8; + wDesc->BTCTRL.bit.SRCINC = 1; // Increment source pointer + } else { // Read-only requires dummy write + wDesc->SRCADDR.reg = (uint32_t)&dum; + wDesc->BTCTRL.bit.SRCINC = 0; // Don't increment source pointer + } + count -= bytesThisDescriptor; + if(count) { // Still more data? + // Link to next descriptors. Extra descriptors are IN ADDITION + // to first, so it's safe and correct that descIdx starts at 0. + rDesc->DESCADDR.reg = (uint32_t)&extraReadDescriptors[descIdx]; + wDesc->DESCADDR.reg = (uint32_t)&extraWriteDescriptors[descIdx]; + rDesc = &extraReadDescriptors[descIdx]; // Update pointers to + wDesc = &extraWriteDescriptors[descIdx]; // next descriptors + descIdx++; + // A write-only transfer doesn't use the read descriptor list, but + // it's quicker to build it (full of nonsense) anyway than to check. + } else { // No more data, end descriptor linked lists + rDesc->DESCADDR.reg = wDesc->DESCADDR.reg = 0; + } + } + + // Set up DMA transfer job(s) ------------------------------------------ + + if(rxbuf) { // Read+write or read-only + // End-of-read callback is already set up, disable write CB, start job + writeChannel.setCallback(dmaDoNothingCallback); + readChannel.startJob(); + } else { // Write-only, use end-of-write callback + writeChannel.setCallback(dmaCallback); + } + + // Run DMA jobs, blocking if requested --------------------------------- + + dma_busy = true; + writeChannel.startJob(); // All xfers, even read-only, need write job. + if(block) { // If blocking transfer requested, + while(dma_busy); // wait for job to finish + } + + } else { // NON-DMA FALLBACK --------------------------------------------- + + if(txbuf8) { + if(rxbuf8) { // Write + read simultaneously + while(count--) { + *rxbuf8++ = _p_sercom->transferDataSPI(*txbuf8++); + } + } else { // Write only + while(count--) { + (void)_p_sercom->transferDataSPI(*txbuf8++); + } + } + } else { // Read only + while(count--) { + *rxbuf8++ = _p_sercom->transferDataSPI(0xFF); + } + } + + } // end non-DMA +} + +// Waits for a prior in-background DMA transfer to complete. +void SPIClass::waitForTransfer(void) { + while(dma_busy); +} + +/* returns the current DMA transfer status to allow non-blocking polling */ +bool SPIClass::isBusy(void) { + return dma_busy; +} + + +// End DMA-based SPI transfer() code --------------------------------------- + void SPIClass::attachInterrupt() { // Should be enableInterrupt() } @@ -243,6 +481,61 @@ void SPIClass::detachInterrupt() { // Should be disableInterrupt() } +// SPI DMA lookup works on both SAMD21 and SAMD51 + +static const struct { + volatile uint32_t *data_reg; + int dmac_id_tx; + int dmac_id_rx; +} sercomData[] = { + { &SERCOM0->SPI.DATA.reg, SERCOM0_DMAC_ID_TX, SERCOM0_DMAC_ID_RX }, + { &SERCOM1->SPI.DATA.reg, SERCOM1_DMAC_ID_TX, SERCOM1_DMAC_ID_RX }, + { &SERCOM2->SPI.DATA.reg, SERCOM2_DMAC_ID_TX, SERCOM2_DMAC_ID_RX }, + { &SERCOM3->SPI.DATA.reg, SERCOM3_DMAC_ID_TX, SERCOM3_DMAC_ID_RX }, +#if defined(SERCOM4) + { &SERCOM4->SPI.DATA.reg, SERCOM4_DMAC_ID_TX, SERCOM4_DMAC_ID_RX }, +#endif +#if defined(SERCOM5) + { &SERCOM5->SPI.DATA.reg, SERCOM5_DMAC_ID_TX, SERCOM5_DMAC_ID_RX }, +#endif +#if defined(SERCOM6) + { &SERCOM6->SPI.DATA.reg, SERCOM6_DMAC_ID_TX, SERCOM6_DMAC_ID_RX }, +#endif +#if defined(SERCOM7) + { &SERCOM7->SPI.DATA.reg, SERCOM7_DMAC_ID_TX, SERCOM7_DMAC_ID_RX }, +#endif +}; + +volatile uint32_t *SPIClass::getDataRegister(void) { + int8_t idx = _p_sercom->getSercomIndex(); + return (idx >= 0) ? sercomData[idx].data_reg: NULL; +} + +int SPIClass::getDMAC_ID_TX(void) { + int8_t idx = _p_sercom->getSercomIndex(); + return (idx >= 0) ? sercomData[idx].dmac_id_tx : -1; +} + +int SPIClass::getDMAC_ID_RX(void) { + int8_t idx = _p_sercom->getSercomIndex(); + return (idx >= 0) ? sercomData[idx].dmac_id_rx : -1; +} + +#if defined(__SAMD51__) + +// Set the SPI device's SERCOM clock CORE and SLOW clock sources. +// SercomClockSource values are an enumeration in SERCOM.h. +// This works on SAMD51 only. On SAMD21, a dummy function is declared +// in SPI.h which compiles to nothing, so user code doesn't need to check +// and conditionally compile lines for different architectures. +void SPIClass::setClockSource(SercomClockSource clk) { + int8_t idx = _p_sercom->getSercomIndex(); + _p_sercom->setClockSource(idx, clk, true); // true = set core clock + _p_sercom->setClockSource(idx, clk, false); // false = set slow clock +} + +#endif // end __SAMD51__ + #if SPI_INTERFACES_COUNT > 0 /* In case new variant doesn't define these macros, * we put here the ones for Arduino Zero. @@ -275,4 +568,3 @@ void SPIClass::detachInterrupt() { #if SPI_INTERFACES_COUNT > 5 SPIClass SPI5(&PERIPH_SPI5, PIN_SPI5_MISO, PIN_SPI5_SCK, PIN_SPI5_MOSI, PAD_SPI5_TX, PAD_SPI5_RX); #endif - diff --git a/libraries/SPI/SPI.h b/libraries/SPI/SPI.h index d4ab2d64a..7c719f695 100644 --- a/libraries/SPI/SPI.h +++ b/libraries/SPI/SPI.h @@ -21,6 +21,7 @@ #define _SPI_H_INCLUDED #include +#include // SPI_HAS_TRANSACTION means SPI has // - beginTransaction() @@ -37,12 +38,27 @@ #define SPI_MODE2 0x03 #define SPI_MODE3 0x01 -#if defined(ARDUINO_ARCH_SAMD) +#if defined(__SAMD51__) + // SAMD51 has configurable MAX_SPI, else use peripheral clock default. + // Update: changing MAX_SPI via compiler flags is DEPRECATED, because + // this affects ALL SPI peripherals including some that should NOT be + // changed (e.g. anything using SD card). Use the setClockSource() + // function instead. This is left here for compatibility with interim code. + #if !defined(MAX_SPI) + #define MAX_SPI 24000000 + #endif + #define SPI_MIN_CLOCK_DIVIDER 1 +#else // The datasheet specifies a typical SPI SCK period (tSCK) of 42 ns, // see "Table 36-48. SPI Timing Characteristics and Requirements", // which translates into a maximum SPI clock of 23.8 MHz. - // Conservatively, the divider is set for a 12 MHz maximum SPI clock. - #define SPI_MIN_CLOCK_DIVIDER (uint8_t)(1 + ((F_CPU - 1) / 12000000)) + // We'll permit use of 24 MHz SPI even though this is slightly out + // of spec. Given how clock dividers work, the next "sensible" + // threshold would be a substantial drop down to 12 MHz. + #if !defined(MAX_SPI) + #define MAX_SPI 24000000 + #endif + #define SPI_MIN_CLOCK_DIVIDER (uint8_t)(1 + ((F_CPU - 1) / MAX_SPI)) #endif class SPISettings { @@ -64,7 +80,11 @@ class SPISettings { } void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) { - this->clockFreq = (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER) ? F_CPU / SPI_MIN_CLOCK_DIVIDER : clock); +#if defined(__SAMD51__) + this->clockFreq = clock; // Clipping handled in SERCOM.cpp +#else + this->clockFreq = clock >= MAX_SPI ? MAX_SPI : clock; +#endif this->bitOrder = (bitOrder == MSBFIRST ? MSB_FIRST : LSB_FIRST); @@ -94,10 +114,13 @@ class SPIClass { public: SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad); - byte transfer(uint8_t data); uint16_t transfer16(uint16_t data); void transfer(void *buf, size_t count); + void transfer(const void* txbuf, void* rxbuf, size_t count, + bool block = true); + void waitForTransfer(void); + bool isBusy(void); // Transaction Functions void usingInterrupt(int interruptNumber); @@ -116,8 +139,21 @@ class SPIClass { void setDataMode(uint8_t uc_mode); void setClockDivider(uint8_t uc_div); + // SERCOM lookup functions are available on both SAMD51 and 21. + volatile uint32_t *getDataRegister(void); + int getDMAC_ID_TX(void); + int getDMAC_ID_RX(void); + uint8_t getSercomIndex(void) { return _p_sercom->getSercomIndex(); }; +#if defined(__SAMD51__) + // SERCOM clock source override is available only on SAMD51. + void setClockSource(SercomClockSource clk); +#else + // On SAMD21, this compiles to nothing, so user code doesn't need to + // check and conditionally compile lines for different architectures. + void setClockSource(SercomClockSource clk) { (void)clk; }; +#endif // end __SAMD51__ + private: - void init(); void config(SPISettings settings); SERCOM *_p_sercom; @@ -132,6 +168,18 @@ class SPIClass { uint8_t interruptMode; char interruptSave; uint32_t interruptMask; + + // transfer(txbuf, rxbuf, count, block) uses DMA when possible + Adafruit_ZeroDMA readChannel; + Adafruit_ZeroDMA writeChannel; + DmacDescriptor *firstReadDescriptor = NULL; // List entry point + DmacDescriptor *firstWriteDescriptor = NULL; + DmacDescriptor *extraReadDescriptors = NULL; // Add'l descriptors + DmacDescriptor *extraWriteDescriptors = NULL; + bool use_dma = false; // true on successful alloc + volatile bool dma_busy = false; + void dmaAllocate(void); + static void dmaCallback(Adafruit_ZeroDMA *dma); }; #if SPI_INTERFACES_COUNT > 0 @@ -155,14 +203,12 @@ class SPIClass { // For compatibility with sketches designed for AVR @ 16 MHz // New programs should use SPI.beginTransaction to set the SPI clock -#if F_CPU == 48000000 - #define SPI_CLOCK_DIV2 6 - #define SPI_CLOCK_DIV4 12 - #define SPI_CLOCK_DIV8 24 - #define SPI_CLOCK_DIV16 48 - #define SPI_CLOCK_DIV32 96 - #define SPI_CLOCK_DIV64 192 - #define SPI_CLOCK_DIV128 255 -#endif +#define SPI_CLOCK_DIV2 (MAX_SPI * 2 / 8000000) +#define SPI_CLOCK_DIV4 (MAX_SPI * 2 / 4000000) +#define SPI_CLOCK_DIV8 (MAX_SPI * 2 / 2000000) +#define SPI_CLOCK_DIV16 (MAX_SPI * 2 / 1000000) +#define SPI_CLOCK_DIV32 (MAX_SPI * 2 / 500000) +#define SPI_CLOCK_DIV64 (MAX_SPI * 2 / 250000) +#define SPI_CLOCK_DIV128 (MAX_SPI * 2 / 125000) #endif diff --git a/libraries/Servo/README.adoc b/libraries/Servo/README.adoc new file mode 100644 index 000000000..dd3f0bae3 --- /dev/null +++ b/libraries/Servo/README.adoc @@ -0,0 +1,25 @@ += Servo Library for Arduino = + +This library allows an Arduino board to control RC (hobby) servo motors. + +For more information about this library please visit us at +http://www.arduino.cc/en/Reference/Servo + +== License == + +Copyright (c) 2013 Arduino LLC. All right reserved. +Copyright (c) 2009 Michael Margolis. All right reserved. + +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 diff --git a/libraries/Servo/examples/Knob/Knob.ino b/libraries/Servo/examples/Knob/Knob.ino new file mode 100644 index 000000000..0db8770bd --- /dev/null +++ b/libraries/Servo/examples/Knob/Knob.ino @@ -0,0 +1,27 @@ +/* + Controlling a servo position using a potentiometer (variable resistor) + by Michal Rinott + + modified on 8 Nov 2013 + by Scott Fitzgerald + http://www.arduino.cc/en/Tutorial/Knob +*/ + +#include + +Servo myservo; // create servo object to control a servo + +int potpin = 0; // analog pin used to connect the potentiometer +int val; // variable to read the value from the analog pin + +void setup() { + myservo.attach(9); // attaches the servo on pin 9 to the servo object +} + +void loop() { + val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) + val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180) + myservo.write(val); // sets the servo position according to the scaled value + delay(15); // waits for the servo to get there +} + diff --git a/libraries/Servo/examples/Sweep/Sweep.ino b/libraries/Servo/examples/Sweep/Sweep.ino new file mode 100644 index 000000000..df904afb1 --- /dev/null +++ b/libraries/Servo/examples/Sweep/Sweep.ino @@ -0,0 +1,32 @@ +/* Sweep + by BARRAGAN + This example code is in the public domain. + + modified 8 Nov 2013 + by Scott Fitzgerald + http://www.arduino.cc/en/Tutorial/Sweep +*/ + +#include + +Servo myservo; // create servo object to control a servo +// twelve servo objects can be created on most boards + +int pos = 0; // variable to store the servo position + +void setup() { + myservo.attach(9); // attaches the servo on pin 9 to the servo object +} + +void loop() { + for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees + // in steps of 1 degree + myservo.write(pos); // tell servo to go to position in variable 'pos' + delay(15); // waits 15ms for the servo to reach the position + } + for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees + myservo.write(pos); // tell servo to go to position in variable 'pos' + delay(15); // waits 15ms for the servo to reach the position + } +} + diff --git a/libraries/Servo/keywords.txt b/libraries/Servo/keywords.txt new file mode 100644 index 000000000..0a7ca1e3d --- /dev/null +++ b/libraries/Servo/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map Servo +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Servo KEYWORD1 Servo + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +attach KEYWORD2 +detach KEYWORD2 +write KEYWORD2 +read KEYWORD2 +attached KEYWORD2 +writeMicroseconds KEYWORD2 +readMicroseconds KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/Servo/library.properties b/libraries/Servo/library.properties new file mode 100644 index 000000000..8e55e5596 --- /dev/null +++ b/libraries/Servo/library.properties @@ -0,0 +1,9 @@ +name=Servo +version=1.1.4 +author=Michael Margolis, Arduino +maintainer=Arduino +sentence=Allows Arduino/Genuino boards to control a variety of servo motors. +paragraph=This library can control a great number of servos.
It makes careful use of timers: the library can control 12 servos using only 1 timer.
On the Arduino Due you can control up to 60 servos.
+category=Device Control +url=http://www.arduino.cc/en/Reference/Servo +architectures=avr,megaavr,sam,samd,nrf52,stm32f4 diff --git a/libraries/Servo/src/Servo.h b/libraries/Servo/src/Servo.h new file mode 100644 index 000000000..a12565800 --- /dev/null +++ b/libraries/Servo/src/Servo.h @@ -0,0 +1,121 @@ +/* + Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 + Copyright (c) 2009 Michael Margolis. All right reserved. + + 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 +*/ + +/* + A servo is activated by creating an instance of the Servo class passing + the desired pin to the attach() method. + The servos are pulsed in the background using the value most recently + written using the write() method. + + Note that analogWrite of PWM on pins associated with the timer are + disabled when the first servo is attached. + Timers are seized as needed in groups of 12 servos - 24 servos use two + timers, 48 servos will use four. + The sequence used to sieze timers is defined in timers.h + + The methods are: + + Servo - Class for manipulating servo motors connected to Arduino pins. + + attach(pin ) - Attaches a servo motor to an i/o pin. + attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds + default min is 544, max is 2400 + + write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) + writeMicroseconds() - Sets the servo pulse width in microseconds + read() - Gets the last written servo pulse width as an angle between 0 and 180. + readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) + attached() - Returns true if there is a servo attached. + detach() - Stops an attached servos from pulsing its i/o pin. + */ + +#ifndef Servo_h +#define Servo_h + +#include + +/* + * Defines for 16 bit timers used with Servo library + * + * If _useTimerX is defined then TimerX is a 16 bit timer on the current board + * timer16_Sequence_t enumerates the sequence that the timers should be allocated + * _Nbr_16timers indicates how many 16 bit timers are available. + */ + +// Architecture specific include +#if defined(ARDUINO_ARCH_AVR) +#include "avr/ServoTimers.h" +#elif defined(ARDUINO_ARCH_SAM) +#include "sam/ServoTimers.h" +#elif defined(ARDUINO_ARCH_SAMD) +#include "samd/ServoTimers.h" +#elif defined(ARDUINO_ARCH_STM32F4) +#include "stm32f4/ServoTimers.h" +#elif defined(ARDUINO_ARCH_NRF52) +#include "nrf52/ServoTimers.h" +#elif defined(ARDUINO_ARCH_MEGAAVR) +#include "megaavr/ServoTimers.h" +#else +#error "This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor." +#endif + +#define Servo_VERSION 2 // software version of this library + +#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo +#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo +#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached +#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds + +#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer +#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER) + +#define INVALID_SERVO 255 // flag indicating an invalid servo index + +#if !defined(ARDUINO_ARCH_STM32F4) + +typedef struct { + uint8_t nbr :6 ; // a pin number from 0 to 63 + uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false +} ServoPin_t ; + +typedef struct { + ServoPin_t Pin; + volatile unsigned int ticks; +} servo_t; + +class Servo +{ +public: + Servo(); + uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure + uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. + void detach(); + void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds + void writeMicroseconds(int value); // Write pulse width in microseconds + int read(); // returns current pulse width as an angle between 0 and 180 degrees + int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) + bool attached(); // return true if this servo is attached, otherwise false +private: + uint8_t servoIndex; // index into the channel data for this servo + int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH + int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH +}; + +#endif +#endif diff --git a/libraries/Servo/src/avr/Servo.cpp b/libraries/Servo/src/avr/Servo.cpp new file mode 100644 index 000000000..ed7376efc --- /dev/null +++ b/libraries/Servo/src/avr/Servo.cpp @@ -0,0 +1,318 @@ +/* + Servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 + Copyright (c) 2009 Michael Margolis. All right reserved. + + 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 + */ + +#if defined(ARDUINO_ARCH_AVR) + +#include +#include + +#include "Servo.h" + +#define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009 +#define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds + + +#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009 + +//#define NBR_TIMERS (MAX_SERVOS / SERVOS_PER_TIMER) + +static servo_t servos[MAX_SERVOS]; // static array of servo structures +static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) + +uint8_t ServoCount = 0; // the total number of attached servos + + +// convenience macros +#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo +#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer +#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel +#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel + +#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo +#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo + +/************ static functions common to all instances ***********************/ + +static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t* OCRnA) +{ + if( Channel[timer] < 0 ) + *TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer + else{ + if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true ) + digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,LOW); // pulse this channel low if activated + } + + Channel[timer]++; // increment to the next channel + if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { + *OCRnA = *TCNTn + SERVO(timer,Channel[timer]).ticks; + if(SERVO(timer,Channel[timer]).Pin.isActive == true) // check if activated + digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high + } + else { + // finished all channels so wait for the refresh period to expire before starting over + if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed + *OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL); + else + *OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed + Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel + } +} + +#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform +// Interrupt handlers for Arduino +#if defined(_useTimer1) +SIGNAL (TIMER1_COMPA_vect) +{ + handle_interrupts(_timer1, &TCNT1, &OCR1A); +} +#endif + +#if defined(_useTimer3) +SIGNAL (TIMER3_COMPA_vect) +{ + handle_interrupts(_timer3, &TCNT3, &OCR3A); +} +#endif + +#if defined(_useTimer4) +SIGNAL (TIMER4_COMPA_vect) +{ + handle_interrupts(_timer4, &TCNT4, &OCR4A); +} +#endif + +#if defined(_useTimer5) +SIGNAL (TIMER5_COMPA_vect) +{ + handle_interrupts(_timer5, &TCNT5, &OCR5A); +} +#endif + +#elif defined WIRING +// Interrupt handlers for Wiring +#if defined(_useTimer1) +void Timer1Service() +{ + handle_interrupts(_timer1, &TCNT1, &OCR1A); +} +#endif +#if defined(_useTimer3) +void Timer3Service() +{ + handle_interrupts(_timer3, &TCNT3, &OCR3A); +} +#endif +#endif + + +static void initISR(timer16_Sequence_t timer) +{ +#if defined (_useTimer1) + if(timer == _timer1) { + TCCR1A = 0; // normal counting mode + TCCR1B = _BV(CS11); // set prescaler of 8 + TCNT1 = 0; // clear the timer count +#if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__) + TIFR |= _BV(OCF1A); // clear any pending interrupts; + TIMSK |= _BV(OCIE1A) ; // enable the output compare interrupt +#else + // here if not ATmega8 or ATmega128 + TIFR1 |= _BV(OCF1A); // clear any pending interrupts; + TIMSK1 |= _BV(OCIE1A) ; // enable the output compare interrupt +#endif +#if defined(WIRING) + timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service); +#endif + } +#endif + +#if defined (_useTimer3) + if(timer == _timer3) { + TCCR3A = 0; // normal counting mode + TCCR3B = _BV(CS31); // set prescaler of 8 + TCNT3 = 0; // clear the timer count +#if defined(__AVR_ATmega128__) + TIFR |= _BV(OCF3A); // clear any pending interrupts; + ETIMSK |= _BV(OCIE3A); // enable the output compare interrupt +#else + TIFR3 = _BV(OCF3A); // clear any pending interrupts; + TIMSK3 = _BV(OCIE3A) ; // enable the output compare interrupt +#endif +#if defined(WIRING) + timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only +#endif + } +#endif + +#if defined (_useTimer4) + if(timer == _timer4) { + TCCR4A = 0; // normal counting mode + TCCR4B = _BV(CS41); // set prescaler of 8 + TCNT4 = 0; // clear the timer count + TIFR4 = _BV(OCF4A); // clear any pending interrupts; + TIMSK4 = _BV(OCIE4A) ; // enable the output compare interrupt + } +#endif + +#if defined (_useTimer5) + if(timer == _timer5) { + TCCR5A = 0; // normal counting mode + TCCR5B = _BV(CS51); // set prescaler of 8 + TCNT5 = 0; // clear the timer count + TIFR5 = _BV(OCF5A); // clear any pending interrupts; + TIMSK5 = _BV(OCIE5A) ; // enable the output compare interrupt + } +#endif +} + +static void finISR(timer16_Sequence_t timer) +{ + //disable use of the given timer +#if defined WIRING // Wiring + if(timer == _timer1) { + #if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) + TIMSK1 &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt + #else + TIMSK &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt + #endif + timerDetach(TIMER1OUTCOMPAREA_INT); + } + else if(timer == _timer3) { + #if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) + TIMSK3 &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt + #else + ETIMSK &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt + #endif + timerDetach(TIMER3OUTCOMPAREA_INT); + } +#else + //For arduino - in future: call here to a currently undefined function to reset the timer + (void) timer; // squash "unused parameter 'timer' [-Wunused-parameter]" warning +#endif +} + +static boolean isTimerActive(timer16_Sequence_t timer) +{ + // returns true if any servo is active on this timer + for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { + if(SERVO(timer,channel).Pin.isActive == true) + return true; + } + return false; +} + + +/****************** end of static functions ******************************/ + +Servo::Servo() +{ + if( ServoCount < MAX_SERVOS) { + this->servoIndex = ServoCount++; // assign a servo index to this instance + servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009 + } + else + this->servoIndex = INVALID_SERVO ; // too many servos +} + +uint8_t Servo::attach(int pin) +{ + return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); +} + +uint8_t Servo::attach(int pin, int min, int max) +{ + if(this->servoIndex < MAX_SERVOS ) { + pinMode( pin, OUTPUT) ; // set servo pin to output + servos[this->servoIndex].Pin.nbr = pin; + // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 + this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS + this->max = (MAX_PULSE_WIDTH - max)/4; + // initialize the timer if it has not already been initialized + timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); + if(isTimerActive(timer) == false) + initISR(timer); + servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive + } + return this->servoIndex ; +} + +void Servo::detach() +{ + servos[this->servoIndex].Pin.isActive = false; + timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); + if(isTimerActive(timer) == false) { + finISR(timer); + } +} + +void Servo::write(int value) +{ + if(value < MIN_PULSE_WIDTH) + { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) + if(value < 0) value = 0; + if(value > 180) value = 180; + value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); + } + this->writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value) +{ + // calculate and store the values for the given channel + byte channel = this->servoIndex; + if( (channel < MAX_SERVOS) ) // ensure channel is valid + { + if( value < SERVO_MIN() ) // ensure pulse width is valid + value = SERVO_MIN(); + else if( value > SERVO_MAX() ) + value = SERVO_MAX(); + + value = value - TRIM_DURATION; + value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009 + + uint8_t oldSREG = SREG; + cli(); + servos[channel].ticks = value; + SREG = oldSREG; + } +} + +int Servo::read() // return the value as degrees +{ + return map( this->readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); +} + +int Servo::readMicroseconds() +{ + unsigned int pulsewidth; + if( this->servoIndex != INVALID_SERVO ) + pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION ; // 12 aug 2009 + else + pulsewidth = 0; + + return pulsewidth; +} + +bool Servo::attached() +{ + return servos[this->servoIndex].Pin.isActive ; +} + +#endif // ARDUINO_ARCH_AVR + diff --git a/libraries/Servo/src/avr/ServoTimers.h b/libraries/Servo/src/avr/ServoTimers.h new file mode 100644 index 000000000..9794c8ef6 --- /dev/null +++ b/libraries/Servo/src/avr/ServoTimers.h @@ -0,0 +1,59 @@ +/* + Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 + Copyright (c) 2009 Michael Margolis. All right reserved. + + 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 +*/ + +/* + * Defines for 16 bit timers used with Servo library + * + * If _useTimerX is defined then TimerX is a 16 bit timer on the current board + * timer16_Sequence_t enumerates the sequence that the timers should be allocated + * _Nbr_16timers indicates how many 16 bit timers are available. + */ + +/** + * AVR Only definitions + * -------------------- + */ + +// Say which 16 bit timers can be used and in what order +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +#define _useTimer5 +#define _useTimer1 +#define _useTimer3 +#define _useTimer4 +typedef enum { _timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t; + +#elif defined(__AVR_ATmega32U4__) +#define _useTimer1 +typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; + +#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) +#define _useTimer3 +#define _useTimer1 +typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t; + +#elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__) +#define _useTimer3 +#define _useTimer1 +typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t; + +#else // everything else +#define _useTimer1 +typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; +#endif + diff --git a/libraries/Servo/src/megaavr/Servo.cpp b/libraries/Servo/src/megaavr/Servo.cpp new file mode 100644 index 000000000..daf7596ee --- /dev/null +++ b/libraries/Servo/src/megaavr/Servo.cpp @@ -0,0 +1,211 @@ +#if defined(ARDUINO_ARCH_MEGAAVR) + +#include +#include + +#define usToTicks(_us) ((clockCyclesPerMicrosecond() / 16 * _us) / 4) // converts microseconds to tick +#define ticksToUs(_ticks) (((unsigned) _ticks * 16) / (clockCyclesPerMicrosecond() / 4)) // converts from ticks back to microseconds + +#define TRIM_DURATION 5 // compensation ticks to trim adjust for digitalWrite delays + +static servo_t servos[MAX_SERVOS]; // static array of servo structures + +uint8_t ServoCount = 0; // the total number of attached servos + +static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval) + +// convenience macros +#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo +#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer +#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel +#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel + +#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo +#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo + +void ServoHandler(int timer) +{ + if (currentServoIndex[timer] < 0) { + // Write compare register + _timer->CCMP = 0; + } else { + if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { + digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated + } + } + + // Select the next servo controlled by this timer + currentServoIndex[timer]++; + + if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) { + if (SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { // check if activated + digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high + } + + // Get the counter value + uint16_t tcCounterValue = 0; //_timer->CCMP; + _timer->CCMP = (uint16_t) (tcCounterValue + SERVO(timer, currentServoIndex[timer]).ticks); + } + else { + // finished all channels so wait for the refresh period to expire before starting over + + // Get the counter value + uint16_t tcCounterValue = _timer->CCMP; + + if (tcCounterValue + 4UL < usToTicks(REFRESH_INTERVAL)) { // allow a few ticks to ensure the next OCR1A not missed + _timer->CCMP = (uint16_t) usToTicks(REFRESH_INTERVAL); + } + else { + _timer->CCMP = (uint16_t) (tcCounterValue + 4UL); // at least REFRESH_INTERVAL has elapsed + } + + currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel + } + + /* Clear flag */ + _timer->INTFLAGS = TCB_CAPT_bm; +} + +#if defined USE_TIMERB0 +ISR(TCB0_INT_vect) +#elif defined USE_TIMERB1 +ISR(TCB1_INT_vect) +#elif defined USE_TIMERB2 +ISR(TCB2_INT_vect) +#endif +{ + ServoHandler(0); +} + +static void initISR(timer16_Sequence_t timer) +{ + //TCA0.SINGLE.CTRLA = (TCA_SINGLE_CLKSEL_DIV16_gc) | (TCA_SINGLE_ENABLE_bm); + + _timer->CTRLA = TCB_CLKSEL_CLKTCA_gc; + // Timer to Periodic interrupt mode + // This write will also disable any active PWM outputs + _timer->CTRLB = TCB_CNTMODE_INT_gc; + // Enable interrupt + _timer->INTCTRL = TCB_CAPTEI_bm; + // Enable timer + _timer->CTRLA |= TCB_ENABLE_bm; +} + +static void finISR(timer16_Sequence_t timer) +{ + // Disable interrupt + _timer->INTCTRL = 0; +} + +static boolean isTimerActive(timer16_Sequence_t timer) +{ + // returns true if any servo is active on this timer + for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { + if(SERVO(timer,channel).Pin.isActive == true) + return true; + } + return false; +} + +/****************** end of static functions ******************************/ + +Servo::Servo() +{ + if (ServoCount < MAX_SERVOS) { + this->servoIndex = ServoCount++; // assign a servo index to this instance + servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values + } else { + this->servoIndex = INVALID_SERVO; // too many servos + } +} + +uint8_t Servo::attach(int pin) +{ + return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); +} + +uint8_t Servo::attach(int pin, int min, int max) +{ + timer16_Sequence_t timer; + + if (this->servoIndex < MAX_SERVOS) { + pinMode(pin, OUTPUT); // set servo pin to output + servos[this->servoIndex].Pin.nbr = pin; + // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 + this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS + this->max = (MAX_PULSE_WIDTH - max)/4; + // initialize the timer if it has not already been initialized + timer = SERVO_INDEX_TO_TIMER(servoIndex); + if (isTimerActive(timer) == false) { + initISR(timer); + } + servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive + } + return this->servoIndex; +} + +void Servo::detach() +{ + timer16_Sequence_t timer; + + servos[this->servoIndex].Pin.isActive = false; + timer = SERVO_INDEX_TO_TIMER(servoIndex); + if(isTimerActive(timer) == false) { + finISR(timer); + } +} + +void Servo::write(int value) +{ + // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) + if (value < MIN_PULSE_WIDTH) + { + if (value < 0) + value = 0; + else if (value > 180) + value = 180; + + value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); + } + writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value) +{ + // calculate and store the values for the given channel + byte channel = this->servoIndex; + if( (channel < MAX_SERVOS) ) // ensure channel is valid + { + if (value < SERVO_MIN()) // ensure pulse width is valid + value = SERVO_MIN(); + else if (value > SERVO_MAX()) + value = SERVO_MAX(); + + value = value - TRIM_DURATION; + value = usToTicks(value); // convert to ticks after compensating for interrupt overhead + servos[channel].ticks = value; + } +} + +int Servo::read() // return the value as degrees +{ + return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); +} + +int Servo::readMicroseconds() +{ + unsigned int pulsewidth; + if (this->servoIndex != INVALID_SERVO) + pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; + else + pulsewidth = 0; + + return pulsewidth; +} + +bool Servo::attached() +{ + return servos[this->servoIndex].Pin.isActive; +} + +#endif \ No newline at end of file diff --git a/libraries/Servo/src/megaavr/ServoTimers.h b/libraries/Servo/src/megaavr/ServoTimers.h new file mode 100644 index 000000000..62702b4f9 --- /dev/null +++ b/libraries/Servo/src/megaavr/ServoTimers.h @@ -0,0 +1,54 @@ +/* + Copyright (c) 2018 Arduino LLC. All right reserved. + + 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 +*/ + +/* + * Defines for 16 bit timers used with Servo library + * + */ + +#ifndef __SERVO_TIMERS_H__ +#define __SERVO_TIMERS_H__ + +#include + +#define USE_TIMERB1 // interferes with PWM on pin 3 +//#define USE_TIMERB2 // interferes with PWM on pin 11 +//#define USE_TIMERB0 // interferes with PWM on pin 6 + +#if !defined(USE_TIMERB1) && !defined(USE_TIMERB2) && !defined(USE_TIMERB0) + # error "No timers allowed for Servo" + /* Please uncomment a timer above and rebuild */ +#endif + +static volatile TCB_t* _timer = +#if defined(USE_TIMERB0) +&TCB0; +#endif +#if defined(USE_TIMERB1) +&TCB1; +#endif +#if defined(USE_TIMERB2) +&TCB2; +#endif + +typedef enum { + timer0, + _Nbr_16timers } timer16_Sequence_t; + + +#endif /* __SERVO_TIMERS_H__ */ diff --git a/libraries/Servo/src/nrf52/Servo.cpp b/libraries/Servo/src/nrf52/Servo.cpp new file mode 100644 index 000000000..a49f09342 --- /dev/null +++ b/libraries/Servo/src/nrf52/Servo.cpp @@ -0,0 +1,134 @@ +/* + Copyright (c) 2016 Arduino. All right reserved. + + 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 +*/ + +#if defined(ARDUINO_ARCH_NRF52) + +#include +#include + + +static servo_t servos[MAX_SERVOS]; // static array of servo structures + +uint8_t ServoCount = 0; // the total number of attached servos + + + +uint32_t group_pins[3][NRF_PWM_CHANNEL_COUNT]={{NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}}; +static uint16_t seq_values[3][NRF_PWM_CHANNEL_COUNT]={{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}; + +Servo::Servo() +{ + if (ServoCount < MAX_SERVOS) { + this->servoIndex = ServoCount++; // assign a servo index to this instance + } else { + this->servoIndex = INVALID_SERVO; // too many servos + } + +} + +uint8_t Servo::attach(int pin) +{ + + return this->attach(pin, 0, 2500); +} + + +uint8_t Servo::attach(int pin, int min, int max) +{ + int servo_min, servo_max; + if (this->servoIndex < MAX_SERVOS) { + pinMode(pin, OUTPUT); // set servo pin to output + servos[this->servoIndex].Pin.nbr = pin; + + if(min < servo_min) min = servo_min; + if (max > servo_max) max = servo_max; + this->min = min; + this->max = max; + + servos[this->servoIndex].Pin.isActive = true; + + } + return this->servoIndex; +} + +void Servo::detach() +{ + servos[this->servoIndex].Pin.isActive = false; +} + + +void Servo::write(int value) +{ + if (value < 0) + value = 0; + else if (value > 180) + value = 180; + value = map(value, 0, 180, MIN_PULSE, MAX_PULSE); + + writeMicroseconds(value); +} + + +void Servo::writeMicroseconds(int value) +{ + uint8_t channel, instance; + uint8_t pin = servos[this->servoIndex].Pin.nbr; + //instance of pwm module is MSB - look at VWariant.h + instance=(g_APinDescription[pin].ulPWMChannel & 0xF0)/16; + //index of pwm channel is LSB - look at VWariant.h + channel=g_APinDescription[pin].ulPWMChannel & 0x0F; + group_pins[instance][channel]=g_APinDescription[pin].ulPin; + NRF_PWM_Type * PWMInstance = instance == 0 ? NRF_PWM0 : (instance == 1 ? NRF_PWM1 : NRF_PWM2); + //configure pwm instance and enable it + seq_values[instance][channel]= value | 0x8000; + nrf_pwm_sequence_t const seq={ + seq_values[instance], + NRF_PWM_VALUES_LENGTH(seq_values), + 0, + 0 + }; + nrf_pwm_pins_set(PWMInstance, group_pins[instance]); + nrf_pwm_enable(PWMInstance); + nrf_pwm_configure(PWMInstance, NRF_PWM_CLK_125kHz, NRF_PWM_MODE_UP, 2500); // 20ms - 50Hz + nrf_pwm_decoder_set(PWMInstance, NRF_PWM_LOAD_INDIVIDUAL, NRF_PWM_STEP_AUTO); + nrf_pwm_sequence_set(PWMInstance, 0, &seq); + nrf_pwm_loop_set(PWMInstance, 0UL); + nrf_pwm_task_trigger(PWMInstance, NRF_PWM_TASK_SEQSTART0); +} + +int Servo::read() // return the value as degrees +{ + return map(readMicroseconds(), MIN_PULSE, MAX_PULSE, 0, 180); +} + +int Servo::readMicroseconds() +{ + uint8_t channel, instance; + uint8_t pin=servos[this->servoIndex].Pin.nbr; + instance=(g_APinDescription[pin].ulPWMChannel & 0xF0)/16; + channel=g_APinDescription[pin].ulPWMChannel & 0x0F; + // remove the 16th bit we added before + return seq_values[instance][channel] & 0x7FFF; +} + +bool Servo::attached() +{ + return servos[this->servoIndex].Pin.isActive; +} + +#endif // ARDUINO_ARCH_NRF52 \ No newline at end of file diff --git a/libraries/Servo/src/nrf52/ServoTimers.h b/libraries/Servo/src/nrf52/ServoTimers.h new file mode 100644 index 000000000..51759beab --- /dev/null +++ b/libraries/Servo/src/nrf52/ServoTimers.h @@ -0,0 +1,38 @@ +/* + Copyright (c) 2016 Arduino. All right reserved. + + 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 +*/ + +/* + * NRF52 doesn't use timer, but pwm. This file include definitions to keep + * compatibility with the Servo library standards. + */ + +#ifndef __SERVO_TIMERS_H__ +#define __SERVO_TIMERS_H__ + +/** + * NRF52 Only definitions + * --------------------- + */ + +#define MIN_PULSE 55 +#define MAX_PULSE 284 + +// define one timer in order to have MAX_SERVOS = 12 +typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; + +#endif // __SERVO_TIMERS_H__ \ No newline at end of file diff --git a/libraries/Servo/src/sam/Servo.cpp b/libraries/Servo/src/sam/Servo.cpp new file mode 100644 index 000000000..21f901f0e --- /dev/null +++ b/libraries/Servo/src/sam/Servo.cpp @@ -0,0 +1,283 @@ +/* + Copyright (c) 2013 Arduino LLC. All right reserved. + + 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 +*/ + +#if defined(ARDUINO_ARCH_SAM) + +#include +#include + +#define usToTicks(_us) (( clockCyclesPerMicrosecond() * _us) / 32) // converts microseconds to tick +#define ticksToUs(_ticks) (( (unsigned)_ticks * 32)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds + +#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays + +static servo_t servos[MAX_SERVOS]; // static array of servo structures + +uint8_t ServoCount = 0; // the total number of attached servos + +static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) + +// convenience macros +#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo +#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer +#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel +#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel + +#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo +#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo + +/************ static functions common to all instances ***********************/ + +//------------------------------------------------------------------------------ +/// Interrupt handler for the TC0 channel 1. +//------------------------------------------------------------------------------ +void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel); +#if defined (_useTimer1) +void HANDLER_FOR_TIMER1(void) { + Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); +} +#endif +#if defined (_useTimer2) +void HANDLER_FOR_TIMER2(void) { + Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); +} +#endif +#if defined (_useTimer3) +void HANDLER_FOR_TIMER3(void) { + Servo_Handler(_timer3, TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); +} +#endif +#if defined (_useTimer4) +void HANDLER_FOR_TIMER4(void) { + Servo_Handler(_timer4, TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); +} +#endif +#if defined (_useTimer5) +void HANDLER_FOR_TIMER5(void) { + Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); +} +#endif + +void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel) +{ + // clear interrupt + tc->TC_CHANNEL[channel].TC_SR; + if (Channel[timer] < 0) { + tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer + } else { + if (SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true) { + digitalWrite(SERVO(timer,Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated + } + } + + Channel[timer]++; // increment to the next channel + if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { + tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks; + if(SERVO(timer,Channel[timer]).Pin.isActive == true) { // check if activated + digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high + } + } + else { + // finished all channels so wait for the refresh period to expire before starting over + if( (tc->TC_CHANNEL[channel].TC_CV) + 4 < usToTicks(REFRESH_INTERVAL) ) { // allow a few ticks to ensure the next OCR1A not missed + tc->TC_CHANNEL[channel].TC_RA = (unsigned int)usToTicks(REFRESH_INTERVAL); + } + else { + tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + 4; // at least REFRESH_INTERVAL has elapsed + } + Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel + } +} + +static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) +{ + pmc_enable_periph_clk(id); + TC_Configure(tc, channel, + TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32 + TC_CMR_WAVE | // Waveform mode + TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC + + /* 84MHz, MCK/32, for 1.5ms: 3937 */ + TC_SetRA(tc, channel, 2625); // 1ms + + /* Configure and enable interrupt */ + NVIC_EnableIRQ(irqn); + // TC_IER_CPAS: RA Compare + tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS; + + // Enables the timer clock and performs a software reset to start the counting + TC_Start(tc, channel); +} + +static void initISR(timer16_Sequence_t timer) +{ +#if defined (_useTimer1) + if (timer == _timer1) + _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1); +#endif +#if defined (_useTimer2) + if (timer == _timer2) + _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2); +#endif +#if defined (_useTimer3) + if (timer == _timer3) + _initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3); +#endif +#if defined (_useTimer4) + if (timer == _timer4) + _initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4); +#endif +#if defined (_useTimer5) + if (timer == _timer5) + _initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5); +#endif +} + +static void finISR(timer16_Sequence_t timer) +{ +#if defined (_useTimer1) + TC_Stop(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); +#endif +#if defined (_useTimer2) + TC_Stop(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); +#endif +#if defined (_useTimer3) + TC_Stop(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); +#endif +#if defined (_useTimer4) + TC_Stop(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); +#endif +#if defined (_useTimer5) + TC_Stop(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); +#endif +} + + +static boolean isTimerActive(timer16_Sequence_t timer) +{ + // returns true if any servo is active on this timer + for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { + if(SERVO(timer,channel).Pin.isActive == true) + return true; + } + return false; +} + +/****************** end of static functions ******************************/ + +Servo::Servo() +{ + if (ServoCount < MAX_SERVOS) { + this->servoIndex = ServoCount++; // assign a servo index to this instance + servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values + } else { + this->servoIndex = INVALID_SERVO; // too many servos + } +} + +uint8_t Servo::attach(int pin) +{ + return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); +} + +uint8_t Servo::attach(int pin, int min, int max) +{ + timer16_Sequence_t timer; + + if (this->servoIndex < MAX_SERVOS) { + pinMode(pin, OUTPUT); // set servo pin to output + servos[this->servoIndex].Pin.nbr = pin; + // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 + this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS + this->max = (MAX_PULSE_WIDTH - max)/4; + // initialize the timer if it has not already been initialized + timer = SERVO_INDEX_TO_TIMER(servoIndex); + if (isTimerActive(timer) == false) { + initISR(timer); + } + servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive + } + return this->servoIndex; +} + +void Servo::detach() +{ + timer16_Sequence_t timer; + + servos[this->servoIndex].Pin.isActive = false; + timer = SERVO_INDEX_TO_TIMER(servoIndex); + if(isTimerActive(timer) == false) { + finISR(timer); + } +} + +void Servo::write(int value) +{ + // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) + if (value < MIN_PULSE_WIDTH) + { + if (value < 0) + value = 0; + else if (value > 180) + value = 180; + + value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); + } + writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value) +{ + // calculate and store the values for the given channel + byte channel = this->servoIndex; + if( (channel < MAX_SERVOS) ) // ensure channel is valid + { + if (value < SERVO_MIN()) // ensure pulse width is valid + value = SERVO_MIN(); + else if (value > SERVO_MAX()) + value = SERVO_MAX(); + + value = value - TRIM_DURATION; + value = usToTicks(value); // convert to ticks after compensating for interrupt overhead + servos[channel].ticks = value; + } +} + +int Servo::read() // return the value as degrees +{ + return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); +} + +int Servo::readMicroseconds() +{ + unsigned int pulsewidth; + if (this->servoIndex != INVALID_SERVO) + pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; + else + pulsewidth = 0; + + return pulsewidth; +} + +bool Servo::attached() +{ + return servos[this->servoIndex].Pin.isActive; +} + +#endif // ARDUINO_ARCH_SAM + diff --git a/libraries/Servo/src/sam/ServoTimers.h b/libraries/Servo/src/sam/ServoTimers.h new file mode 100644 index 000000000..13f736a19 --- /dev/null +++ b/libraries/Servo/src/sam/ServoTimers.h @@ -0,0 +1,88 @@ +/* + Copyright (c) 2013 Arduino LLC. All right reserved. + + 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 +*/ + +/* + * Defines for 16 bit timers used with Servo library + * + * If _useTimerX is defined then TimerX is a 16 bit timer on the current board + * timer16_Sequence_t enumerates the sequence that the timers should be allocated + * _Nbr_16timers indicates how many 16 bit timers are available. + */ + +/** + * SAM Only definitions + * -------------------- + */ + +// For SAM3X: +#define _useTimer1 +#define _useTimer2 +#define _useTimer3 +#define _useTimer4 +#define _useTimer5 + +/* + TC0, chan 0 => TC0_Handler + TC0, chan 1 => TC1_Handler + TC0, chan 2 => TC2_Handler + TC1, chan 0 => TC3_Handler + TC1, chan 1 => TC4_Handler + TC1, chan 2 => TC5_Handler + TC2, chan 0 => TC6_Handler + TC2, chan 1 => TC7_Handler + TC2, chan 2 => TC8_Handler + */ + +#if defined (_useTimer1) +#define TC_FOR_TIMER1 TC1 +#define CHANNEL_FOR_TIMER1 0 +#define ID_TC_FOR_TIMER1 ID_TC3 +#define IRQn_FOR_TIMER1 TC3_IRQn +#define HANDLER_FOR_TIMER1 TC3_Handler +#endif +#if defined (_useTimer2) +#define TC_FOR_TIMER2 TC1 +#define CHANNEL_FOR_TIMER2 1 +#define ID_TC_FOR_TIMER2 ID_TC4 +#define IRQn_FOR_TIMER2 TC4_IRQn +#define HANDLER_FOR_TIMER2 TC4_Handler +#endif +#if defined (_useTimer3) +#define TC_FOR_TIMER3 TC1 +#define CHANNEL_FOR_TIMER3 2 +#define ID_TC_FOR_TIMER3 ID_TC5 +#define IRQn_FOR_TIMER3 TC5_IRQn +#define HANDLER_FOR_TIMER3 TC5_Handler +#endif +#if defined (_useTimer4) +#define TC_FOR_TIMER4 TC0 +#define CHANNEL_FOR_TIMER4 2 +#define ID_TC_FOR_TIMER4 ID_TC2 +#define IRQn_FOR_TIMER4 TC2_IRQn +#define HANDLER_FOR_TIMER4 TC2_Handler +#endif +#if defined (_useTimer5) +#define TC_FOR_TIMER5 TC0 +#define CHANNEL_FOR_TIMER5 0 +#define ID_TC_FOR_TIMER5 ID_TC0 +#define IRQn_FOR_TIMER5 TC0_IRQn +#define HANDLER_FOR_TIMER5 TC0_Handler +#endif + +typedef enum { _timer1, _timer2, _timer3, _timer4, _timer5, _Nbr_16timers } timer16_Sequence_t ; + diff --git a/libraries/Servo/src/samd/Servo.cpp b/libraries/Servo/src/samd/Servo.cpp new file mode 100644 index 000000000..ba07e70a7 --- /dev/null +++ b/libraries/Servo/src/samd/Servo.cpp @@ -0,0 +1,396 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + 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 +*/ + +#if defined(ARDUINO_ARCH_SAMD) + +#include +#include + +#ifdef USE_TINYUSB +// For Serial when selecting TinyUSB +#include +#endif + +#if defined(__SAMD51__) + // Different prescalers depending on FCPU (avoid overflowing 16-bit counter) + #if(F_CPU > 200000000) + #define usToTicks(_us) ((clockCyclesPerMicrosecond() * _us) / 128) + #define ticksToUs(_ticks) (((unsigned) _ticks * 128) / clockCyclesPerMicrosecond()) + #else + #define usToTicks(_us) ((clockCyclesPerMicrosecond() * _us) / 64) + #define ticksToUs(_ticks) (((unsigned) _ticks * 64) / clockCyclesPerMicrosecond()) + #endif +#else + #define usToTicks(_us) ((clockCyclesPerMicrosecond() * _us) / 16) // converts microseconds to tick + #define ticksToUs(_ticks) (((unsigned) _ticks * 16) / clockCyclesPerMicrosecond()) // converts from ticks back to microseconds +#endif + +#define TRIM_DURATION 5 // compensation ticks to trim adjust for digitalWrite delays + +static servo_t servos[MAX_SERVOS]; // static array of servo structures + +uint8_t ServoCount = 0; // the total number of attached servos + +static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval) + +// convenience macros +#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo +#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer +#define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel +#define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel + +#define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo +#define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo + +// Referenced in SAMD21 code only, no harm in defining regardless +#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY); + +/************ static functions common to all instances ***********************/ + +void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel, uint8_t intFlag); +#if defined (_useTimer1) +void HANDLER_FOR_TIMER1(void) { + Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, INTFLAG_BIT_FOR_TIMER_1); +} +#endif +#if defined (_useTimer2) +void HANDLER_FOR_TIMER2(void) { + Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, INTFLAG_BIT_FOR_TIMER_2); +} +#endif + +void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel, uint8_t intFlag) +{ + if (currentServoIndex[timer] < 0) { + tc->COUNT16.COUNT.reg = (uint16_t) 0; +#if defined(__SAMD51__) + while(tc->COUNT16.SYNCBUSY.bit.COUNT); +#else + WAIT_TC16_REGS_SYNC(tc) +#endif + } else { + if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { + digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated + } + } + + // Select the next servo controlled by this timer + currentServoIndex[timer]++; + + if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) { + if (SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { // check if activated + digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high + } + + // Get the counter value +#if defined(__SAMD51__) + // Note from datasheet: Prior to any read access, this register must be synchronized by user by writing the according TC + // Command value to the Control B Set register (CTRLBSET.CMD=READSYNC) + while (tc->COUNT16.SYNCBUSY.bit.CTRLB); + tc->COUNT16.CTRLBSET.bit.CMD = TC_CTRLBSET_CMD_READSYNC_Val; + while (tc->COUNT16.SYNCBUSY.bit.CTRLB); +#endif + uint16_t tcCounterValue = tc->COUNT16.COUNT.reg; +#if defined(__SAMD51__) + while(tc->COUNT16.SYNCBUSY.bit.COUNT); +#else + WAIT_TC16_REGS_SYNC(tc) +#endif + + tc->COUNT16.CC[channel].reg = (uint16_t) (tcCounterValue + SERVO(timer, currentServoIndex[timer]).ticks); +#if defined(__SAMD51__) + if(channel == 0) { + while(tc->COUNT16.SYNCBUSY.bit.CC0); + } else if(channel == 1) { + while(tc->COUNT16.SYNCBUSY.bit.CC1); + } +#else + WAIT_TC16_REGS_SYNC(tc) +#endif + } + else { + // finished all channels so wait for the refresh period to expire before starting over + + // Get the counter value + uint16_t tcCounterValue = tc->COUNT16.COUNT.reg; +#if defined(__SAMD51__) + while(tc->COUNT16.SYNCBUSY.bit.COUNT); +#else + WAIT_TC16_REGS_SYNC(tc) +#endif + + if (tcCounterValue + 4UL < usToTicks(REFRESH_INTERVAL)) { // allow a few ticks to ensure the next OCR1A not missed + tc->COUNT16.CC[channel].reg = (uint16_t) usToTicks(REFRESH_INTERVAL); + } + else { + tc->COUNT16.CC[channel].reg = (uint16_t) (tcCounterValue + 4UL); // at least REFRESH_INTERVAL has elapsed + } +#if defined(__SAMD51__) + if(channel == 0) { + while(tc->COUNT16.SYNCBUSY.bit.CC0); + } else if(channel == 1) { + while(tc->COUNT16.SYNCBUSY.bit.CC1); + } +#else + WAIT_TC16_REGS_SYNC(tc) +#endif + + currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel + } + + // Clear the interrupt + tc->COUNT16.INTFLAG.reg = intFlag; +} + +static inline void resetTC (Tc* TCx) +{ + // Disable TCx + TCx->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE; +#if defined(__SAMD51__) + while(TCx->COUNT16.SYNCBUSY.bit.ENABLE); +#else + WAIT_TC16_REGS_SYNC(TCx) +#endif + + // Reset TCx + TCx->COUNT16.CTRLA.reg = TC_CTRLA_SWRST; +#if defined(__SAMD51__) + while(TCx->COUNT16.SYNCBUSY.bit.SWRST); +#else + WAIT_TC16_REGS_SYNC(TCx) +#endif + while (TCx->COUNT16.CTRLA.bit.SWRST); +} + +static void _initISR(Tc *tc, uint8_t channel, uint32_t id, IRQn_Type irqn, uint8_t gcmForTimer, uint8_t intEnableBit) +{ + (void)id; + // Select GCLK0 as timer/counter input clock source +#if defined(__SAMD51__) + int idx = gcmForTimer; // see datasheet Table 14-9 + GCLK->PCHCTRL[idx].bit.GEN = 0; // Select GCLK0 as periph clock source + GCLK->PCHCTRL[idx].bit.CHEN = 1; // Enable peripheral + while(!GCLK->PCHCTRL[idx].bit.CHEN); +#else + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(gcmForTimer)); + while (GCLK->STATUS.bit.SYNCBUSY); +#endif + + // Reset the timer + // TODO this is not the right thing to do if more than one channel per timer is used by the Servo library + resetTC(tc); + + // Set timer counter mode to 16 bits + tc->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16; + +#if defined(__SAMD51__) + // Set timer counter mode as normal PWM + tc->COUNT16.WAVE.bit.WAVEGEN = TCC_WAVE_WAVEGEN_NPWM_Val; + + // Set the prescaler factor to 64 or 128 depending on FCPU + // (avoid overflowing 16-bit clock counter) + #if(F_CPU > 200000000) + tc->COUNT16.CTRLA.bit.PRESCALER = TCC_CTRLA_PRESCALER_DIV128_Val; + #else + // At 120-200 MHz GCLK this is 1875-3125 ticks per millisecond + tc->COUNT16.CTRLA.bit.PRESCALER = TCC_CTRLA_PRESCALER_DIV64_Val; + #endif +#else + // Set timer counter mode as normal PWM + tc->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM; + + // Set the prescaler factor to GCLK_TC/16. At nominal 48MHz GCLK_TC this is 3000 ticks per millisecond + tc->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV16; +#endif + + // Count up + tc->COUNT16.CTRLBCLR.bit.DIR = 1; +#if defined(__SAMD51__) + while(tc->COUNT16.SYNCBUSY.bit.CTRLB); +#else + WAIT_TC16_REGS_SYNC(tc) +#endif + + // First interrupt request after 1 ms + tc->COUNT16.CC[channel].reg = (uint16_t) usToTicks(1000UL); +#if defined(__SAMD51__) + if(channel == 0) { + while(tc->COUNT16.SYNCBUSY.bit.CC0); + } else if(channel == 1) { + while(tc->COUNT16.SYNCBUSY.bit.CC1); + } +#else + WAIT_TC16_REGS_SYNC(tc) +#endif + + // Configure interrupt request + // TODO this should be changed if more than one channel per timer is used by the Servo library + NVIC_DisableIRQ(irqn); + NVIC_ClearPendingIRQ(irqn); + NVIC_SetPriority(irqn, 0); + NVIC_EnableIRQ(irqn); + + // Enable the match channel interrupt request + tc->COUNT16.INTENSET.reg = intEnableBit; + + // Enable the timer and start it + tc->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; +#if defined(__SAMD51__) + while(tc->COUNT16.SYNCBUSY.bit.ENABLE); +#else + WAIT_TC16_REGS_SYNC(tc) +#endif +} + +static void initISR(timer16_Sequence_t timer) +{ +#if defined (_useTimer1) + if (timer == _timer1) + _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1, GCM_FOR_TIMER_1, INTENSET_BIT_FOR_TIMER_1); +#endif +#if defined (_useTimer2) + if (timer == _timer2) + _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2, GCM_FOR_TIMER_2, INTENSET_BIT_FOR_TIMER_2); +#endif +} + +static void finISR(timer16_Sequence_t timer) +{ + (void)timer; +#if defined (_useTimer1) + // Disable the match channel interrupt request + TC_FOR_TIMER1->COUNT16.INTENCLR.reg = INTENCLR_BIT_FOR_TIMER_1; +#endif +#if defined (_useTimer2) + // Disable the match channel interrupt request + TC_FOR_TIMER2->COUNT16.INTENCLR.reg = INTENCLR_BIT_FOR_TIMER_2; +#endif +} + +static boolean isTimerActive(timer16_Sequence_t timer) +{ + // returns true if any servo is active on this timer + for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { + if(SERVO(timer,channel).Pin.isActive == true) + return true; + } + return false; +} + +/****************** end of static functions ******************************/ + +Servo::Servo() +{ + if (ServoCount < MAX_SERVOS) { + this->servoIndex = ServoCount++; // assign a servo index to this instance + servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values + } else { + this->servoIndex = INVALID_SERVO; // too many servos + } +} + +uint8_t Servo::attach(int pin) +{ + return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); +} + +uint8_t Servo::attach(int pin, int min, int max) +{ + timer16_Sequence_t timer; + + if (this->servoIndex < MAX_SERVOS) { + pinMode(pin, OUTPUT); // set servo pin to output + servos[this->servoIndex].Pin.nbr = pin; + // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 + this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS + this->max = (MAX_PULSE_WIDTH - max)/4; + // initialize the timer if it has not already been initialized + timer = SERVO_INDEX_TO_TIMER(servoIndex); + if (isTimerActive(timer) == false) { + initISR(timer); + } + servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive + } + return this->servoIndex; +} + +void Servo::detach() +{ + timer16_Sequence_t timer; + + servos[this->servoIndex].Pin.isActive = false; + timer = SERVO_INDEX_TO_TIMER(servoIndex); + if(isTimerActive(timer) == false) { + finISR(timer); + } +} + +void Servo::write(int value) +{ + // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) + if (value < MIN_PULSE_WIDTH) + { + if (value < 0) + value = 0; + else if (value > 180) + value = 180; + + value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); + } + writeMicroseconds(value); +} + +void Servo::writeMicroseconds(int value) +{ + // calculate and store the values for the given channel + byte channel = this->servoIndex; + if( (channel < MAX_SERVOS) ) // ensure channel is valid + { + if (value < SERVO_MIN()) // ensure pulse width is valid + value = SERVO_MIN(); + else if (value > SERVO_MAX()) + value = SERVO_MAX(); + + value = value - TRIM_DURATION; + value = usToTicks(value); // convert to ticks after compensating for interrupt overhead + servos[channel].ticks = value; + } +} + +int Servo::read() // return the value as degrees +{ + return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); +} + +int Servo::readMicroseconds() +{ + unsigned int pulsewidth; + if (this->servoIndex != INVALID_SERVO) + pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; + else + pulsewidth = 0; + + return pulsewidth; +} + +bool Servo::attached() +{ + return servos[this->servoIndex].Pin.isActive; +} + +#endif // ARDUINO_ARCH_SAMD diff --git a/libraries/Servo/src/samd/ServoTimers.h b/libraries/Servo/src/samd/ServoTimers.h new file mode 100644 index 000000000..c4da50694 --- /dev/null +++ b/libraries/Servo/src/samd/ServoTimers.h @@ -0,0 +1,98 @@ +/* + Copyright (c) 2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* + * Defines for 16 bit timers used with Servo library + * + * If _useTimerX is defined then TimerX is a 16 bit timer on the current board + * timer16_Sequence_t enumerates the sequence that the timers should be allocated + * _Nbr_16timers indicates how many 16 bit timers are available. + */ + +#ifndef __SERVO_TIMERS_H__ +#define __SERVO_TIMERS_H__ + +/** + * SAMD Only definitions + * --------------------- + */ + +// For SAMD: +#define _useTimer1 +//#define _useTimer2 // <- TODO do not activate until the code in Servo.cpp has been changed in order + // to manage more than one channel per timer on the SAMD architecture + +#if defined(__SAMD51__) + #if defined (_useTimer1) + #define TC_FOR_TIMER1 TC1 + #define CHANNEL_FOR_TIMER1 0 + #define INTENSET_BIT_FOR_TIMER_1 TC_INTENSET_MC0 + #define INTENCLR_BIT_FOR_TIMER_1 TC_INTENCLR_MC0 + #define INTFLAG_BIT_FOR_TIMER_1 TC_INTFLAG_MC0 + #define ID_TC_FOR_TIMER1 ID_TC1 + #define IRQn_FOR_TIMER1 TC1_IRQn + #define HANDLER_FOR_TIMER1 TC1_Handler + #define GCM_FOR_TIMER_1 TC1_GCLK_ID + #endif + + #if defined (_useTimer2) + #define TC_FOR_TIMER2 TC1 + #define CHANNEL_FOR_TIMER2 1 + #define INTENSET_BIT_FOR_TIMER_2 TC_INTENSET_MC1 + #define INTENCLR_BIT_FOR_TIMER_2 TC_INTENCLR_MC1 + #define INTFLAG_BIT_FOR_TIMER_2 TC_INTFLAG_MC1 + #define ID_TC_FOR_TIMER2 ID_TC1 + #define IRQn_FOR_TIMER2 TC1_IRQn + #define HANDLER_FOR_TIMER2 TC1_Handler + #define GCM_FOR_TIMER_2 TC1_GCLK_ID + #endif +#else + #if defined (_useTimer1) + #define TC_FOR_TIMER1 TC4 + #define CHANNEL_FOR_TIMER1 0 + #define INTENSET_BIT_FOR_TIMER_1 TC_INTENSET_MC0 + #define INTENCLR_BIT_FOR_TIMER_1 TC_INTENCLR_MC0 + #define INTFLAG_BIT_FOR_TIMER_1 TC_INTFLAG_MC0 + #define ID_TC_FOR_TIMER1 ID_TC4 + #define IRQn_FOR_TIMER1 TC4_IRQn + #define HANDLER_FOR_TIMER1 TC4_Handler + #define GCM_FOR_TIMER_1 GCM_TC4_TC5 + #endif + + #if defined (_useTimer2) + #define TC_FOR_TIMER2 TC4 + #define CHANNEL_FOR_TIMER2 1 + #define INTENSET_BIT_FOR_TIMER_2 TC_INTENSET_MC1 + #define INTENCLR_BIT_FOR_TIMER_2 TC_INTENCLR_MC1 + #define ID_TC_FOR_TIMER2 ID_TC4 + #define IRQn_FOR_TIMER2 TC4_IRQn + #define HANDLER_FOR_TIMER2 TC4_Handler + #define GCM_FOR_TIMER_2 GCM_TC4_TC5 + #endif +#endif + +typedef enum { +#if defined (_useTimer1) + _timer1, +#endif +#if defined (_useTimer2) + _timer2, +#endif + _Nbr_16timers } timer16_Sequence_t; + +#endif // __SERVO_TIMERS_H__ diff --git a/libraries/Servo/src/stm32f4/Servo.cpp b/libraries/Servo/src/stm32f4/Servo.cpp new file mode 100644 index 000000000..01d05d98d --- /dev/null +++ b/libraries/Servo/src/stm32f4/Servo.cpp @@ -0,0 +1,194 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010, LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + +#if defined(ARDUINO_ARCH_STM32F4) + +#include "ServoTimers.h" + +#include "boards.h" +#include "io.h" +#include "pwm.h" +#include "math.h" + +// 20 millisecond period config. For a 1-based prescaler, +// +// (prescaler * overflow / CYC_MSEC) msec = 1 timer cycle = 20 msec +// => prescaler * overflow = 20 * CYC_MSEC +// +// This picks the smallest prescaler that allows an overflow < 2^16. +#define MAX_OVERFLOW ((1 << 16) - 1) +#define CYC_MSEC (1000 * CYCLES_PER_MICROSECOND) +#define TAU_MSEC 20 +#define TAU_USEC (TAU_MSEC * 1000) +#define TAU_CYC (TAU_MSEC * CYC_MSEC) +#define SERVO_PRESCALER (TAU_CYC / MAX_OVERFLOW + 1) +#define SERVO_OVERFLOW ((uint16)round((double)TAU_CYC / SERVO_PRESCALER)) + +// Unit conversions +#define US_TO_COMPARE(us) ((uint16)map((us), 0, TAU_USEC, 0, SERVO_OVERFLOW)) +#define COMPARE_TO_US(c) ((uint32)map((c), 0, SERVO_OVERFLOW, 0, TAU_USEC)) +#define ANGLE_TO_US(a) ((uint16)(map((a), this->minAngle, this->maxAngle, \ + this->minPW, this->maxPW))) +#define US_TO_ANGLE(us) ((int16)(map((us), this->minPW, this->maxPW, \ + this->minAngle, this->maxAngle))) + +Servo::Servo() { + this->resetFields(); +} + +bool Servo::attach(uint8 pin, uint16 minPW, uint16 maxPW, int16 minAngle, int16 maxAngle) +{ + // SerialUSB.begin(115200); + // SerialUSB.println(MAX_OVERFLOW); + + + timer_dev *tdev = PIN_MAP[pin].timer_device; + + analogWriteResolution(16); + + int prescaler = 6; + int overflow = 65400; + int minPW_correction = 300; + int maxPW_correction = 300; + + pinMode(pin, OUTPUT); + + + if (tdev == NULL) { + // don't reset any fields or ASSERT(0), to keep driving any + // previously attach()ed servo. + return false; + } + + if ( (tdev == TIMER1) || (tdev == TIMER8) || (tdev == TIMER10) || (tdev == TIMER11)) + { + prescaler = 54; + overflow = 65400; + minPW_correction = 40; + maxPW_correction = 50; + } + + if ( (tdev == TIMER2) || (tdev == TIMER3) || (tdev == TIMER4) || (tdev == TIMER5) ) + { + prescaler = 6; + overflow = 64285; + minPW_correction = 370; + maxPW_correction = 350; + } + + if ( (tdev == TIMER6) || (tdev == TIMER7) ) + { + prescaler = 6; + overflow = 65400; + minPW_correction = 0; + maxPW_correction = 0; + } + + if ( (tdev == TIMER9) || (tdev == TIMER12) || (tdev == TIMER13) || (tdev == TIMER14) ) + { + prescaler = 6; + overflow = 65400; + minPW_correction = 30; + maxPW_correction = 0; + } + + if (this->attached()) { + this->detach(); + } + + this->pin = pin; + this->minPW = (minPW + minPW_correction); + this->maxPW = (maxPW + maxPW_correction); + this->minAngle = minAngle; + this->maxAngle = maxAngle; + + timer_pause(tdev); + timer_set_prescaler(tdev, prescaler); // prescaler is 1-based + timer_set_reload(tdev, overflow); + timer_generate_update(tdev); + timer_resume(tdev); + + return true; +} + +bool Servo::detach() { + if (!this->attached()) { + return false; + } + + timer_dev *tdev = PIN_MAP[this->pin].timer_device; + uint8 tchan = PIN_MAP[this->pin].timer_channel; + timer_set_mode(tdev, tchan, TIMER_DISABLED); + + this->resetFields(); + + return true; +} + +void Servo::write(int degrees) { + degrees = constrain(degrees, this->minAngle, this->maxAngle); + this->writeMicroseconds(ANGLE_TO_US(degrees)); +} + +int Servo::read() const { + int a = US_TO_ANGLE(this->readMicroseconds()); + // map() round-trips in a weird way we mostly correct for here; + // the round-trip is still sometimes off-by-one for write(1) and + // write(179). + return a == this->minAngle || a == this->maxAngle ? a : a + 1; +} + +void Servo::writeMicroseconds(uint16 pulseWidth) { + if (!this->attached()) { + ASSERT(0); + return; + } + pulseWidth = constrain(pulseWidth, this->minPW, this->maxPW); + analogWrite(this->pin, US_TO_COMPARE(pulseWidth)); +} + +uint16 Servo::readMicroseconds() const { + if (!this->attached()) { + ASSERT(0); + return 0; + } + + stm32_pin_info pin_info = PIN_MAP[this->pin]; + uint16 compare = timer_get_compare(pin_info.timer_device, + pin_info.timer_channel); + + return COMPARE_TO_US(compare); +} + +void Servo::resetFields(void) { + this->pin = NOT_ATTACHED; + this->minAngle = MIN_ANGLE; + this->maxAngle = MAX_ANGLE; + this->minPW = MIN_PULSE_WIDTH; + this->maxPW = MAX_PULSE_WIDTH; +} + +#endif diff --git a/libraries/Servo/src/stm32f4/ServoTimers.h b/libraries/Servo/src/stm32f4/ServoTimers.h new file mode 100644 index 000000000..12d55b730 --- /dev/null +++ b/libraries/Servo/src/stm32f4/ServoTimers.h @@ -0,0 +1,207 @@ +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2010, LeafLabs, LLC. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *****************************************************************************/ + + /* + * Arduino srl - www.arduino.org + * 2017 Feb 23: Edited by Francesco Alessi (alfran) - francesco@arduino.org + */ +#ifndef _SERVO_H_ +#define _SERVO_H_ + +#include "types.h" +#include "timer.h" + +#include "wiring.h" /* hack for IDE compile */ + +/* + * Note on Arduino compatibility: + * + * In the Arduino implementation, PWM is done "by hand" in the sense + * that timer channels are hijacked in groups and an ISR is set which + * toggles Servo::attach()ed pins using digitalWrite(). + * + * While this scheme allows any pin to drive a servo, it chews up + * cycles and complicates the programmer's notion of when a particular + * timer channel will be in use. + * + * This implementation only allows Servo instances to attach() to pins + * that already have a timer channel associated with them, and just + * uses pwmWrite() to drive the wave. + * + * This introduces an incompatibility: while the Arduino + * implementation of attach() returns the affected channel on success + * and 0 on failure, this one returns true on success and false on + * failure. + * + * RC Servos expect a pulse every 20ms. Since periods are set for + * entire timers, rather than individual channels, attach()ing a Servo + * to a pin can interfere with other pins associated with the same + * timer. As always, your board's pin map is your friend. + */ + +// Pin number of unattached pins +#define NOT_ATTACHED (-1) + +#define _Nbr_16timers 14 // mumber of STM32F469 Timers +#define SERVOS_PER_TIMER 4 // Number of timer channels + + +// Default min/max pulse widths (in microseconds) and angles (in +// degrees). Values chosen for Arduino compatibility. These values +// are part of the public API; DO NOT CHANGE THEM. +#define MIN_ANGLE 0 +#define MAX_ANGLE 180 + +#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo +#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo + +/** Class for interfacing with RC servomotors. */ +class Servo { +public: + /** + * @brief Construct a new Servo instance. + * + * The new instance will not be attached to any pin. + */ + Servo(); + + /** + * @brief Associate this instance with a servomotor whose input is + * connected to pin. + * + * If this instance is already attached to a pin, it will be + * detached before being attached to the new pin. This function + * doesn't detach any interrupt attached with the pin's timer + * channel. + * + * @param pin Pin connected to the servo pulse wave input. This + * pin must be capable of PWM output. + * + * @param minPulseWidth Minimum pulse width to write to pin, in + * microseconds. This will be associated + * with a minAngle degree angle. Defaults to + * SERVO_DEFAULT_MIN_PW = 544. + * + * @param maxPulseWidth Maximum pulse width to write to pin, in + * microseconds. This will be associated + * with a maxAngle degree angle. Defaults to + * SERVO_DEFAULT_MAX_PW = 2400. + * + * @param minAngle Target angle (in degrees) associated with + * minPulseWidth. Defaults to + * SERVO_DEFAULT_MIN_ANGLE = 0. + * + * @param maxAngle Target angle (in degrees) associated with + * maxPulseWidth. Defaults to + * SERVO_DEFAULT_MAX_ANGLE = 180. + * + * @sideeffect May set pinMode(pin, PWM). + * + * @return true if successful, false when pin doesn't support PWM. + */ + + bool attach(uint8 pin, + uint16 minPulseWidth=MIN_PULSE_WIDTH, + uint16 maxPulseWidth=MAX_PULSE_WIDTH, + int16 minAngle=MIN_ANGLE, + int16 maxAngle=MAX_ANGLE); + /** + * @brief Stop driving the servo pulse train. + * + * If not currently attached to a motor, this function has no effect. + * + * @return true if this call did anything, false otherwise. + */ + bool detach(); + + /** + * @brief Set the servomotor target angle. + * + * @param angle Target angle, in degrees. If the target angle is + * outside the range specified at attach() time, it + * will be clamped to lie in that range. + * + * @see Servo::attach() + */ + void write(int angle); + + /** + * @brief Set the pulse width, in microseconds. + * + * @param pulseWidth Pulse width to send to the servomotor, in + * microseconds. If outside of the range + * specified at attach() time, it is clamped to + * lie in that range. + * + * @see Servo::attach() + */ + void writeMicroseconds(uint16 pulseWidth); + + /** + * Get the servomotor's target angle, in degrees. This will + * lie inside the range specified at attach() time. + * + * @see Servo::attach() + */ + int read() const; + + /** + * Get the current pulse width, in microseconds. This will + * lie within the range specified at attach() time. + * + * @see Servo::attach() + */ + uint16 readMicroseconds() const; + + + /** + * @brief Check if this instance is attached to a servo. + * @return true if this instance is attached to a servo, false otherwise. + * @see Servo::attachedPin() + */ + bool attached() const { return this->pin != NOT_ATTACHED; } + + /** + * @brief Get the pin this instance is attached to. + * @return Pin number if currently attached to a pin, NOT_ATTACHED + * otherwise. + * @see Servo::attach() + */ + int attachedPin() const { return this->pin; } + +private: + int16 pin; + uint16 minPW; + uint16 maxPW; + int16 minAngle; + int16 maxAngle; + + void resetFields(void); +}; + + + +#endif /* _SERVO_H_ */ diff --git a/libraries/USBHost/examples/ADKTerminalTest/ADKTerminalTest.ino b/libraries/USBHost/examples/ADKTerminalTest/ADKTerminalTest.ino index ea7509cbc..21d6ef522 100644 --- a/libraries/USBHost/examples/ADKTerminalTest/ADKTerminalTest.ino +++ b/libraries/USBHost/examples/ADKTerminalTest/ADKTerminalTest.ino @@ -37,7 +37,7 @@ void setup(void) while (!SERIAL_PORT_MONITOR); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection SERIAL_PORT_MONITOR.println("\r\nADK demo start"); - if (usb.Init() == -1) + if (usb.Init() == (uint32_t)-1) SERIAL_PORT_MONITOR.println("OSC did not start."); delay(20); diff --git a/libraries/USBHost/examples/KeyboardController/KeyboardController.ino b/libraries/USBHost/examples/KeyboardController/KeyboardController.ino index b869ad803..0daf7b02d 100644 --- a/libraries/USBHost/examples/KeyboardController/KeyboardController.ino +++ b/libraries/USBHost/examples/KeyboardController/KeyboardController.ino @@ -2,7 +2,7 @@ Keyboard Controller Example Shows the output of a USB Keyboard connected to - the Native USB port on an Arduino Due Board. + the Native USB port on an Arduino Zero created 8 Oct 2012 by Cristian Maglie @@ -15,6 +15,13 @@ // Require keyboard control library #include + +// on a zero with debug port, use debug port +//#define SerialDebug Serial + +// on a feather or non-debug Zero, use Serial1 (since USB is taken!) +#define SerialDebug Serial1 + // Initialize USB Controller USBHost usb; @@ -25,60 +32,61 @@ void printKey(); // This function intercepts key press void keyPressed() { - SERIAL_PORT_MONITOR.print("Pressed: "); + SerialDebug.print("Pressed: "); printKey(); } // This function intercepts key release void keyReleased() { - SERIAL_PORT_MONITOR.print("Released: "); + SerialDebug.print("Released: "); printKey(); } void printKey() { // getOemKey() returns the OEM-code associated with the key - SERIAL_PORT_MONITOR.print(" key:"); - SERIAL_PORT_MONITOR.print(keyboard.getOemKey()); + SerialDebug.print(" key:"); + SerialDebug.print(keyboard.getOemKey()); // getModifiers() returns a bits field with the modifiers-keys int mod = keyboard.getModifiers(); - SERIAL_PORT_MONITOR.print(" mod:"); - SERIAL_PORT_MONITOR.print(mod); + SerialDebug.print(" mod:"); + SerialDebug.print(mod); - SERIAL_PORT_MONITOR.print(" => "); + SerialDebug.print(" => "); if (mod & LeftCtrl) - SERIAL_PORT_MONITOR.print("L-Ctrl "); + SerialDebug.print("L-Ctrl "); if (mod & LeftShift) - SERIAL_PORT_MONITOR.print("L-Shift "); + SerialDebug.print("L-Shift "); if (mod & Alt) - SERIAL_PORT_MONITOR.print("Alt "); + SerialDebug.print("Alt "); if (mod & LeftCmd) - SERIAL_PORT_MONITOR.print("L-Cmd "); + SerialDebug.print("L-Cmd "); if (mod & RightCtrl) - SERIAL_PORT_MONITOR.print("R-Ctrl "); + SerialDebug.print("R-Ctrl "); if (mod & RightShift) - SERIAL_PORT_MONITOR.print("R-Shift "); + SerialDebug.print("R-Shift "); if (mod & AltGr) - SERIAL_PORT_MONITOR.print("AltGr "); + SerialDebug.print("AltGr "); if (mod & RightCmd) - SERIAL_PORT_MONITOR.print("R-Cmd "); + SerialDebug.print("R-Cmd "); // getKey() returns the ASCII translation of OEM key // combined with modifiers. - SERIAL_PORT_MONITOR.write(keyboard.getKey()); - SERIAL_PORT_MONITOR.println(); + SerialDebug.write(keyboard.getKey()); + SerialDebug.println(); } +uint32_t lastUSBstate = 0; + void setup() { - SERIAL_PORT_MONITOR.begin( 115200 ); - while (!SERIAL_PORT_MONITOR); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection - SERIAL_PORT_MONITOR.println("Keyboard Controller Program started"); + SerialDebug.begin( 115200 ); + SerialDebug.println("USB Host Keyboard Controller Program started"); + if (usb.Init() == (uint32_t)-1) + SerialDebug.println("USB Host did not start."); - if (usb.Init() == -1) - SERIAL_PORT_MONITOR.println("OSC did not start."); - + SerialDebug.println("USB Host started"); delay( 20 ); } @@ -86,4 +94,21 @@ void loop() { // Process USB tasks usb.Task(); + + uint32_t currentUSBstate = usb.getUsbTaskState(); + if (lastUSBstate != currentUSBstate) { + SerialDebug.print("USB state changed: 0x"); + SerialDebug.print(lastUSBstate, HEX); + SerialDebug.print(" -> 0x"); + SerialDebug.println(currentUSBstate, HEX); + switch (currentUSBstate) { + case USB_ATTACHED_SUBSTATE_SETTLE: SerialDebug.println("Device Attached"); break; + case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: SerialDebug.println("Detached, waiting for Device"); break; + case USB_ATTACHED_SUBSTATE_RESET_DEVICE: SerialDebug.println("Resetting Device"); break; + case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: SerialDebug.println("Reset complete"); break; + case USB_STATE_CONFIGURING: SerialDebug.println("USB Configuring"); break; + case USB_STATE_RUNNING: SerialDebug.println("USB Running"); break; + } + lastUSBstate = currentUSBstate; + } } diff --git a/libraries/USBHost/examples/MouseController/MouseController.ino b/libraries/USBHost/examples/MouseController/MouseController.ino index ae3a1c046..90e6dce2b 100644 --- a/libraries/USBHost/examples/MouseController/MouseController.ino +++ b/libraries/USBHost/examples/MouseController/MouseController.ino @@ -15,6 +15,14 @@ // Require mouse control library #include +// on a zero with debug port, use debug port +//#define SerialDebug Serial + +// on a feather or non-debug Zero, use Serial1 (since USB is taken!) +#define SerialDebug Serial1 + +uint32_t lastUSBstate = 0; + // Initialize USB Controller USBHost usb; @@ -28,65 +36,65 @@ bool rightButton = false; // This function intercepts mouse movements void mouseMoved() { - SERIAL_PORT_MONITOR.print("Move: "); - SERIAL_PORT_MONITOR.print(mouse.getXChange()); - SERIAL_PORT_MONITOR.print(", "); - SERIAL_PORT_MONITOR.println(mouse.getYChange()); + SerialDebug.print("Move: "); + SerialDebug.print(mouse.getXChange()); + SerialDebug.print(", "); + SerialDebug.println(mouse.getYChange()); } // This function intercepts mouse movements while a button is pressed void mouseDragged() { - SERIAL_PORT_MONITOR.print("DRAG: "); - SERIAL_PORT_MONITOR.print(mouse.getXChange()); - SERIAL_PORT_MONITOR.print(", "); - SERIAL_PORT_MONITOR.println(mouse.getYChange()); + SerialDebug.print("Drag: "); + SerialDebug.print(mouse.getXChange()); + SerialDebug.print(", "); + SerialDebug.println(mouse.getYChange()); } // This function intercepts mouse button press void mousePressed() { - SERIAL_PORT_MONITOR.print("Pressed: "); + SerialDebug.print("Pressed: "); if (mouse.getButton(LEFT_BUTTON)) { - SERIAL_PORT_MONITOR.print("L"); + SerialDebug.print("L"); leftButton = true; } if (mouse.getButton(MIDDLE_BUTTON)) { - SERIAL_PORT_MONITOR.print("M"); + SerialDebug.print("M"); middleButton = true; } if (mouse.getButton(RIGHT_BUTTON)) { - SERIAL_PORT_MONITOR.print("R"); + SerialDebug.print("R"); rightButton = true; } - SERIAL_PORT_MONITOR.println(); + SerialDebug.println(); } // This function intercepts mouse button release void mouseReleased() { - SERIAL_PORT_MONITOR.print("Released: "); + SerialDebug.print("Released: "); if (!mouse.getButton(LEFT_BUTTON) && leftButton == true) { - SERIAL_PORT_MONITOR.print("L"); + SerialDebug.print("L"); leftButton = false; } if (!mouse.getButton(MIDDLE_BUTTON) && middleButton == true) { - SERIAL_PORT_MONITOR.print("M"); + SerialDebug.print("M"); middleButton = false; } if (!mouse.getButton(RIGHT_BUTTON) && rightButton == true) { - SERIAL_PORT_MONITOR.print("R"); + SerialDebug.print("R"); rightButton = false; } - SERIAL_PORT_MONITOR.println(); + SerialDebug.println(); } void setup() { - SERIAL_PORT_MONITOR.begin( 115200 ); - while (!SERIAL_PORT_MONITOR); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection - SERIAL_PORT_MONITOR.println("Mouse Controller Program started"); + SerialDebug.begin( 115200 ); + SerialDebug.println("USB Host Mouse Controller Program started"); - if (usb.Init() == -1) - SERIAL_PORT_MONITOR.println("OSC did not start."); + if (usb.Init() == (uint32_t)-1) + SerialDebug.println("USB Host did not start."); + SerialDebug.println("USB Host started"); delay( 20 ); } @@ -94,4 +102,21 @@ void loop() { // Process USB tasks usb.Task(); + + uint32_t currentUSBstate = usb.getUsbTaskState(); + if (lastUSBstate != currentUSBstate) { + SerialDebug.print("USB state changed: 0x"); + SerialDebug.print(lastUSBstate, HEX); + SerialDebug.print(" -> 0x"); + SerialDebug.println(currentUSBstate, HEX); + switch (currentUSBstate) { + case USB_ATTACHED_SUBSTATE_SETTLE: SerialDebug.println("Device Attached"); break; + case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: SerialDebug.println("Detached, waiting for Device"); break; + case USB_ATTACHED_SUBSTATE_RESET_DEVICE: SerialDebug.println("Resetting Device"); break; + case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: SerialDebug.println("Reset complete"); break; + case USB_STATE_CONFIGURING: SerialDebug.println("USB Configuring"); break; + case USB_STATE_RUNNING: SerialDebug.println("USB Running"); break; + } + lastUSBstate = currentUSBstate; + } } diff --git a/libraries/USBHost/examples/USB_desc/USB_desc.ino b/libraries/USBHost/examples/USB_desc/USB_desc.ino index a7ede046c..2af42b172 100644 --- a/libraries/USBHost/examples/USB_desc/USB_desc.ino +++ b/libraries/USBHost/examples/USB_desc/USB_desc.ino @@ -1,22 +1,16 @@ - - #include "Arduino.h" #include #include "wiring_constants.h" #include "pgmstrings.h" -// Satisfy IDE, which only needs to see the include statment in the ino. -#ifdef dobogusinclude -#include -#endif + + +// on a zero with debug port, use debug port +//#define SerialDebug Serial + +// on a feather or non-debug Zero, use Serial1 (since USB is taken!) +#define SerialDebug Serial1 USBHost usb; -//USBHub Hub1(&Usb); -//USBHub Hub2(&Usb); -//USBHub Hub3(&Usb); -//USBHub Hub4(&Usb); -//USBHub Hub5(&Usb); -//USBHub Hub6(&Usb); -//USBHub Hub7(&Usb); uint32_t next_time; @@ -33,39 +27,40 @@ void PrintAllAddresses(UsbDeviceDefinition *pdev) { UsbDeviceAddress adr; adr.devAddress = pdev->address.devAddress; - SERIAL_PORT_MONITOR.print("\r\nAddr:"); - SERIAL_PORT_MONITOR.print(adr.devAddress, HEX); - SERIAL_PORT_MONITOR.print("("); - SERIAL_PORT_MONITOR.print(adr.bmHub, HEX); - SERIAL_PORT_MONITOR.print("."); - SERIAL_PORT_MONITOR.print(adr.bmParent, HEX); - SERIAL_PORT_MONITOR.print("."); - SERIAL_PORT_MONITOR.print(adr.bmAddress, HEX); - SERIAL_PORT_MONITOR.println(")"); + SerialDebug.print("\r\nAddr:"); + SerialDebug.print(adr.devAddress, HEX); + SerialDebug.print("("); + SerialDebug.print(adr.bmHub, HEX); + SerialDebug.print("."); + SerialDebug.print(adr.bmParent, HEX); + SerialDebug.print("."); + SerialDebug.print(adr.bmAddress, HEX); + SerialDebug.println(")"); } void PrintAddress(uint8_t addr) { UsbDeviceAddress adr; adr.devAddress = addr; - SERIAL_PORT_MONITOR.print("\r\nADDR:\t"); - SERIAL_PORT_MONITOR.println(adr.devAddress,HEX); - SERIAL_PORT_MONITOR.print("DEV:\t"); - SERIAL_PORT_MONITOR.println(adr.bmAddress,HEX); - SERIAL_PORT_MONITOR.print("PRNT:\t"); - SERIAL_PORT_MONITOR.println(adr.bmParent,HEX); - SERIAL_PORT_MONITOR.print("HUB:\t"); - SERIAL_PORT_MONITOR.println(adr.bmHub,HEX); + SerialDebug.print("\r\nADDR:\t"); + SerialDebug.println(adr.devAddress,HEX); + SerialDebug.print("DEV:\t"); + SerialDebug.println(adr.bmAddress,HEX); + SerialDebug.print("PRNT:\t"); + SerialDebug.println(adr.bmParent,HEX); + SerialDebug.print("HUB:\t"); + SerialDebug.println(adr.bmHub,HEX); } void setup() { - SERIAL_PORT_MONITOR.begin( 115200 ); - while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection - SERIAL_PORT_MONITOR.println("Start USB Desc"); + Serial.begin(115200); + SerialDebug.begin(115200); + SerialDebug.println("Starting USB Descriptor test"); - if (usb.Init() == -1) - SERIAL_PORT_MONITOR.println("OSC did not start."); + SerialDebug.println("Initializing USB"); + if (usb.Init() == (uint32_t)-1) + SerialDebug.println("USBhost did not start."); delay( 20 ); @@ -85,7 +80,7 @@ void PrintDescriptors(uint8_t addr) printProgStr(Gen_Error_str); print_hex( rcode, 8 ); } - SERIAL_PORT_MONITOR.print("\r\n"); + SerialDebug.print("\r\n"); for (int i=0; iaddress.devAddress, 8); - SERIAL_PORT_MONITOR.println("\r\n--"); + SerialDebug.println("\r\n--"); PrintDescriptors( pdev->address.devAddress ); } @@ -166,42 +161,43 @@ byte getdevdescr( byte addr, byte &num_conf ) void printhubdescr(uint8_t *descrptr, uint8_t addr) { + (void)addr; HubDescriptor *pHub = (HubDescriptor*) descrptr; uint8_t len = *((uint8_t*)descrptr); printProgStr(PSTR("\r\n\r\nHub Descriptor:\r\n")); printProgStr(PSTR("bDescLength:\t\t")); - SERIAL_PORT_MONITOR.println(pHub->bDescLength, HEX); + SerialDebug.println(pHub->bDescLength, HEX); printProgStr(PSTR("bDescriptorType:\t")); - SERIAL_PORT_MONITOR.println(pHub->bDescriptorType, HEX); + SerialDebug.println(pHub->bDescriptorType, HEX); printProgStr(PSTR("bNbrPorts:\t\t")); - SERIAL_PORT_MONITOR.println(pHub->bNbrPorts, HEX); + SerialDebug.println(pHub->bNbrPorts, HEX); printProgStr(PSTR("LogPwrSwitchMode:\t")); - SERIAL_PORT_MONITOR.println(pHub->LogPwrSwitchMode, BIN); + SerialDebug.println(pHub->LogPwrSwitchMode, BIN); printProgStr(PSTR("CompoundDevice:\t\t")); - SERIAL_PORT_MONITOR.println(pHub->CompoundDevice, BIN); + SerialDebug.println(pHub->CompoundDevice, BIN); printProgStr(PSTR("OverCurrentProtectMode:\t")); - SERIAL_PORT_MONITOR.println(pHub->OverCurrentProtectMode, BIN); + SerialDebug.println(pHub->OverCurrentProtectMode, BIN); printProgStr(PSTR("TTThinkTime:\t\t")); - SERIAL_PORT_MONITOR.println(pHub->TTThinkTime, BIN); + SerialDebug.println(pHub->TTThinkTime, BIN); printProgStr(PSTR("PortIndicatorsSupported:")); - SERIAL_PORT_MONITOR.println(pHub->PortIndicatorsSupported, BIN); + SerialDebug.println(pHub->PortIndicatorsSupported, BIN); printProgStr(PSTR("Reserved:\t\t")); - SERIAL_PORT_MONITOR.println(pHub->Reserved, HEX); + SerialDebug.println(pHub->Reserved, HEX); printProgStr(PSTR("bPwrOn2PwrGood:\t\t")); - SERIAL_PORT_MONITOR.println(pHub->bPwrOn2PwrGood, HEX); + SerialDebug.println(pHub->bPwrOn2PwrGood, HEX); printProgStr(PSTR("bHubContrCurrent:\t")); - SERIAL_PORT_MONITOR.println(pHub->bHubContrCurrent, HEX); + SerialDebug.println(pHub->bHubContrCurrent, HEX); for (uint8_t i=7; i sizeof(buf)) { //check if total length is larger than buffer printProgStr(Conf_Trunc_str); total_length = sizeof(buf); } + // FIXME -- no check of return code from usb.getConfDescr() rcode = usb.getConfDescr( addr, 0, total_length, conf, buf ); //get the whole descriptor + (void) rcode; while( buf_ptr < buf + total_length ) { //parsing descriptors descr_length = *( buf_ptr ); descr_type = *( buf_ptr + 1 ); @@ -271,7 +271,7 @@ void print_hex(int v, int num_places) } do { digit = ((v >> (num_nibbles-1) * 4)) & 0x0f; - SERIAL_PORT_MONITOR.print(digit, HEX); + SerialDebug.print(digit, HEX); } while(--num_nibbles); } @@ -329,7 +329,7 @@ void printHIDdescr( uint8_t* descr_ptr ) printProgStr(PSTR("\r\nNumb Class Descriptor:\t")); print_hex( ep_ptr->bNumDescriptors, 8 ); printProgStr(PSTR("\r\nDescriptor Type:\t")); - if( ep_ptr->bDescrType == 0x22 ) + if( ep_ptr->bDescrType == 0x22 ) printProgStr(PSTR("REPORT DESCRIPTOR")); else print_hex( ep_ptr->bDescrType, 8 ); @@ -386,5 +386,5 @@ void printProgStr(const prog_char str[]) char c; if(!str) return; while((c = pgm_read_byte(str++))) - SERIAL_PORT_MONITOR.print(c); + SerialDebug.print(c); } diff --git a/libraries/USBHost/src/Usb.cpp b/libraries/USBHost/src/Usb.cpp index 3b3b8b1c6..757d3bb32 100644 --- a/libraries/USBHost/src/Usb.cpp +++ b/libraries/USBHost/src/Usb.cpp @@ -429,15 +429,14 @@ uint32_t USBHost::dispatchPkt(uint32_t token, uint32_t epAddr, uint32_t nak_limi //case hrNAK: if((USB->HOST.HostPipe[epAddr].PINTFLAG.reg & USB_HOST_PINTFLAG_TRFAIL) ) { - USB->HOST.HostPipe[epAddr].PINTFLAG.reg = USB_HOST_PINTFLAG_TRFAIL; - nak_count++; - if(nak_limit && (nak_count == nak_limit)) { - rcode = USB_ERRORFLOW; - return (rcode); - } - } + USB->HOST.HostPipe[epAddr].PINTFLAG.reg = USB_HOST_PINTFLAG_TRFAIL; + nak_count++; + if(nak_limit && (nak_count == nak_limit)) { + rcode = USB_ERRORFLOW; + return (rcode); + } + } - //case hrNAK: if( (usb_pipe_table[epAddr].HostDescBank[0].STATUS_BK.reg & USB_ERRORFLOW ) ) { nak_count++; if(nak_limit && (nak_count == nak_limit)) { diff --git a/libraries/USBHost/src/confdescparser.h b/libraries/USBHost/src/confdescparser.h index 4b2b41b4f..de69e2ccd 100644 --- a/libraries/USBHost/src/confdescparser.h +++ b/libraries/USBHost/src/confdescparser.h @@ -59,15 +59,15 @@ class ConfigDescParser : public USBReadParser { uint32_t ifaceNumber; // Interface number uint32_t ifaceAltSet; // Interface alternate settings - bool UseOr; + bool UseOr; bool ParseDescriptor(uint8_t **pp, uint32_t *pcntdn); void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc); public: - void SetOR(void) { - UseOr = true; - } + void SetOR(void) { + UseOr = true; + } ConfigDescParser(UsbConfigXtracter *xtractor); virtual void Parse(const uint32_t len, const uint8_t *pbuf, const uint32_t &offset); }; @@ -98,8 +98,19 @@ void ConfigDescParser::Parse(const uin compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */ template bool ConfigDescParser::ParseDescriptor(uint8_t **pp, uint32_t *pcntdn) { - USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast(varBuffer); - USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast(varBuffer); + USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast(varBuffer); + USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast(varBuffer); + + +#pragma GCC diagnostic push // Available since GCC 4.6.4 +/* + * FIXME -- Enabled and review all `-Wimplicit-fallthrough` messages + * This code has multiple switch statements that "fall through" to the + * next case -- but it's not always clear if this is intentional or not. + * Review and commenting of code, and reducing cyclomatic complexity + * are highly recommended.... + */ +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" switch(stateParseDescr) { case 0: theBuffer.valueSize = 2; @@ -112,7 +123,7 @@ bool ConfigDescParser::ParseDescriptor dscrType = *((uint8_t*)theBuffer.pValue + 1); stateParseDescr = 2; case 2: - // This is a sort of hack. Assuming that two bytes are all ready in the buffer + // This is a sort of hack. Assuming that two bytes are all ready in the buffer // the pointer is positioned two bytes ahead in order for the rest of descriptor // to be read right after the size and the type fields. // This should be used carefully. varBuffer should be used directly to handle data @@ -120,14 +131,14 @@ bool ConfigDescParser::ParseDescriptor theBuffer.pValue = varBuffer + 2; stateParseDescr = 3; case 3: - switch(dscrType) { - case USB_DESCRIPTOR_INTERFACE: - isGoodInterface = false; - case USB_DESCRIPTOR_CONFIGURATION: - theBuffer.valueSize = sizeof (USB_CONFIGURATION_DESCRIPTOR) - 2; - break; - case USB_DESCRIPTOR_ENDPOINT: - theBuffer.valueSize = sizeof (USB_ENDPOINT_DESCRIPTOR) - 2; + switch(dscrType) { + case USB_DESCRIPTOR_INTERFACE: + isGoodInterface = false; + case USB_DESCRIPTOR_CONFIGURATION: + theBuffer.valueSize = sizeof (USB_CONFIGURATION_DESCRIPTOR) - 2; + break; + case USB_DESCRIPTOR_ENDPOINT: + theBuffer.valueSize = sizeof (USB_ENDPOINT_DESCRIPTOR) - 2; break; case HID_DESCRIPTOR_HID: theBuffer.valueSize = dscrLen - 2; @@ -136,37 +147,37 @@ bool ConfigDescParser::ParseDescriptor valParser.Initialize(&theBuffer); stateParseDescr = 4; case 4: - switch(dscrType) { + switch(dscrType) { case USB_DESCRIPTOR_CONFIGURATION: - if(!valParser.Parse(pp, pcntdn)) - return false; - confValue = ucd->bConfigurationValue; + if(!valParser.Parse(pp, pcntdn)) + return false; + confValue = ucd->bConfigurationValue; break; case USB_DESCRIPTOR_INTERFACE: - if(!valParser.Parse(pp, pcntdn)) - return false; - if((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID) - break; - if((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID) - break; - if(UseOr) { - if((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol))) - break; - } else { - if((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID) - break; - } - isGoodInterface = true; - ifaceNumber = uid->bInterfaceNumber; - ifaceAltSet = uid->bAlternateSetting; - protoValue = uid->bInterfaceProtocol; - break; - case USB_DESCRIPTOR_ENDPOINT: - if(!valParser.Parse(pp, pcntdn)) - return false; - if(isGoodInterface) - if(theXtractor) - theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer); + if(!valParser.Parse(pp, pcntdn)) + return false; + if((MASK & CP_MASK_COMPARE_CLASS) && uid->bInterfaceClass != CLASS_ID) + break; + if((MASK & CP_MASK_COMPARE_SUBCLASS) && uid->bInterfaceSubClass != SUBCLASS_ID) + break; + if(UseOr) { + if((!((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol))) + break; + } else { + if((MASK & CP_MASK_COMPARE_PROTOCOL) && uid->bInterfaceProtocol != PROTOCOL_ID) + break; + } + isGoodInterface = true; + ifaceNumber = uid->bInterfaceNumber; + ifaceAltSet = uid->bAlternateSetting; + protoValue = uid->bInterfaceProtocol; + break; + case USB_DESCRIPTOR_ENDPOINT: + if(!valParser.Parse(pp, pcntdn)) + return false; + if(isGoodInterface) + if(theXtractor) + theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer); break; //case HID_DESCRIPTOR_HID: // if (!valParser.Parse(pp, pcntdn)) @@ -180,44 +191,47 @@ bool ConfigDescParser::ParseDescriptor theBuffer.pValue = varBuffer; stateParseDescr = 0; } +#pragma GCC diagnostic pop + return true; } template void ConfigDescParser::PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc) { - Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80); - Notify(PSTR("bDescLength:\t\t"), 0x80); - PrintHex (pDesc->bLength, 0x80); + Notify(PSTR("\r\n\r\nHID Descriptor:\r\n"), 0x80); + Notify(PSTR("bDescLength:\t\t"), 0x80); + PrintHex (pDesc->bLength, 0x80); - Notify(PSTR("\r\nbDescriptorType:\t"), 0x80); - PrintHex (pDesc->bDescriptorType, 0x80); + Notify(PSTR("\r\nbDescriptorType:\t"), 0x80); + PrintHex (pDesc->bDescriptorType, 0x80); - Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80); - PrintHex (pDesc->bcdHID, 0x80); + Notify(PSTR("\r\nbcdHID:\t\t\t"), 0x80); + PrintHex (pDesc->bcdHID, 0x80); - Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80); - PrintHex (pDesc->bCountryCode, 0x80); + Notify(PSTR("\r\nbCountryCode:\t\t"), 0x80); + PrintHex (pDesc->bCountryCode, 0x80); - Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80); - PrintHex (pDesc->bNumDescriptors, 0x80); + Notify(PSTR("\r\nbNumDescriptors:\t"), 0x80); + PrintHex (pDesc->bNumDescriptors, 0x80); - //Notify(PSTR("\r\nbDescrType:\t\t")); - //PrintHex(pDesc->bDescrType); - // - //Notify(PSTR("\r\nwDescriptorLength:\t")); - //PrintHex(pDesc->wDescriptorLength); + //Notify(PSTR("\r\nbDescrType:\t\t")); + //PrintHex(pDesc->bDescrType); + // + //Notify(PSTR("\r\nwDescriptorLength:\t")); + //PrintHex(pDesc->wDescriptorLength); for (uint32_t i = 0; i < pDesc->bNumDescriptors; i++) { HID_CLASS_DESCRIPTOR_LEN_AND_TYPE *pLT = (HID_CLASS_DESCRIPTOR_LEN_AND_TYPE*)&(pDesc->bDescrType); - Notify(PSTR("\r\nbDescrType:\t\t"), 0x80); - PrintHex (pLT[i].bDescrType, 0x80); + Notify(PSTR("\r\nbDescrType:\t\t"), 0x80); + PrintHex (pLT[i].bDescrType, 0x80); - Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80); - PrintHex (pLT[i].wDescriptorLength, 0x80); - } - Notify(PSTR("\r\n"), 0x80); + Notify(PSTR("\r\nwDescriptorLength:\t"), 0x80); + PrintHex (pLT[i].wDescriptorLength, 0x80); + } + Notify(PSTR("\r\n"), 0x80); } + #endif // __CONFDESCPARSER_H__ diff --git a/libraries/USBHost/src/hidescriptorparser.cpp b/libraries/USBHost/src/hidescriptorparser.cpp index 353874300..b137cb8ab 100644 --- a/libraries/USBHost/src/hidescriptorparser.cpp +++ b/libraries/USBHost/src/hidescriptorparser.cpp @@ -994,7 +994,6 @@ void ReportDescParserBase::Parse(const uint32_t len, const uint8_t *pbuf, const uint32_t cntdn = (uint32_t)len; uint8_t *p = (uint8_t*)pbuf; - totalSize = 0; while(cntdn) { @@ -1091,6 +1090,17 @@ void ReportDescParserBase::PrintItemTitle(uint8_t prefix) { uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint32_t *pcntdn) { //uint8_t ret = enErrorSuccess; //reinterpret_cast<>(varBuffer); + + +#pragma GCC diagnostic push // Available since GCC 4.6.4 +/* + * FIXME -- Enabled and review all `-Wimplicit-fallthrough` messages + * This code has multiple switch statements that "fall through" to the + * next case -- but it's not always clear if this is intentional or not. + * Review and commenting of code, and reducing cyclomatic complexity + * are highly recommended.... + */ +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" switch(itemParseState) { case 0: if(**pp == HID_LONG_ITEM_PREFIX) @@ -1207,6 +1217,7 @@ uint8_t ReportDescParserBase::ParseItem(uint8_t **pp, uint32_t *pcntdn) { } // switch (**pp & (TYPE_MASK | TAG_MASK)) } } // switch (itemParseState) +#pragma GCC diagnostic pop itemParseState = 0; return enErrorSuccess; } @@ -1236,18 +1247,18 @@ void ReportDescParserBase::SetUsagePage(uint16_t page) { if(VALUE_BETWEEN(page, 0x00, 0x11)) pfUsage = (usagePageFunctions[page - 1]); - // Dead code... - // - // pfUsage = (UsagePageFunc)pgm_read_pointer(usagePageFunctions[page - 1]); - //else if (page > 0x7f && page < 0x84) - // E_Notify(pstrUsagePageMonitor); - //else if (page > 0x83 && page < 0x8c) - // E_Notify(pstrUsagePagePower); - //else if (page > 0x8b && page < 0x92) - // E_Notify((char*)pgm_read_pointer(&usagePageTitles1[page - 0x8c])); - //else if (page > 0xfeff && page <= 0xffff) - // E_Notify(pstrUsagePageVendorDefined); - // + // Dead code... + // + // pfUsage = (UsagePageFunc)pgm_read_pointer(usagePageFunctions[page - 1]); + //else if (page > 0x7f && page < 0x84) + // E_Notify(pstrUsagePageMonitor); + //else if (page > 0x83 && page < 0x8c) + // E_Notify(pstrUsagePagePower); + //else if (page > 0x8b && page < 0x92) + // E_Notify((char*)pgm_read_pointer(&usagePageTitles1[page - 0x8c])); + //else if (page > 0xfeff && page <= 0xffff) + // E_Notify(pstrUsagePageVendorDefined); + // else switch(page) { case 0x14: @@ -1440,6 +1451,15 @@ void ReportDescParserBase::PrintMedicalInstrumentPageUsage(uint16_t usage) { uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint32_t *pcntdn) { //uint8_t ret = enErrorSuccess; +#pragma GCC diagnostic push // Available since GCC 4.6.4 +/* + * FIXME -- Enabled and review all `-Wimplicit-fallthrough` messages + * This code has multiple switch statements that "fall through" to the + * next case -- but it's not always clear if this is intentional or not. + * Review and commenting of code, and reducing cyclomatic complexity + * are highly recommended.... + */ +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" switch(itemParseState) { case 0: if(**pp == HID_LONG_ITEM_PREFIX) @@ -1519,6 +1539,8 @@ uint8_t ReportDescParser2::ParseItem(uint8_t **pp, uint32_t *pcntdn) { } // switch (**pp & (TYPE_MASK | TAG_MASK)) } } // switch (itemParseState) +#pragma GCC diagnostic pop + itemParseState = 0; return enErrorSuccess; } @@ -1558,8 +1580,7 @@ void ReportDescParser2::OnInputItem(uint8_t itm) { // bits_to_copy - number of bits to copy to result buffer // for each bit in a field - for(uint8_t bits_left = rptSize, bits_to_copy = 0; bits_left; - bits_left -= bits_to_copy) { + for(uint8_t bits_left = rptSize, bits_to_copy = 0; bits_left; bits_left -= bits_to_copy) { bits_to_copy = (bits_left > bits_of_byte) ? bits_of_byte : bits_left; result.dwResult <<= bits_to_copy; // Result buffer is shifted by the number of bits to be copied into it diff --git a/libraries/USBHost/src/parsetools.cpp b/libraries/USBHost/src/parsetools.cpp index 00ca9e642..9867cbc46 100644 --- a/libraries/USBHost/src/parsetools.cpp +++ b/libraries/USBHost/src/parsetools.cpp @@ -17,14 +17,14 @@ e-mail : support@circuitsathome.com #include "Usb.h" bool MultiByteValueParser::Parse(uint8_t **pp, uint32_t *pcntdn) { - if(!pBuf) { - Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80); + if(!pBuf) { + Notify(PSTR("Buffer pointer is NULL!\r\n"), 0x80); return false; } for (; countDown && (*pcntdn); countDown--, (*pcntdn)--, (*pp)++) pBuf[valueSize - countDown] = (**pp); - if(countDown) + if(countDown) return false; countDown = valueSize; @@ -32,36 +32,48 @@ bool MultiByteValueParser::Parse(uint8_t **pp, uint32_t *pcntdn) { } bool PTPListParser::Parse(uint8_t **pp, uint32_t *pcntdn, PTP_ARRAY_EL_FUNC pf, const void *me) { - switch(nStage) { - case 0: - pBuf->valueSize = lenSize; - theParser.Initialize(pBuf); - nStage = 1; - case 1: - if(!theParser.Parse(pp, pcntdn)) - return false; +#pragma GCC diagnostic push // Available since GCC 4.6.4 +/* + * FIXME -- Enabled and review all `-Wimplicit-fallthrough` messages + * This code has multiple switch statements that "fall through" to the + * next case -- but it's not always clear if this is intentional or not. + * Review and commenting of code, and reducing cyclomatic complexity + * are highly recommended.... + */ +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" - arLen = 0; - arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue)); - arLenCntdn = arLen; - nStage = 2; + switch(nStage) { + case 0: + pBuf->valueSize = lenSize; + theParser.Initialize(pBuf); + nStage = 1; - case 2: - pBuf->valueSize = valSize; - theParser.Initialize(pBuf); - nStage = 3; - - case 3: - for(; arLenCntdn; arLenCntdn--) { + case 1: if(!theParser.Parse(pp, pcntdn)) return false; + arLen = 0; + arLen = (pBuf->valueSize >= 4) ? *((uint32_t*)pBuf->pValue) : (uint32_t)(*((uint16_t*)pBuf->pValue)); + arLenCntdn = arLen; + nStage = 2; + + case 2: + pBuf->valueSize = valSize; + theParser.Initialize(pBuf); + nStage = 3; + + case 3: + for(; arLenCntdn; arLenCntdn--) { + if(!theParser.Parse(pp, pcntdn)) + return false; + if(pf) pf(pBuf, (arLen - arLenCntdn), me); } - nStage = 0; } +#pragma GCC diagnostic pop + return true; } diff --git a/libraries/USBHost/src/parsetools.h b/libraries/USBHost/src/parsetools.h index d46335891..947ba02dc 100644 --- a/libraries/USBHost/src/parsetools.h +++ b/libraries/USBHost/src/parsetools.h @@ -35,12 +35,12 @@ class MultiByteValueParser { public: - MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) { - }; + MultiByteValueParser() : pBuf(NULL), countDown(0), valueSize(0) { + }; - const uint8_t* GetBuffer() { - return pBuf; - }; + const uint8_t* GetBuffer() { + return pBuf; + }; void Initialize(MultiValueBuffer * const pbuf) { pBuf = (uint8_t*)pbuf->pValue; @@ -58,7 +58,7 @@ class ByteSkipper { public: ByteSkipper() : pBuf(NULL), nStage(0), countDown(0) { - }; + }; void Initialize(MultiValueBuffer *pbuf) { pBuf = (uint8_t*)pbuf->pValue; @@ -66,16 +66,25 @@ class ByteSkipper { }; bool Skip(uint8_t **pp, uint32_t *pcntdn, uint32_t bytes_to_skip) { - switch(nStage) { - case 0: - countDown = bytes_to_skip; - nStage++; - case 1: - for(; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--); - - if(!countDown) - nStage = 0; +#pragma GCC diagnostic push // Available since GCC 4.6.4 +/* + * FIXME -- Enabled and review all `-Wimplicit-fallthrough` messages + * This code has multiple switch statements that "fall through" to the + * next case -- but it's not always clear if this is intentional or not. + * Review and commenting of code, and reducing cyclomatic complexity + * are highly recommended.... + */ +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" + switch(nStage) { + case 0: + countDown = bytes_to_skip; + nStage++; + case 1: + for(; countDown && (*pcntdn); countDown--, (*pp)++, (*pcntdn)--); + if(!countDown) + nStage = 0; }; +#pragma GCC diagnostic pop return (!countDown); }; }; @@ -86,9 +95,9 @@ typedef void (*PTP_ARRAY_EL_FUNC)(const MultiValueBuffer * const p, uint32_t cou class PTPListParser { public: - enum ParseMode { - modeArray, modeRange/*, modeEnum*/ - }; + enum ParseMode { + modeArray, modeRange/*, modeEnum*/ + }; private: uint32_t nStage; diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index b94389b0a..da9732c59 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -24,6 +24,11 @@ extern "C" { #include #include +#ifdef USE_TINYUSB +// For Serial when selecting TinyUSB +#include +#endif + #include "Wire.h" TwoWire::TwoWire(SERCOM * s, uint8_t pinSDA, uint8_t pinSCL) @@ -287,6 +292,13 @@ void TwoWire::onService(void) void WIRE_IT_HANDLER(void) { Wire.onService(); } + + #if defined(__SAMD51__) + void WIRE_IT_HANDLER_0(void) { Wire.onService(); } + void WIRE_IT_HANDLER_1(void) { Wire.onService(); } + void WIRE_IT_HANDLER_2(void) { Wire.onService(); } + void WIRE_IT_HANDLER_3(void) { Wire.onService(); } + #endif // __SAMD51__ #endif #if WIRE_INTERFACES_COUNT > 1 @@ -295,6 +307,13 @@ void TwoWire::onService(void) void WIRE1_IT_HANDLER(void) { Wire1.onService(); } + + #if defined(__SAMD51__) + void WIRE1_IT_HANDLER_0(void) { Wire1.onService(); } + void WIRE1_IT_HANDLER_1(void) { Wire1.onService(); } + void WIRE1_IT_HANDLER_2(void) { Wire1.onService(); } + void WIRE1_IT_HANDLER_3(void) { Wire1.onService(); } + #endif // __SAMD51__ #endif #if WIRE_INTERFACES_COUNT > 2 @@ -303,6 +322,13 @@ void TwoWire::onService(void) void WIRE2_IT_HANDLER(void) { Wire2.onService(); } + + #if defined(__SAMD51__) + void WIRE2_IT_HANDLER_0(void) { Wire2.onService(); } + void WIRE2_IT_HANDLER_1(void) { Wire2.onService(); } + void WIRE2_IT_HANDLER_2(void) { Wire2.onService(); } + void WIRE2_IT_HANDLER_3(void) { Wire2.onService(); } + #endif // __SAMD51__ #endif #if WIRE_INTERFACES_COUNT > 3 @@ -311,6 +337,13 @@ void TwoWire::onService(void) void WIRE3_IT_HANDLER(void) { Wire3.onService(); } + + #if defined(__SAMD51__) + void WIRE3_IT_HANDLER_0(void) { Wire3.onService(); } + void WIRE3_IT_HANDLER_1(void) { Wire3.onService(); } + void WIRE3_IT_HANDLER_2(void) { Wire3.onService(); } + void WIRE3_IT_HANDLER_3(void) { Wire3.onService(); } + #endif // __SAMD51__ #endif #if WIRE_INTERFACES_COUNT > 4 @@ -319,6 +352,13 @@ void TwoWire::onService(void) void WIRE4_IT_HANDLER(void) { Wire4.onService(); } + + #if defined(__SAMD51__) + void WIRE4_IT_HANDLER_0(void) { Wire4.onService(); } + void WIRE4_IT_HANDLER_1(void) { Wire4.onService(); } + void WIRE4_IT_HANDLER_2(void) { Wire4.onService(); } + void WIRE4_IT_HANDLER_3(void) { Wire4.onService(); } + #endif // __SAMD51__ #endif #if WIRE_INTERFACES_COUNT > 5 @@ -327,5 +367,12 @@ void TwoWire::onService(void) void WIRE5_IT_HANDLER(void) { Wire5.onService(); } + + #if defined(__SAMD51__) + void WIRE5_IT_HANDLER_0(void) { Wire5.onService(); } + void WIRE5_IT_HANDLER_1(void) { Wire5.onService(); } + void WIRE5_IT_HANDLER_2(void) { Wire5.onService(); } + void WIRE5_IT_HANDLER_3(void) { Wire5.onService(); } + #endif // __SAMD51__ #endif diff --git a/libraries/Wire/examples/slave_receiver/slave_receiver.ino b/libraries/Wire/examples/slave_receiver/slave_receiver.ino index 60dd4bdde..a3103f8b9 100644 --- a/libraries/Wire/examples/slave_receiver/slave_receiver.ino +++ b/libraries/Wire/examples/slave_receiver/slave_receiver.ino @@ -28,6 +28,8 @@ void loop() // this function is registered as an event, see setup() void receiveEvent(int howMany) { + (void)howMany; // avoid compiler warning about unused parameter + while(1 < Wire.available()) // loop through all but the last { char c = Wire.read(); // receive byte as a character diff --git a/platform.txt b/platform.txt index 2a2e59cc3..747b7e16e 100644 --- a/platform.txt +++ b/platform.txt @@ -17,29 +17,29 @@ # Arduino SAMD Core and platform. # # For more info: -# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification +# https://arduino.github.io/arduino-cli/0.33/platform-specification/ -name=Arduino SAMD (32-bits ARM Cortex-M0+) Boards -version=1.6.21 +name=Adafruit SAMD (32-bits ARM Cortex-M0+ and Cortex-M4) Boards +version=1.7.16 # Compile variables # ----------------- -compiler.warning_flags=-w -compiler.warning_flags.none=-w -compiler.warning_flags.default= -compiler.warning_flags.more=-Wall -compiler.warning_flags.all=-Wall -Wextra +compiler.warning_flags=-Werror=return-type +compiler.warning_flags.none=-Werror=return-type +compiler.warning_flags.default=-Werror=return-type +compiler.warning_flags.more=-Wall -Werror=return-type -Wno-expansion-to-defined +compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-expansion-to-defined -compiler.path={runtime.tools.arm-none-eabi-gcc-4.8.3-2014q1.path}/bin/ +compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/ compiler.c.cmd=arm-none-eabi-gcc -compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD +compiler.c.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -MMD -D__SKETCH_NAME__="""{build.project_name}""" compiler.c.elf.cmd=arm-none-eabi-g++ compiler.c.elf.flags=-Os -Wl,--gc-sections -save-temps compiler.S.cmd=arm-none-eabi-gcc compiler.S.flags=-c -g -x assembler-with-cpp -MMD compiler.cpp.cmd=arm-none-eabi-g++ -compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD +compiler.cpp.flags=-mcpu={build.mcu} -mthumb -c -g -Os {compiler.warning_flags} -std=gnu++11 -ffunction-sections -fdata-sections -fno-threadsafe-statics -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -MMD -D__SKETCH_NAME__="""{build.project_name}""" compiler.ar.cmd=arm-none-eabi-ar compiler.ar.flags=rcs compiler.objcopy.cmd=arm-none-eabi-objcopy @@ -54,6 +54,12 @@ compiler.readelf.cmd=arm-none-eabi-readelf # this can be overriden in boards.txt build.extra_flags= +build.cache_flags= +build.flags.optimize= +build.flags.maxspi= +build.flags.maxqspi= +build.flags.usbstack= +build.flags.debug= # These can be overridden in platform.local.txt compiler.c.extra_flags= @@ -64,28 +70,34 @@ compiler.S.extra_flags= compiler.ar.extra_flags= compiler.elf2hex.extra_flags= -compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Include/" "-I{runtime.tools.CMSIS-Atmel-1.1.0.path}/CMSIS/Device/ATMEL/" -compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-4.5.0.path}/CMSIS/Lib/GCC/" -larm_cortexM0l_math +compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/DSP/Include/" "-I{runtime.tools.CMSIS-Atmel-1.2.2.path}/CMSIS/Device/ATMEL/" +compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" -larm_cortexM0l_math + +compiler.libraries.ldflags= # USB Flags # --------- -build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' +build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON -DUSB_CONFIG_POWER={build.usb_power} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {build.flags.usbstack} {build.flags.debug} "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino" + +# Default advertised device power setting in mA +build.usb_power=100 # Default usb manufacturer will be replaced at compile time using # numeric vendor ID if available or by board's specific value. build.usb_manufacturer="Unknown" + # Compile patterns # ---------------- ## Compile c files -recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_SAMD_ADAFRUIT {compiler.c.extra_flags} {build.extra_flags} {build.cache_flags} {build.flags.debug} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" ## Compile c++ files -recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_SAMD_ADAFRUIT {compiler.cpp.extra_flags} {build.extra_flags} {build.cache_flags} {build.flags.debug} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" ## Compile S files -recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" +recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_SAMD_ADAFRUIT {compiler.S.extra_flags} {build.extra_flags} {build.cache_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" ## Create archives # archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value @@ -93,7 +105,7 @@ archive_file_path={build.path}/{archive_file} recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nano.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} -Wl,--start-group {compiler.arm.cmsis.ldflags} -lm "{build.path}/{archive_file}" -Wl,--end-group +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" --specs=nano.specs --specs=nosys.specs {compiler.ldflags} -o "{build.path}/{build.project_name}.elf" {object_files} {compiler.libraries.ldflags} -Wl,--start-group {compiler.arm.cmsis.ldflags} "-L{build.variant.path}" -lm "{build.path}/{archive_file}" -Wl,--end-group ## Create output (bin file) recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.bin.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" @@ -111,30 +123,10 @@ recipe.output.save_file={build.project_name}.{build.variant}.{build.preferred_ou recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.regex=\.text\s+([0-9]+).* -# Uploader tools -# -------------- - -# -# AVRDUDE -# -tools.avrdude.path={runtime.tools.avrdude.path} -tools.avrdude.cmd={path}/bin/avrdude -tools.avrdude.config.path={path}/etc/avrdude.conf - -tools.avrdude.upload.params.verbose=-v -v -tools.avrdude.upload.params.quiet=-q -q -tools.avrdude.upload.params.noverify=-V -tools.avrdude.upload.pattern="{cmd}" "-C{config.path}" {upload.verbose} -p{build.emu.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} "-Uflash:w:{build.path}/{build.project_name}.hex:i" - -tools.avrdude_remote.upload.pattern="openocd --version 2>&1 | grep 2016 && if opkg update; then opkg upgrade openocd; exit 1; else echo 'Please connect your board to the Internet in order to upgrade tools' >&2; exit 1; fi || /usr/bin/run-avrdude /tmp/sketch.hex" - -tools.avrdude.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA -tools.avrdude.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b - # # BOSSA # -tools.bossac.path={runtime.tools.bossac-1.7.0.path} +tools.bossac.path={runtime.tools.bossac-1.7.0-arduino3.path} tools.bossac.cmd=bossac tools.bossac.cmd.windows=bossac.exe @@ -147,17 +139,47 @@ tools.bossac_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=t tools.bossac.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA tools.bossac.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b +# v1.8.0 + +tools.bossac18.path={runtime.tools.bossac-1.8.0-48-gb176eee.path} +tools.bossac18.cmd=bossac +tools.bossac18.cmd.windows=bossac.exe + +tools.bossac18.upload.params.verbose=-i -d +tools.bossac18.upload.params.quiet= +tools.bossac18.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U -i --offset={upload.offset} -w -v "{build.path}/{build.project_name}.bin" -R + +tools.bossac18.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA +tools.bossac18.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b + +# +# BOSSA (ignore binary size) +# +tools.bossacI.path={runtime.tools.bossac-1.7.0-arduino3.path} +tools.bossacI.cmd=bossac +tools.bossacI.cmd.windows=bossac.exe + +tools.bossacI.upload.params.verbose=-i -d +tools.bossacI.upload.params.quiet= +tools.bossacI.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -I -U {upload.native_usb} -i -e -w "{build.path}/{build.project_name}.bin" -R + +tools.bossacI_remote.upload.pattern=/usr/bin/run-bossac {upload.verbose} --port=ttyATH0 -U {upload.native_usb} -e -w -v /tmp/sketch.bin -R + +tools.bossacI.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA +tools.bossacI.upload.network_pattern="{network_cmd}" -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b + + # # OpenOCD sketch upload # -tools.openocd.path={runtime.tools.openocd-0.9.0-arduino6-static.path} +tools.openocd.path={runtime.tools.openocd-0.11.0-arduino2.path} tools.openocd.cmd=bin/openocd tools.openocd.cmd.windows=bin/openocd.exe tools.openocd.upload.params.verbose=-d2 tools.openocd.upload.params.quiet=-d0 -tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{{build.path}/{build.project_name}.bin}} verify reset 0x2000; shutdown" +tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset 0x2000; shutdown" tools.openocd.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b @@ -165,7 +187,7 @@ tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port # Program flashes the binary at 0x0000, so use the linker script without_bootloader tools.openocd.program.params.verbose=-d2 tools.openocd.program.params.quiet=-d0 -tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{{build.path}/{build.project_name}.elf}} verify reset; shutdown" +tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown" tools.openocd.erase.params.verbose=-d3 tools.openocd.erase.params.quiet=-d0 @@ -173,25 +195,25 @@ tools.openocd.erase.pattern= tools.openocd.bootloader.params.verbose=-d2 tools.openocd.bootloader.params.quiet=-d0 -tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{{runtime.platform.path}/bootloaders/{bootloader.file}}} verify reset; shutdown" +tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; init; halt; $_FLASHDRIVER bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown" # # OpenOCD sketch upload - version with configurable bootloader size # FIXME: this programmer is a workaround for default options being overwritten by uploadUsingPreferences # -tools.openocd-withbootsize.path={runtime.tools.openocd-0.9.0-arduino6-static.path} +tools.openocd-withbootsize.path={runtime.tools.openocd-0.11.0-arduino2.path} tools.openocd-withbootsize.cmd=bin/openocd tools.openocd-withbootsize.cmd.windows=bin/openocd.exe tools.openocd-withbootsize.upload.params.verbose=-d2 tools.openocd-withbootsize.upload.params.quiet=-d0 -tools.openocd-withbootsize.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{{build.path}/{build.project_name}.bin}} verify reset {bootloader.size}; shutdown" +tools.openocd-withbootsize.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset {bootloader.size}; shutdown" # Program flashes the binary at 0x0000, so use the linker script without_bootloader tools.openocd-withbootsize.program.params.verbose=-d2 tools.openocd-withbootsize.program.params.quiet=-d0 -tools.openocd-withbootsize.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{{build.path}/{build.project_name}.elf}} verify reset; shutdown" +tools.openocd-withbootsize.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown" tools.openocd-withbootsize.erase.params.verbose=-d3 tools.openocd-withbootsize.erase.params.quiet=-d0 @@ -199,4 +221,28 @@ tools.openocd-withbootsize.erase.pattern= tools.openocd-withbootsize.bootloader.params.verbose=-d2 tools.openocd-withbootsize.bootloader.params.quiet=-d0 -tools.openocd-withbootsize.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{{runtime.platform.path}/bootloaders/{bootloader.file}}} verify reset; shutdown" +tools.openocd-withbootsize.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; init; halt; $_FLASHDRIVER bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown" + +# ---------------------------------------- +# Debugger configuration (general options) +# ---------------------------------------- +# EXPERIMENTAL feature: +# - this is alpha and may be subject to change without notice +debug.executable={build.path}/{build.project_name}.elf +debug.toolchain=gcc +debug.toolchain.path={runtime.tools.arm-none-eabi-gcc.path}/bin/ +debug.toolchain.prefix=arm-none-eabi- + +debug.server=openocd +debug.server.openocd.path={runtime.tools.openocd-0.11.0-arduino2.path}/bin/openocd +debug.server.openocd.scripts_dir={runtime.tools.openocd-0.11.0-arduino2.path}/share/openocd/scripts/ +debug.server.openocd.script={runtime.platform.path}/{build.openocdscript} + +# JLinkServer is not supported by arduino-cli yet +# https://github.com/arduino/arduino-cli/blob/eca9d9a8f00582a08fadea8a4b7e3ef01b40d082/commands/debug/debug.go#L160 +# use debug_custom.json to run JLinkGDBServer instead +# https://docs.arduino.cc/tutorials/mkr-wifi-1010/mkr-jlink-setup +#debug.server=jlink +#debug.server.jlink.path=JLinkGDBServer +#debug.server.jlink.device=ATSAMD21G18 +#debug.server.jlink.script={runtime.platform.path}/{build.openocdscript} diff --git a/programmers.txt b/programmers.txt index fd7471b7d..f1617e4c1 100644 --- a/programmers.txt +++ b/programmers.txt @@ -14,23 +14,17 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -edbg.name=Atmel EDBG -edbg.communication=USB -edbg.protocol= -edbg.program.protocol= -edbg.program.tool=openocd -edbg.program.extra_params= +adafruit_jlink.name=J-Link over OpenOCD +adafruit_jlink.communication=USB +adafruit_jlink.protocol=jlink +adafruit_jlink.program.protocol=jlink +adafruit_jlink.program.tool=openocd +adafruit_jlink.program.setup_command=interface jlink; transport select swd; reset_config none separate; set WORKAREASIZE 0; -atmel_ice.name=Atmel-ICE -atmel_ice.communication=USB -atmel_ice.protocol= -atmel_ice.program.protocol= -atmel_ice.program.tool=openocd -atmel_ice.program.extra_params= -sam_ice.name=Atmel SAM-ICE -sam_ice.communication=USB -sam_ice.protocol= -sam_ice.program.protocol= -sam_ice.program.tool=openocd -sam_ice.program.extra_params= +adafruit_atmel_ice.name=Atmel-ICE over OpenOCD +adafruit_atmel_ice.communication=USB +adafruit_atmel_ice.protocol=cmsis-dap +adafruit_atmel_ice.program.protocol=cmsis-dap +adafruit_atmel_ice.program.tool=openocd +adafruit_atmel_ice.program.setup_command=cmsis_dap_vid_pid 0x03eb 0x2141; transport select swd; \ No newline at end of file diff --git a/scripts/jlink/samd21/debug_custom.json b/scripts/jlink/samd21/debug_custom.json new file mode 100644 index 000000000..f5b625244 --- /dev/null +++ b/scripts/jlink/samd21/debug_custom.json @@ -0,0 +1,6 @@ +{ + "servertype": "jlink", + "device": "ATSAMD21G18A", + "interface": "SWD", + "serverpath": "JLinkGDBServer" +} diff --git a/scripts/jlink/samd51/debug_custom.json b/scripts/jlink/samd51/debug_custom.json new file mode 100644 index 000000000..13f573953 --- /dev/null +++ b/scripts/jlink/samd51/debug_custom.json @@ -0,0 +1,6 @@ +{ + "servertype": "jlink", + "device": "ATSAMD51G18", + "interface": "SWD", + "serverpath": "JLinkGDBServer" +} diff --git a/scripts/openocd/daplink_samd21.cfg b/scripts/openocd/daplink_samd21.cfg new file mode 100644 index 000000000..6c60b8832 --- /dev/null +++ b/scripts/openocd/daplink_samd21.cfg @@ -0,0 +1,29 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +source [find interface/cmsis-dap.cfg] +transport select swd + +# chip name +set CHIPNAME samd21 + +set _FLASHDRIVER at91samd + +source [find target/at91samdXX.cfg] diff --git a/scripts/openocd/daplink_samd51.cfg b/scripts/openocd/daplink_samd51.cfg new file mode 100644 index 000000000..6aa96d40b --- /dev/null +++ b/scripts/openocd/daplink_samd51.cfg @@ -0,0 +1,29 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +source [find interface/cmsis-dap.cfg] +transport select swd + +# chip name +set CHIPNAME samd51 + +set _FLASHDRIVER atsame5 + +source [find target/atsame5x.cfg] diff --git a/scripts/openocd/jlink_samd21.cfg b/scripts/openocd/jlink_samd21.cfg new file mode 100644 index 000000000..423a5e6bb --- /dev/null +++ b/scripts/openocd/jlink_samd21.cfg @@ -0,0 +1,29 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +source [find interface/jlink.cfg] +transport select swd + +# chip name +set CHIPNAME samd21 + +set _FLASHDRIVER at91samd + +source [find target/at91samdXX.cfg] diff --git a/scripts/openocd/jlink_samd51.cfg b/scripts/openocd/jlink_samd51.cfg new file mode 100644 index 000000000..8e9db6bdb --- /dev/null +++ b/scripts/openocd/jlink_samd51.cfg @@ -0,0 +1,29 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +source [find interface/jlink.cfg] +transport select swd + +# chip name +set CHIPNAME samd51 + +set _FLASHDRIVER atsame5 + +source [find target/atsame5x.cfg] diff --git a/tools/build_all.py b/tools/build_all.py new file mode 100644 index 000000000..f36fd45e2 --- /dev/null +++ b/tools/build_all.py @@ -0,0 +1,106 @@ +import os +import glob +import sys +import subprocess +from subprocess import Popen, PIPE +import time + +SUCCEEDED = "\033[32msucceeded\033[0m" +FAILED = "\033[31mfailed\033[0m" +SKIPPED = "\033[35mskipped\033[0m" +WARNING = "\033[33mwarnings\033[0m " + +exit_status = 0 +success_count = 0 +fail_count = 0 +skip_count = 0 + +build_format = '| {:25} | {:35} | {:18} | {:6} |' +build_separator = '-' * 88 + +FQBN_PREFIX='adafruit:samd:adafruit_' + +#default_boards = [ 'metro_m0', 'metro_m4', 'circuitplayground_m0', 'feather_m4_can', 'metro_m0:usbstack=tinyusb', 'metro_m4:speed=120,usbstack=tinyusb' ] +default_boards = [ 'metro_m0', 'metro_m0:usbstack=tinyusb' ] +build_boards = [] + +# build all variants if input not existed +if len(sys.argv) > 1: + build_boards.append(sys.argv[1]) +else: + build_boards = default_boards + +all_examples = list(glob.iglob('libraries/**/*.ino', recursive=True)) +all_examples.sort() + +def build_examples(variant): + global exit_status, success_count, fail_count, skip_count, build_format, build_separator + + print('\n') + print(build_separator) + print('| {:^84} |'.format('Board ' + variant)) + print(build_separator) + print(build_format.format('Library', 'Example', '\033[39mResult\033[0m', 'Time')) + print(build_separator) + + fqbn = "{}{}".format(FQBN_PREFIX, variant) + + for sketch in all_examples: + start_time = time.monotonic() + + # Skip if contains: ".board.test.skip" or ".all.test.skip" + # Skip if not contains: ".board.test.only" for a specific board + sketchdir = os.path.dirname(sketch) + if os.path.exists(sketchdir + '/.all.test.skip') or os.path.exists(sketchdir + '/.' + variant + '.test.skip'): + success = SKIPPED + skip_count += 1 + elif glob.glob(sketchdir+"/.*.test.only") and not os.path.exists(sketchdir + '/.' + variant + '.test.only'): + success = SKIPPED + skip_count += 1 + elif 'usbstack=tinyusb' not in variant and "libraries/Adafruit_TinyUSB_Arduino" in sketch: + # skip non-tinyusb variant for tinyusb examples + success = SKIPPED + skip_count += 1 + elif 'usbstack=tinyusb' in variant and "libraries/USBHost" in sketch: + # skip -tinyusb variant for USBHost examples + success = SKIPPED + skip_count += 1 + else: + build_result = subprocess.run("arduino-cli compile --warnings all --fqbn {} {}".format(fqbn, sketch), shell=True, stdout=PIPE, stderr=PIPE) + + # get stderr into a form where warning/error was output to stderr + if build_result.returncode != 0: + exit_status = build_result.returncode + success = FAILED + fail_count += 1 + else: + success_count += 1 + if build_result.stderr: + success = WARNING + else: + success = SUCCEEDED + + build_duration = time.monotonic() - start_time + + print(build_format.format(sketch.split(os.path.sep)[1], os.path.basename(sketch), success, '{:5.2f}s'.format(build_duration))) + + if success != SKIPPED: + # Build failed + if build_result.returncode != 0: + print(build_result.stdout.decode("utf-8")) + + # Build with warnings + if build_result.stderr: + print(build_result.stderr.decode("utf-8")) + +build_time = time.monotonic() + +for board in build_boards: + build_examples(board) + +print(build_separator) +build_time = time.monotonic() - build_time +print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, build_time)) +print(build_separator) + +sys.exit(exit_status) diff --git a/tools/makeboards.py b/tools/makeboards.py new file mode 100755 index 000000000..fb5b8997b --- /dev/null +++ b/tools/makeboards.py @@ -0,0 +1,414 @@ +#!/usr/bin/env python3 + +print('''# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +''') + +mcu_dict = { + 'SAMD21': { + 'flash_size': 262144, + 'data_size': 0, + 'offset': '0x2000', + 'build_mcu': 'cortex-m0plus', + 'f_cpu': '48000000L', + 'extra_flags': '-DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS', + 'openocdscript': 'scripts/openocd/daplink_samd21.cfg', + }, + + 'SAMD51': { + 'flash_size': 507904, # SAMD51P20A and SAMD51J20A has 1032192 + 'data_size': 0, + 'offset': '0x4000', + 'build_mcu': 'cortex-m4', + 'f_cpu': '120000000L', + 'extra_flags': '-D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16', + 'openocdscript': 'scripts/openocd/daplink_samd51.cfg', + }, + + 'SAME51': { + 'flash_size': 507904, + 'data_size': 0, + 'offset': '0x4000', + 'build_mcu': 'cortex-m4', + 'f_cpu': '120000000L', + 'extra_flags': '-D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16', + 'openocdscript': 'scripts/openocd/daplink_samd51.cfg', + }, +} + + +def build_header(mcu, name, vendor, product, vid, pid_list): + prettyname = f"{vendor} {product} ({mcu})" + print() + print("# -----------------------------------") + print(f"# {prettyname}") + print("# -----------------------------------") + print(f"{name}.name={prettyname}") + print() + + print("# VID/PID for Bootloader, Arduino & CircuitPython") + for i in range(len(pid_list)): + print(f"{name}.vid.{i}={vid}") + print(f"{name}.pid.{i}={pid_list[i]}") + print() + + +def build_upload(mcu, name, extra_flags): + print("# Upload") + print(f"{name}.upload.tool=bossac18") + print(f"{name}.upload.protocol=sam-ba") + + if ('SAMD51P20A' in extra_flags) or ('SAMD51J20A' in extra_flags): + flash_size = 1032192 + else: + flash_size = mcu_dict[mcu]['flash_size'] + print(f"{name}.upload.maximum_size={flash_size}") + #print(f"{name}.upload.maximum_data_size={mcu_dict[mcu]['data_size']}") + + print(f"{name}.upload.offset={mcu_dict[mcu]['offset']}") + print(f"{name}.upload.use_1200bps_touch=true") + print(f"{name}.upload.wait_for_upload_port=true") + print(f"{name}.upload.native_usb=true") + print() + + +def build_build(mcu, name, variant, vendor, product, vid, pid_list, boarddefine, extra_flags, bootloader): + mcu_properties = mcu_dict[mcu] + + print("# Build") + print(f"{name}.build.mcu={mcu_properties['build_mcu']}") + print(f"{name}.build.f_cpu={mcu_properties['f_cpu']}") + print(f'{name}.build.usb_product="{product}"') + print(f'{name}.build.usb_manufacturer="{vendor}"') + print(f"{name}.build.board={boarddefine}") + print(f"{name}.build.core=arduino") + + # Due to fastLed issue https://github.com/FastLED/FastLED/issues/1363 + # although there is a simple fix already https://github.com/FastLED/FastLED/pull/1424 + # fastLED is not well maintained, and we need to skip ARDUINO_SAMD_ZERO for affected boards + # in the long run we should move all of our libraries away from ARDUINO_SAMD_ZERO + if variant in [ 'gemma_m0', 'trinket_m0', 'qtpy_m0', 'itsybitsy_m0' ]: + print(f"{name}.build.extra_flags={extra_flags} -DARM_MATH_CM0PLUS {{build.usb_flags}}") + else: + print(f"{name}.build.extra_flags={extra_flags} {mcu_properties['extra_flags']} {{build.usb_flags}}") + + print(f"{name}.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld") + print(f"{name}.build.openocdscript={mcu_properties['openocdscript']}") + print(f"{name}.build.variant={variant}") + print(f"{name}.build.variant_system_lib=") + print(f"{name}.build.vid={vid}") + print(f"{name}.build.pid={pid_list[0]}") + print(f"{name}.bootloader.tool=openocd") + print(f"{name}.bootloader.file={bootloader}") + if (mcu == 'SAMD51' or mcu == 'SAME51'): + print(f'{name}.compiler.arm.cmsis.ldflags="-L{{runtime.tools.CMSIS-5.4.0.path}}/CMSIS/Lib/GCC/" "-L{{build.variant.path}}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16') + print() + + +def build_menu(mcu, name): + if (mcu == 'SAMD51' or mcu == 'SAME51'): + print("# Menu: Cache") + print(f"{name}.menu.cache.on=Enabled") + print(f"{name}.menu.cache.on.build.cache_flags=-DENABLE_CACHE") + print(f"{name}.menu.cache.off=Disabled") + print(f"{name}.menu.cache.off.build.cache_flags=") + print() + + print("# Menu: Speed") + print(f"{name}.menu.speed.120=120 MHz (standard)") + print(f"{name}.menu.speed.120.build.f_cpu=120000000L") + print(f"{name}.menu.speed.150=150 MHz (overclock)") + print(f"{name}.menu.speed.150.build.f_cpu=150000000L") + print(f"{name}.menu.speed.180=180 MHz (overclock)") + print(f"{name}.menu.speed.180.build.f_cpu=180000000L") + print(f"{name}.menu.speed.200=200 MHz (overclock)") + print(f"{name}.menu.speed.200.build.f_cpu=200000000L") + print() + + print("# Menu: Optimization") + print(f"{name}.menu.opt.small=Small (-Os) (standard)") + print(f"{name}.menu.opt.small.build.flags.optimize=-Os") + print(f"{name}.menu.opt.fast=Fast (-O2)") + print(f"{name}.menu.opt.fast.build.flags.optimize=-O2") + print(f"{name}.menu.opt.faster=Faster (-O3)") + print(f"{name}.menu.opt.faster.build.flags.optimize=-O3") + print(f"{name}.menu.opt.fastest=Fastest (-Ofast)") + print(f"{name}.menu.opt.fastest.build.flags.optimize=-Ofast") + print(f"{name}.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops)") + print(f"{name}.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops") + print() + + if (mcu == 'SAMD51' or mcu == 'SAME51'): + print("# Menu: QSPI Speed") + print(f"{name}.menu.maxqspi.50=50 MHz (standard)") + print(f"{name}.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000") + print(f"{name}.menu.maxqspi.fcpu=CPU Speed / 2") + print(f"{name}.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({{build.f_cpu}})") + print() + + print("# Menu: USB Stack") + print(f"{name}.menu.usbstack.arduino=Arduino") + print(f"{name}.menu.usbstack.tinyusb=TinyUSB") + print(f"{name}.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB") + print() + + print("# Menu: Debug") + print(f"{name}.menu.debug.off=Off") + print(f"{name}.menu.debug.on=On") + print(f"{name}.menu.debug.on.build.flags.debug=-g") + print() + + # comment out for now since debugger selection does not work, debug does not pickup the right openocd script + # print("# Menu: Debugger") + # script_mcu = 'samd21' if mcu == 'SAMD21' else 'samd51' + # print(f"{name}.menu.debugger.daplink=CMSIS-DAP (DAPLink)") + # print(f"{name}.menu.debugger.daplink.build.openocdscript=scripts/openocd/daplink_{script_mcu}.cfg") + # print(f"{name}.menu.debugger.jlink=J-Link") + # print(f"{name}.menu.debugger.jlink.build.openocdscript=scripts/openocd/jlink_{script_mcu}.cfg") + + +def build_global_menu(): + print("menu.cache=Cache") + print("menu.speed=CPU Speed") + print("menu.opt=Optimize") + print("menu.maxqspi=Max QSPI") + print("menu.usbstack=USB Stack") + print("menu.debug=Debug") + #print("menu.debugger=Debugger") + + +def make_board(mcu, name, variant, vendor, product, vid, pid_list, boarddefine, extra_flags, bootloader): + build_header(mcu, name, vendor, product, vid, pid_list) + build_upload(mcu, name, extra_flags) + build_build(mcu, name, variant, vendor, product, vid, pid_list, boarddefine, extra_flags, bootloader) + build_menu(mcu, name) + + +# ------------------------------ +# main +# ------------------------------ + +build_global_menu() + +# ------------------------------ +# SAM D21 (M0) +# ------------------------------ + +# name, variant, vendor, product, vid, pid_list, boarddefine, extra_flags, bootloader +# try to sort in Alphabetical order +d21_board_list = [ + ["adafruit_feather_m0", "feather_m0", "Adafruit", "Feather M0", + "0x239A", ["0x800B", "0x000B", "0x0015"], + "SAMD_ZERO", "-D__SAMD21G18A__ -DADAFRUIT_FEATHER_M0", + "featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin"], + + ["adafruit_feather_m0_express", "feather_m0_express", "Adafruit", "Feather M0 Express", + "0x239A", ["0x801B", "0x001B"], + "SAMD_FEATHER_M0_EXPRESS", "-D__SAMD21G18A__ -DARDUINO_SAMD_FEATHER_M0 -DADAFRUIT_FEATHER_M0_EXPRESS", + "featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin"], + + ["adafruit_metro_m0", "metro_m0", "Adafruit", "Metro M0 Express", + "0x239A", ["0x8013", "0x0013"], + "SAMD_ZERO", "-D__SAMD21G18A__ -DADAFRUIT_METRO_M0_EXPRESS", + "metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.bin"], + + ["adafruit_circuitplayground_m0", "circuitplay", "Adafruit", "Circuit Playground Express", + "0x239A", ["0x8018", "0x0019"], + "SAMD_CIRCUITPLAYGROUND_EXPRESS", "-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_CIRCUITPLAYGROUND_M0", + "circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.bin"], + + ["adafruit_gemma_m0", "gemma_m0", "Adafruit", "Gemma M0", + "0x239A", ["0x801C", "0x001C"], + "GEMMA_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_GEMMA_M0", + "gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.bin"], + + ["adafruit_trinket_m0", "trinket_m0", "Adafruit", "Trinket M0", + "0x239A", ["0x801E", "0x001E"], + "TRINKET_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_TRINKET_M0", + "trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.bin"], + + ["adafruit_qtpy_m0", "qtpy_m0", "Adafruit", "QT Py M0", + "0x239A", ["0x80CB", "0x00CB", "0x00CC"], + "QTPY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_QTPY_M0", + "qtpyM0/bootloader-qtpy_m0.bin"], + + ["adafruit_neotrinkey_m0", "neotrinkey_m0", "Adafruit", "NeoPixel Trinkey M0", + "0x239A", ["0x80EF", "0x00EF", "0x80F0"], + "NEOTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_NEOTRINKEY_M0", + "neotrinkey_m0/bootloader-neotrinkey_m0.bin"], + + ["adafruit_rotarytrinkey_m0", "rotarytrinkey_m0", "Adafruit", "Rotary Trinkey M0", + "0x239A", ["0x80FB", "0x00FB", "0x80FC"], + "ROTARYTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_ROTARYTRINKEY_M0", + "rotarytrinkey_m0/bootloader-rotarytrinkey_m0.bin"], + + ["adafruit_neokeytrinkey_m0", "neokeytrinkey_m0", "Adafruit", "NeoKey Trinkey M0", + "0x239A", ["0x80FF", "0x00FF", "0x8100"], + "NEOKEYTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_NEOKEYTRINKEY_M0", + "neokeytrinkey_m0/bootloader-neokeytrinkey_m0.bin"], + + ["adafruit_slidetrinkey_m0", "slidetrinkey_m0", "Adafruit", "Slide Trinkey M0", + "0x239A", ["0x8101", "0x0101", "0x8102"], + "SLIDETRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_SLIDETRINKEY_M0", + "slidetrinkey_m0/bootloader-slidetrinkey_m0.bin"], + + ["adafruit_proxlighttrinkey_m0", "proxlighttrinkey_m0", "Adafruit", "ProxLight Trinkey M0", + "0x239A", ["0x8103", "0x0103", "0x8104"], + "PROXLIGHTTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PROXLIGHTTRINKEY_M0", + "proxlighttrinkey_m0/bootloader-proxlighttrinkey_m0.bin"], + + ["adafruit_sht4xtrinkey_m0", "sht4xtrinkey_m0", "Adafruit", "SHT4x Trinkey M0", + "0x239A", ["0x8153", "0x0153", "0x8154"], + "SHT4XTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_SHT4XTRINKEY_M0", + "sht4xtrinkey_m0/bootloader-sht4xtrinkey_m0.bin"], + + ["adafruit_pixeltrinkey_m0", "pixeltrinkey_m0", "Adafruit", "Pixel Trinkey M0", + "0x239A", ["0x8155", "0x0155", "0x8156"], + "PIXELTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PIXELTRINKEY_M0", + "pixeltrinkey_m0/bootloader-pixeltrinkey_m0.bin"], + + ["adafruit_TRRStrinkey_m0", "trrstrinkey_m0", "Adafruit", "TRRS Trinkey M0", + "0x239A", ["0x8157", "0x0157", "0x8158"], + "TRRSTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_TRRSTRINKEY_M0", + "trrstrinkey_m0/bootloader-TRRStrinkey_m0.bin"], + + ["adafruit_thumbsticktrinkey_m0", "thumbsticktrinkey_m0", "Adafruit", "Thumbstick Trinkey M0", + "0x239A", ["0x8159", "0x0159", "0x8160"], + "THUMBSTICKTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_THUMBSTICKTRINKEY_M0", + "thumbsticktrinkey_m0/bootloader-thumbsticktrinkey_m0.bin"], + + ["adafruit_itsybitsy_m0", "itsybitsy_m0", "Adafruit", "ItsyBitsy M0 Express", + "0x239A", ["0x800F", "0x000F", "0x8012"], + "ITSYBITSY_M0", "-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_ITSYBITSY_M0", + "itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.bin"], + + ["adafruit_pirkey", "pirkey", "Adafruit", "pIRKey", + "0x239A", ["0x8027", "0x0027", "0x8028"], + "PIRKEY", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PIRKEY", + "pirkey/bootloader-pirkey-v2.0.0-adafruit.5.bin"], + + ["adafruit_hallowing", "hallowing_m0_express", "Adafruit", "Hallowing M0", + "0x239A", ["0xDEAD", "0xD1ED", "0xB000"], + "SAMD_HALLOWING", "-D__SAMD21G18A__ -DCRYSTALLESS -DARDUINO_SAMD_HALLOWING_M0 -DADAFRUIT_HALLOWING", + "hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.bin"], + + ["adafruit_crickit_m0", "crickit_m0", "Adafruit", "Crickit M0", + "0x239A", ["0x802D", "0x002D", "0x802D"], + "CRICKIT_M0", "-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_CRICKIT_M0", + "crickit/samd21_sam_ba.bin"], + + ["adafruit_blm_badge", "blm_badge", "Adafruit", "BLM Badge", + "0x239A", ["0x80BF", "0x00BF", "0x80C0"], + "BLM_BADGE_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_BLM_BADGE", + "blmbadge/bootloader-blm_badge.bin"], +] + +for b in d21_board_list: + make_board("SAMD21", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]) + + +# ---------------------------- +# SAM D51 and E51 (M4) +# ---------------------------- + +d51_board_list = [ + ["adafruit_metro_m4", "metro_m4", "Adafruit", "Metro M4", + "0x239A", ["0x8020", "0x0020", "0x8021", "0x0021"], + "METRO_M4", "-D__SAMD51J19A__ -DADAFRUIT_METRO_M4_EXPRESS", + "metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_grandcentral_m4", "grand_central_m4", "Adafruit", "Grand Central M4", + "0x239A", ["0x8031", "0x0031", "0x0032"], + "GRAND_CENTRAL_M4", "-D__SAMD51P20A__ -DADAFRUIT_GRAND_CENTRAL_M4", + "grand_central_m4/bootloader-grandcentral_m4.bin"], + + ["adafruit_itsybitsy_m4", "itsybitsy_m4", "Adafruit", "ItsyBitsy M4", + "0x239A", ["0x802B", "0x002B"], + "ITSYBITSY_M4", "-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_ITSYBITSY_M4_EXPRESS", + "itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_feather_m4", "feather_m4", "Adafruit", "Feather M4 Express", + "0x239A", ["0x8022", "0x0022", "0x8026"], + "FEATHER_M4", "-D__SAMD51J19A__ -DADAFRUIT_FEATHER_M4_EXPRESS", + "featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_feather_m4_can", "feather_m4_can", "Adafruit", "Feather M4 CAN", + "0x239A", ["0x80CD", "0x00CD"], + "FEATHER_M4_CAN", "-D__SAME51J19A__ -DADAFRUIT_FEATHER_M4_EXPRESS -DADAFRUIT_FEATHER_M4_CAN", + "featherM4/bootloader-feather_m4_express-v2.0.0-adafruit.5.bin"], + + # ["adafruit_feather_m4_log", "feather_m4_log", "Adafruit", "Feather M4 Adalogger", + # "0x239A", ["0x8115", "0x0115", "0x8116"], + # "FEATHER_M4_ADALOGGER", "-D__SAME51J19A__ -DADAFRUIT_FEATHER_M4_ADALOGGER", + # "feather_m4_log/bootloader-feather_m4_log-v2.0.0-adafruit.5.bin"], + + ["adafruit_trellis_m4", "trellis_m4", + "Adafruit", "Trellis M4", "0x239A", ["0x802F", "0x002F", "0x0030"], + "TRELLIS_M4", "-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_TRELLIS_M4_EXPRESS", + "trellisM4/bootloader-trellis_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_pyportal_m4", "pyportal_m4", "Adafruit", "PyPortal M4", + "0x239A", ["0x8035", "0x0035", "0x8036"], + "PYPORTAL_M4", "-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYPORTAL", + "metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_pyportal_m4_titano", "pyportal_m4_titano", "Adafruit", "PyPortal M4 Titano", + "0x239A", ["0x8053", "0x8053"], + "PYPORTAL_M4_TITANO", "-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYPORTAL_M4_TITANO", + "metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_pybadge_m4", "pybadge_m4", "Adafruit", "pyBadge M4 Express", + "0x239A", ["0x8033", "0x0033", "0x8034", "0x0034"], + "PYBADGE_M4", "-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_PYBADGE_M4_EXPRESS", + "featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_metro_m4_airliftlite", "metro_m4_airlift", "Adafruit", "Metro M4 AirLift Lite", + "0x239A", ["0x8037", "0x0037"], + "METRO_M4_AIRLIFT_LITE", "-D__SAMD51J19A__ -DADAFRUIT_METRO_M4_AIRLIFT_LITE", + "metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_pygamer_m4", "pygamer_m4", "Adafruit", "PyGamer M4 Express", + "0x239A", ["0x803D", "0x003D", "0x803E"], + "PYGAMER_M4", "-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_PYGAMER_M4_EXPRESS", + "featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_pybadge_airlift_m4", "pybadge_airlift_m4", "Adafruit", "pyBadge AirLift M4", + "0x239A", ["0x8043", "0x0043", "0x8044"], + "PYBADGE_AIRLIFT_M4", "-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYBADGE_AIRLIFT_M4", + "featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_monster_m4sk", "monster_m4sk", "Adafruit", "MONSTER M4SK", + "0x239A", ["0x8047", "0x0047", "0x8048"], + "MONSTER_M4SK", "-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_MONSTER_M4SK_EXPRESS", + "featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_hallowing_m4", "hallowing_m4", "Adafruit", "Hallowing M4", + "0x239A", ["0x8049", "0x0049", "0x804A"], + "HALLOWING_M4", "-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_HALLOWING_M4_EXPRESS", + "featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"], + + ["adafruit_matrixportal_m4", "matrixportal_m4", "Adafruit", "Matrix Portal M4", + "0x239A", ["0x80C9", "0x00C9", "0x80CA"], + "MATRIXPORTAL_M4", "-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_MATRIXPORTAL_M4_EXPRESS", + "matrixportalM4/bootloader-matrixportal_m4.bin"], +] + +for b in d51_board_list: + # M4 CAN is the only SAME51 + if b[0] == "adafruit_feather_m4_can": + make_board("SAME51", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]) + else: + make_board("SAMD51", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8]) diff --git a/variants/arduino_mzero/variant.h b/variants/arduino_mzero/variant.h index 4bb8460b8..b48fde2ed 100755 --- a/variants/arduino_mzero/variant.h +++ b/variants/arduino_mzero/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) /** Master clock frequency */ -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) /*---------------------------------------------------------------------------- * Headers diff --git a/variants/arduino_zero/variant.cpp b/variants/arduino_zero/variant.cpp index 90769a984..dfbaf745a 100644 --- a/variants/arduino_zero/variant.cpp +++ b/variants/arduino_zero/variant.cpp @@ -131,8 +131,8 @@ const PinDescription g_APinDescription[]= { PORTA, 21, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_5 }, // TCC0/WO[7] // Digital High - { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] - { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // TCC0/WO[3] @@ -214,7 +214,7 @@ SERCOM sercom4( SERCOM4 ) ; SERCOM sercom5( SERCOM5 ) ; Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; -Uart Serial( &sercom5, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ) ; +Uart Serial5( &sercom5, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ) ; void SERCOM0_Handler() { Serial1.IrqHandler(); @@ -222,6 +222,6 @@ void SERCOM0_Handler() void SERCOM5_Handler() { - Serial.IrqHandler(); + Serial5.IrqHandler(); } diff --git a/variants/arduino_zero/variant.h b/variants/arduino_zero/variant.h index 3856a9838..196ef773b 100644 --- a/variants/arduino_zero/variant.h +++ b/variants/arduino_zero/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) /** Master clock frequency */ -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) /*---------------------------------------------------------------------------- * Headers @@ -54,8 +54,8 @@ extern "C" // Number of pins defined in PinDescription array #define PINS_COUNT (26u) -#define NUM_DIGITAL_PINS (20u) -#define NUM_ANALOG_INPUTS (6u) +#define NUM_DIGITAL_PINS (14u) +#define NUM_ANALOG_INPUTS (8u) #define NUM_ANALOG_OUTPUTS (1u) #define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) @@ -94,6 +94,8 @@ extern "C" #define PIN_A3 (17ul) #define PIN_A4 (18ul) #define PIN_A5 (19ul) +#define PIN_A6 (8ul) +#define PIN_A7 (9ul) #define PIN_DAC0 (14ul) static const uint8_t A0 = PIN_A0; @@ -102,6 +104,8 @@ static const uint8_t A2 = PIN_A2; static const uint8_t A3 = PIN_A3; static const uint8_t A4 = PIN_A4; static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; static const uint8_t DAC0 = PIN_DAC0; #define ADC_RESOLUTION 12 @@ -193,7 +197,7 @@ extern SERCOM sercom3; extern SERCOM sercom4; extern SERCOM sercom5; -extern Uart Serial; +extern Uart Serial5; extern Uart Serial1; #endif @@ -213,7 +217,7 @@ extern Uart Serial1; // // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX // pins are NOT connected to anything by default. -#define SERIAL_PORT_USBVIRTUAL SerialUSB +#define SERIAL_PORT_USBVIRTUAL Serial #define SERIAL_PORT_MONITOR Serial // Serial has no physical pins broken out, so it's not listed as HARDWARE port #define SERIAL_PORT_HARDWARE Serial1 diff --git a/variants/mkrgsm1400/debug_scripts/variant.gdb b/variants/blm_badge/debug_scripts/variant.gdb similarity index 100% rename from variants/mkrgsm1400/debug_scripts/variant.gdb rename to variants/blm_badge/debug_scripts/variant.gdb diff --git a/variants/blm_badge/linker_scripts/gcc/flash_with_bootloader.ld b/variants/blm_badge/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..4475f9511 --- /dev/null +++ b/variants/blm_badge/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,211 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/blm_badge/linker_scripts/gcc/flash_without_bootloader.ld b/variants/blm_badge/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0162f0774 --- /dev/null +++ b/variants/blm_badge/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,212 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/blm_badge/openocd_scripts/gemma_m0.cfg b/variants/blm_badge/openocd_scripts/gemma_m0.cfg new file mode 100644 index 000000000..93d782d39 --- /dev/null +++ b/variants/blm_badge/openocd_scripts/gemma_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Gemma M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/mkrgsm1400/pins_arduino.h b/variants/blm_badge/pins_arduino.h similarity index 100% rename from variants/mkrgsm1400/pins_arduino.h rename to variants/blm_badge/pins_arduino.h diff --git a/variants/blm_badge/variant.cpp b/variants/blm_badge/variant.cpp new file mode 100644 index 000000000..805b6e262 --- /dev/null +++ b/variants/blm_badge/variant.cpp @@ -0,0 +1,95 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // GPIO 0 - I2S Data + { PORTA, 8, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, + + // GPIO 1 - Cap touch 1 + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + + // GPIO 2 - Cap touch 2 + { PORTA, 4, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // TCC0/WO[0] + + // GPIO 3 - Cap touch 3 + { PORTA, 6, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + + // GPIO 4 - Cap touch 4 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + + // GPIO 5 - Stemma I2C SDA + { PORTA, 0, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // SDA + + // GPIO 6 - Stemma I2C SCL + { PORTA, 1, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // SCL + + // GPIO 7 - PDM clock + { PORTA, 10, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel18, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + + // D8/A0 - CT1 + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + // D9/A1 - CT2 + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // TCC0/WO[0] + // D10/A2 - CT3 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + // D11/A3 - CT4 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + + // D12/A4 - Light + { PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel19, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + + // D13 - LED + { PORTA, 3, PIO_DIGITAL, 0, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // LED + + // GPIO 14 - NeoPixel + { PORTA, 5, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, + + // GPIO 15 & 16 (SWCLK & SWDIO) + // -------------------------- + { PORTA, 30, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 31, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 17..19 - USB + // -------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); +} + diff --git a/variants/blm_badge/variant.h b/variants/blm_badge/variant.h new file mode 100644 index 000000000..dbee168d1 --- /dev/null +++ b/variants/blm_badge/variant.h @@ -0,0 +1,192 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ADAFRUIT_BLMBADGE_ +#define _VARIANT_ADAFRUIT_BLMBADGE_ + +// The definitions here needs a SAMD core >=1.6.6 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10606 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (20u) +#define NUM_DIGITAL_PINS (17u) +#define NUM_ANALOG_INPUTS (5u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 3u) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (13u) +#define PIN_LED_TXL (13u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 + +// Neopixel LED +#define PIN_NEOPIXEL 14 +#define NEOPIXEL_NUM 6 + +/* + * Analog pins + */ +#define PIN_A0 (8ul) +#define PIN_A1 (9ul) +#define PIN_A2 (10ul) +#define PIN_A3 (11ul) +#define PIN_A4 (12ul) + +#define PIN_DAC0 (PIN_A0) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +/* + * Serial interfaces + */ + +// Serial1 (sercom 0) +#define PIN_SERIAL1_RX (3ul) // captouch pad +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_2) +#define PIN_SERIAL1_TX (2ul) // captouch pad +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 0 // we'll just have SPI CLK and MOSI on sercom 0, no MISO + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (5u) +#define PIN_WIRE_SCL (6u) +#define PERIPH_WIRE sercom1 +//#define WIRE_IT_HANDLER // hack! we call the i2c handler from within the serial handler! + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (17ul) +#define PIN_USB_DM (18ul) +#define PIN_USB_DP (19ul) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ADAFRUIT_BLMBADGE_ */ + diff --git a/variants/circuitplay/openocd_scripts/circuitplay.cfg b/variants/circuitplay/openocd_scripts/circuitplay.cfg new file mode 100644 index 000000000..e203ef3b0 --- /dev/null +++ b/variants/circuitplay/openocd_scripts/circuitplay.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Circuit Playground OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/circuitplay/variant.cpp b/variants/circuitplay/variant.cpp index 1aa76015f..0e39cf35e 100644 --- a/variants/circuitplay/variant.cpp +++ b/variants/circuitplay/variant.cpp @@ -15,94 +15,6 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * + Pin number + ZERO Board pin | PIN | Label/Name | Comments (* is for default peripheral in use) - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | Digital Low | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 0 | 0 -> RX | PA11 | | EIC/EXTINT[11] ADC/AIN[19] PTC/X[3] *SERCOM0/PAD[3] SERCOM2/PAD[3] TCC0/WO[3] TCC1/WO[1] - * | 1 | 1 <- TX | PA10 | | EIC/EXTINT[10] ADC/AIN[18] PTC/X[2] *SERCOM0/PAD[2] TCC0/WO[2] TCC1/WO[0] - * | 2 | 2 | PA14 | | EIC/EXTINT[14] SERCOM2/PAD[2] SERCOM4/PAD[2] TC3/WO[0] TCC0/WO[4] - * | 3 | ~3 | PA09 | | EIC/EXTINT[9] ADC/AIN[17] PTC/X[1] SERCOM0/PAD[1] SERCOM2/PAD[1] *TCC0/WO[1] TCC1/WO[3] - * | 4 | ~4 | PA08 | | EIC/NMI ADC/AIN[16] PTC/X[0] SERCOM0/PAD[0] SERCOM2/PAD[0] *TCC0/WO[0] TCC1/WO[2] - * | 5 | ~5 | PA15 | | EIC/EXTINT[15] SERCOM2/PAD[3] SERCOM4/PAD[3] *TC3/WO[1] TCC0/WO[5] - * | 6 | ~6 | PA20 | | EIC/EXTINT[4] PTC/X[8] SERCOM5/PAD[2] SERCOM3/PAD[2] *TCC0/WO[6] - * | 7 | 7 | PA21 | | EIC/EXTINT[5] PTC/X[9] SERCOM5/PAD[3] SERCOM3/PAD[3] TCC0/WO[7] - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | Digital High | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 8 | ~8 | PA06 | | EIC/EXTINT[6] ADC/AIN[6] AC/AIN[2] PTC/Y[4] SERCOM0/PAD[2] *TCC1/WO[0] - * | 9 | ~9 | PA07 | | EIC/EXTINT[7] ADC/AIN[7] AC/AIN[3] PTC/Y[5] SERCOM0/PAD[3] *TCC1/WO[1] - * | 10 | ~10 | PA18 | | EIC/EXTINT[2] PTC/X[6] +SERCOM1/PAD[2] SERCOM3/PAD[2] *TC3/WO[0] TCC0/WO[2] - * | 11 | ~11 | PA16 | | EIC/EXTINT[0] PTC/X[4] +SERCOM1/PAD[0] SERCOM3/PAD[0] *TCC2/WO[0] TCC0/WO[6] - * | 12 | ~12 | PA19 | | EIC/EXTINT[3] PTC/X[7] +SERCOM1/PAD[3] SERCOM3/PAD[3] TC3/WO[1] *TCC0/WO[3] - * | 13 | ~13 | PA17 | LED | EIC/EXTINT[1] PTC/X[5] +SERCOM1/PAD[1] SERCOM3/PAD[1] *TCC2/WO[1] TCC0/WO[7] - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | Analog Connector | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 14 | A0 | PA02 | A0 | EIC/EXTINT[2] *ADC/AIN[0] DAC/VOUT PTC/Y[0] - * | 15 | A1 | PB08 | A1 | EIC/EXTINT[8] *ADC/AIN[2] PTC/Y[14] SERCOM4/PAD[0] TC4/WO[0] - * | 16 | A2 | PB09 | A2 | EIC/EXTINT[9] *ADC/AIN[3] PTC/Y[15] SERCOM4/PAD[1] TC4/WO[1] - * | 17 | A3 | PA04 | A3 | EIC/EXTINT[4] *ADC/AIN[4] AC/AIN[0] PTC/Y[2] SERCOM0/PAD[0] TCC0/WO[0] - * | 18 | A4 | PA05 | A4 | EIC/EXTINT[5] *ADC/AIN[5] AC/AIN[1] PTC/Y[5] SERCOM0/PAD[1] TCC0/WO[1] - * | 19 | A5 | PB02 | A5 | EIC/EXTINT[2] *ADC/AIN[10] PTC/Y[8] SERCOM5/PAD[0] - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | Wire | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 20 | SDA | PA22 | SDA | EIC/EXTINT[6] PTC/X[10] *SERCOM3/PAD[0] SERCOM5/PAD[0] TC4/WO[0] TCC0/WO[4] - * | 21 | SCL | PA23 | SCL | EIC/EXTINT[7] PTC/X[11] *SERCOM3/PAD[1] SERCOM5/PAD[1] TC4/WO[1] TCC0/WO[5] - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | |SPI (Legacy ICSP) | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 22 | 1 | PA12 | MISO | EIC/EXTINT[12] SERCOM2/PAD[0] *SERCOM4/PAD[0] TCC2/WO[0] TCC0/WO[6] - * | | 2 | | 5V0 | - * | 23 | 4 | PB10 | MOSI | EIC/EXTINT[10] *SERCOM4/PAD[2] TC5/WO[0] TCC0/WO[4] - * | 24 | 3 | PB11 | SCK | EIC/EXTINT[11] *SERCOM4/PAD[3] TC5/WO[1] TCC0/WO[5] - * | | 5 | | RESET | - * | | 6 | | GND | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | LEDs | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 25 | | PB03 | RX | - * | 26 | | PA27 | TX | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | USB | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 27 | | PA28 | USB_HOST_ENABLE | EIC/EXTINT[8] - * | 28 | | PA24 | USB_NEGATIVE | *USB/DM - * | 29 | | PA25 | USB_POSITIVE | *USB/DP - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | EDBG | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 30 | | PB22 | EDBG_UART TX | *SERCOM5/PAD[2] - * | 31 | | PB23 | EDBG_UART RX | *SERCOM5/PAD[3] - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 32 | | PA22 | EDBG_SDA | Pin 20 (SDA) - * | 33 | | PA23 | EDBG_SCL | Pin 21 (SCL) - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 34 | | PA19 | EDBG_MISO | EIC/EXTINT[3] *SERCOM1/PAD[3] SERCOM3/PAD[3] TC3/WO[1] TCC0/WO[3] - * | 35 | | PA16 | EDBG_MOSI | EIC/EXTINT[0] *SERCOM1/PAD[0] SERCOM3/PAD[0] TCC2/WO[0] TCC0/WO[6] - * | 36 | | PA18 | EDBG_SS | EIC/EXTINT[2] *SERCOM1/PAD[2] SERCOM3/PAD[2] TC3/WO[0] TCC0/WO[2] - * | 37 | | PA17 | EDBG_SCK | EIC/EXTINT[1] *SERCOM1/PAD[1] SERCOM3/PAD[1] TCC2/WO[1] TCC0/WO[7] - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | 38 | ATN | PA13 | EDBG_GPIO0 | EIC/EXTINT[13] SERCOM2/PAD[1] SERCOM4/PAD[1] *TCC2/WO[1] TCC0/WO[7] - * | 39 | | PA21 | EDBG_GPIO1 | Pin 7 - * | 40 | | PA06 | EDBG_GPIO2 | Pin 8 - * | 41 | | PA07 | EDBG_GPIO3 | Pin 9 - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | GND | | | - * | 42 | AREF | PA03 | | EIC/EXTINT[3] *[ADC|DAC]/VREFA ADC/AIN[1] PTC/Y[1] - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | |32.768KHz Crystal | | | - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - * | | | PA00 | XIN32 | EIC/EXTINT[0] SERCOM1/PAD[0] TCC2/WO[0] - * | | | PA01 | XOUT32 | EIC/EXTINT[1] SERCOM1/PAD[1] TCC2/WO[1] - * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- - */ - #include "variant.h" @@ -121,16 +33,16 @@ const PinDescription g_APinDescription[]= // Digital Low { PORTB, 2, PIO_SERCOM_ALT, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // GPIO D2 / A5 / SDA { PORTB, 3, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // GPIO D3 / A4 / SCL - { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // GPIO D4 / Left Button + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // GPIO D4 / Left Button { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // GPIO D5 / Right button - { PORTA, 5, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // GPIO D6 / A1 + { PORTA, 5, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // GPIO D6 / A1 { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // GPIO D7 / Slide Switch // Digital High - { PORTB, 23, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // GPIO D8 / NeoPixels - { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // GPIO D9 / A2 - { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // GPIO D10 / A3 - { PORTA, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // GPIO D11 / Speaker Shutdown + { PORTB, 23, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // GPIO D8 / NeoPixels + { PORTA, 6, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // GPIO D9 / A2 + { PORTA, 7, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // GPIO D10 / A3 + { PORTA, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // GPIO D11 / Speaker Shutdown { PORTA, 2, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // GPIO D12 / VOut / A0 // 13 (LED) { PORTA, 17, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // GPIO D13 / Red LED @@ -141,7 +53,7 @@ const PinDescription g_APinDescription[]= { PORTA, 5, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // A1 (Same as D6) { PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // A2 (Same as D9) { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // A3 (Same as D10 - { PORTB, 3, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel11, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // A4 (Same as D3) + { PORTB, 3, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel11, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // A4 (Same as D3) { PORTB, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A5 (Same as D2) { PORTB, 9, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel3, PWM4_CH1, TC4_CH1, EXTERNAL_INT_9 }, // A6 (Same as D0) { PORTB, 8, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel2, PWM4_CH0, TC4_CH0, EXTERNAL_INT_8 }, // A7 (Same as D1) @@ -159,8 +71,8 @@ const PinDescription g_APinDescription[]= { PORTA, 13, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH5, NOT_ON_TIMER, EXTERNAL_INT_13 }, // EIC/EXTINT[13] *TCC2/WO[1] TCC0/WO[7] // GPIO 28 & 29 internal I2C (original xtal pins) - { PORTA, 0, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Internal SDA - { PORTA, 1, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Internal SCL + { PORTA, 0, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // Internal SDA + { PORTA, 1, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // Internal SCL // GPIO 30, 31, 32 Internal SPI { PORTA, 16, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MISO: SERCOM3/PAD[0] @@ -182,6 +94,12 @@ const PinDescription g_APinDescription[]= { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + // 39-42 External SPI + { PORTB, 2, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // GPIO D2 / A5 / SDA + { PORTB, 3, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // GPIO D3 / A4 / SCL + { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // Not available + { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // Not available + } ; const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; diff --git a/variants/circuitplay/variant.h b/variants/circuitplay/variant.h index 1697188f1..7a0a5a55c 100644 --- a/variants/circuitplay/variant.h +++ b/variants/circuitplay/variant.h @@ -31,7 +31,7 @@ #define VARIANT_MAINOSC (32768ul) // Master clock frequency -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) // Pins // ---- @@ -51,7 +51,10 @@ #define portInputRegister(port) (&(port->IN.reg)) #define portModeRegister(port) (&(port->DIR.reg)) #define digitalPinHasPWM(P) (g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER) -#define digitalPinToInterrupt(P) (g_APinDescription[P].ulExtInt) + +#if (ARDUINO_SAMD_VARIANT_COMPLIANCE < 10606) + #define digitalPinToInterrupt(P) (g_APinDescription[P].ulExtInt) +#endif /* * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD @@ -63,12 +66,37 @@ // #define digitalPinToTimer(P) +// Digital pins +// ---- +#define PIN_D4 (4u) +#define PIN_D5 (5u) +#define PIN_D7 (7u) +#define PIN_D8 (8u) +#define PIN_D11 (25u) +#define PIN_D12 (26u) +#define PIN_D13 (13u) + +#define D4 PIN_D4 +#define D5 PIN_D5 +#define D7 PIN_D7 +#define D8 PIN_D8 +#define D11 PIN_D11 +#define D12 PIN_D12 +#define D13 PIN_D13 + // LEDs // ---- -#define PIN_LED_13 (13u) +#define PIN_LED_13 (D13) #define PIN_LED PIN_LED_13 #define LED_BUILTIN PIN_LED +// Neopixel +#define PIN_NEOPIXEL D8 +#define NEOPIXEL_NUM 10 + +#define PIN_BUTTON1 D4 // Left Button +#define PIN_BUTTON2 D5 // Right Button + //#define PIN_LED_RXL (25u) //#define PIN_LED_TXL (26u) @@ -108,11 +136,18 @@ static const uint8_t DAC0 = PIN_DAC0; #define ADC_RESOLUTION 12 + +// On-board SPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_SPI SPI +#define EXTERNAL_FLASH_USE_CS SS + /* * SPI Interfaces */ -#define SPI_INTERFACES_COUNT 1 +#define SPI_INTERFACES_COUNT 3 +// SPI interface for QSPI flash #define PIN_SPI_MISO (30u) #define PIN_SPI_SCK (31u) #define PIN_SPI_MOSI (32u) @@ -126,6 +161,42 @@ static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t SCK = PIN_SPI_SCK ; +// Extra hardware SPI for Gizmo +#define PIN_SPI1_SCK (40u) +#define PIN_SPI1_MOSI (39u) +#define PIN_SPI1_MISO (41u) +#define PERIPH_SPI1 sercom5 +#define PAD_SPI1_TX SPI_PAD_0_SCK_1 // MOSI / SCK +#define PAD_SPI1_RX SERCOM_RX_PAD_2 // MISO not avail + +static const uint8_t SS1 = 42 ; +static const uint8_t MOSI1 = PIN_SPI_MOSI ; +static const uint8_t MISO1 = PIN_SPI_MISO ; +static const uint8_t SCK1 = PIN_SPI_SCK ; + + +// Extra hardware for SD card +#define PIN_SPI2_SCK (10u) +#define PIN_SPI2_MOSI (9u) +#define PIN_SPI2_MISO (6u) +#define PIN_SPI2_SS (5u) +#define PERIPH_SPI2 sercom0 +#define PAD_SPI2_TX SPI_PAD_2_SCK_3 // MOSI / SCK +#define PAD_SPI2_RX SERCOM_RX_PAD_1 // MISO not avail + +static const uint8_t SS2 = 5 ; +static const uint8_t MOSI2 = PIN_SPI2_MOSI ; +static const uint8_t MISO2 = PIN_SPI2_MISO ; +static const uint8_t SCK2 = PIN_SPI2_SCK ; + + +// Needed for SD library +#define SDCARD_SPI SPI2 +#define SDCARD_MISO_PIN PIN_SPI2_MISO +#define SDCARD_MOSI_PIN PIN_SPI2_MOSI +#define SDCARD_SCK_PIN PIN_SPI2_SCK +#define SDCARD_SS_PIN PIN_SPI2_SS + /* * Wire Interfaces */ @@ -196,10 +267,7 @@ extern Uart Serial1; // // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX // pins are NOT connected to anything by default. -#define SERIAL_PORT_USBVIRTUAL SerialUSB -#define SERIAL_PORT_MONITOR SerialUSB +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial #define SERIAL_PORT_HARDWARE Serial1 #define SERIAL_PORT_HARDWARE_OPEN Serial1 - -// Alias Serial to SerialUSB -#define Serial SerialUSB diff --git a/variants/mkrwan1300/debug_scripts/variant.gdb b/variants/crickit_m0/debug_scripts/variant.gdb similarity index 100% rename from variants/mkrwan1300/debug_scripts/variant.gdb rename to variants/crickit_m0/debug_scripts/variant.gdb diff --git a/variants/mkrwan1300/linker_scripts/gcc/flash_with_bootloader.ld b/variants/crickit_m0/linker_scripts/gcc/flash_with_bootloader.ld similarity index 100% rename from variants/mkrwan1300/linker_scripts/gcc/flash_with_bootloader.ld rename to variants/crickit_m0/linker_scripts/gcc/flash_with_bootloader.ld diff --git a/variants/mkrgsm1400/linker_scripts/gcc/flash_without_bootloader.ld b/variants/crickit_m0/linker_scripts/gcc/flash_without_bootloader.ld similarity index 100% rename from variants/mkrgsm1400/linker_scripts/gcc/flash_without_bootloader.ld rename to variants/crickit_m0/linker_scripts/gcc/flash_without_bootloader.ld diff --git a/variants/crickit_m0/openocd_scripts/cricket_m0.cfg b/variants/crickit_m0/openocd_scripts/cricket_m0.cfg new file mode 100644 index 000000000..79ded8ec2 --- /dev/null +++ b/variants/crickit_m0/openocd_scripts/cricket_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Crickit M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/mkrwan1300/pins_arduino.h b/variants/crickit_m0/pins_arduino.h similarity index 100% rename from variants/mkrwan1300/pins_arduino.h rename to variants/crickit_m0/pins_arduino.h diff --git a/variants/crickit_m0/variant.cpp b/variants/crickit_m0/variant.cpp new file mode 100644 index 000000000..944e731e4 --- /dev/null +++ b/variants/crickit_m0/variant.cpp @@ -0,0 +1,112 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/I2C + { PORTA, 0, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SDA + { PORTA, 1, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCL + + // D2..D5 - Drive 1 thru 4 + { PORTA, 13, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_13 }, // Drive 1 + { PORTA, 12, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_12 }, // Drive 2 + { PORTB, 11, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH1, TC5_CH1, EXTERNAL_INT_11 }, // Drive 3 + { PORTB, 10, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH0, TC5_CH0, EXTERNAL_INT_10 }, // Drive 4 + + // D6..D9 - Servo 1 thru 4 + { PORTA, 17, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_1 }, + { PORTA, 16, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_0 }, + { PORTA, 15, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH5, TCC0_CH5, EXTERNAL_INT_15 }, + { PORTA, 14, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH4, TCC0_CH4, EXTERNAL_INT_14 }, + + // D10 Internal NeoPixel + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, + + // D11 External NeoPixel + { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, + + // D12 IRQ + { PORTA, 28, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, + + // 13 (LED) + { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Yellow LED next to USB + + // A0-A8 - Analog signal pins + // A0 is duplicated since we mark it starting at analog1, so might as well! + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // Analog 0 == 1 + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // Analog 1 + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Analog 2 + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel2, PWM4_CH0, TC4_CH0, EXTERNAL_INT_8 }, // Analog 3 + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel3, PWM4_CH1, TC4_CH1, EXTERNAL_INT_9 }, // Analog 4 + { PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel19, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // A5 + { PORTA, 10, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel18, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // A6 + { PORTA, 9, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // A7 + { PORTA, 8, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // A8 + + // A9-A12 - 4 Captouch pins (also analog!) + { PORTA, 4, PIO_ANALOG, 0, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // Captouch 1 + { PORTA, 5, PIO_ANALOG, 0, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // Captouch 2 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // Captouch 3 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // Captouch 4 + + // A13 - VIN sense pin + { PORTB, 3, PIO_ANALOG, 0, ADC_Channel11, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // VIN sense divider + + /**************/ + // 28..31 - 4 Motor PWM pins + { PORTA, 22, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM4_CH0, TC4_CH1, EXTERNAL_INT_6 }, // TC4/WO[0] + { PORTA, 23, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM4_CH1, TC4_CH1, EXTERNAL_INT_7 }, // TC4/WO[1] + { PORTA, 19, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_3 }, // TC3/WO[1] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] + + // 32..34 - USB + // -------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 35..36 - fake sercom 5 serial + { PORTB, 2, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // Sercom 5.0 UART TX + { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // Sercom 5.3 UART RX + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM5_Handler() +{ + Serial1.IrqHandler(); +} + diff --git a/variants/crickit_m0/variant.h b/variants/crickit_m0/variant.h new file mode 100644 index 000000000..9b7646578 --- /dev/null +++ b/variants/crickit_m0/variant.h @@ -0,0 +1,250 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ITSYBITSY_ZERO_ +#define _VARIANT_ITSYBITSY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (26u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (12u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 12u) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 + + +/* CRICKIT pins */ + +#define CRICKIT_DRIVE_1 (2ul) +#define CRICKIT_DRIVE_2 (CRICKIT_DRIVE_1 + 1) +#define CRICKIT_DRIVE_3 (CRICKIT_DRIVE_2 + 1) +#define CRICKIT_DRIVE_4 (CRICKIT_DRIVE_3 + 1) + +#define CRICKIT_SERVO_1 (6ul) +#define CRICKIT_SERVO_2 (CRICKIT_SERVO_1 + 1) +#define CRICKIT_SERVO_3 (CRICKIT_SERVO_2 + 1) +#define CRICKIT_SERVO_4 (CRICKIT_SERVO_3 + 1) + +#define CRICKIT_INTERNAL_NEOPIXEL (10ul) +#define CRICKIT_EXTERNAL_NEOPIXEL (11ul) + +#define CRICKIT_IRQ (12ul) + +#define CRICKIT_TOUCH_1 (PIN_A9) +#define CRICKIT_TOUCH_2 (CRICKIT_TOUCH_1 + 1) +#define CRICKIT_TOUCH_3 (CRICKIT_TOUCH_2 + 1) +#define CRICKIT_TOUCH_4 (CRICKIT_TOUCH_3 + 1) + +#define CRICKIT_VIN_SENSE (PIN_A13) + +#define CRICKIT_MOTOR_1A (28ul) +#define CRICKIT_MOTOR_1B (29ul) +#define CRICKIT_MOTOR_2A (30ul) +#define CRICKIT_MOTOR_2B (31ul) + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_A10 (PIN_A0 + 10) +#define PIN_A11 (PIN_A0 + 11) +#define PIN_A12 (PIN_A0 + 12) +#define PIN_A13 (PIN_A0 + 13) +#define PIN_DAC0 (14ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; +static const uint8_t A8 = PIN_A8 ; +static const uint8_t A9 = PIN_A9 ; +static const uint8_t A10 = PIN_A10 ; +static const uint8_t A11 = PIN_A11 ; +static const uint8_t A12 = PIN_A12 ; +static const uint8_t A13 = PIN_A13 ; +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (38ul) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_TX (35ul) +#define PIN_SERIAL1_RX (36ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 0 + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (0u) +#define PIN_WIRE_SCL (1u) +#define PERIPH_WIRE sercom1 +#define WIRE_IT_HANDLER SERCOM1_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (32ul) +#define PIN_USB_DM (33ul) +#define PIN_USB_DP (34ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 +// PA07 ISD0 +#define PIN_I2S_SD (CRICKIT_TOUCH_4) +// PA10 I2SCK +#define PIN_I2S_SCK (A6) +// PA11 IS2FS0 +#define PIN_I2S_FS (A4) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/mkrwifi1010/debug_scripts/variant.gdb b/variants/feather_m0/debug_scripts/variant.gdb similarity index 100% rename from variants/mkrwifi1010/debug_scripts/variant.gdb rename to variants/feather_m0/debug_scripts/variant.gdb diff --git a/variants/mkrgsm1400/linker_scripts/gcc/flash_with_bootloader.ld b/variants/feather_m0/linker_scripts/gcc/flash_with_bootloader.ld similarity index 99% rename from variants/mkrgsm1400/linker_scripts/gcc/flash_with_bootloader.ld rename to variants/feather_m0/linker_scripts/gcc/flash_with_bootloader.ld index 5c0dcb4e0..357946455 100644 --- a/variants/mkrgsm1400/linker_scripts/gcc/flash_with_bootloader.ld +++ b/variants/feather_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -83,7 +83,6 @@ SECTIONS *(SORT(.ctors.*)) *(.ctors) - /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) diff --git a/variants/mkrwan1300/linker_scripts/gcc/flash_without_bootloader.ld b/variants/feather_m0/linker_scripts/gcc/flash_without_bootloader.ld similarity index 100% rename from variants/mkrwan1300/linker_scripts/gcc/flash_without_bootloader.ld rename to variants/feather_m0/linker_scripts/gcc/flash_without_bootloader.ld diff --git a/variants/feather_m0/openocd_scripts/feather_m0.cfg b/variants/feather_m0/openocd_scripts/feather_m0.cfg new file mode 100644 index 000000000..1dc08b177 --- /dev/null +++ b/variants/feather_m0/openocd_scripts/feather_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Feather M0 Express OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/mkrwifi1010/pins_arduino.h b/variants/feather_m0/pins_arduino.h similarity index 100% rename from variants/mkrwifi1010/pins_arduino.h rename to variants/feather_m0/pins_arduino.h diff --git a/variants/feather_m0/variant.cpp b/variants/feather_m0/variant.cpp new file mode 100644 index 000000000..f9e76061c --- /dev/null +++ b/variants/feather_m0/variant.cpp @@ -0,0 +1,139 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_11 }, // RX: SERCOM0/PAD[3] + { PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_10 }, // TX: SERCOM0/PAD[2] + + // 2..12 + // Digital Low + { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, PWM0_CH4, TCC0_CH4, EXTERNAL_INT_14 }, + { PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // TC3/WO[1] + { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // TCC0/WO[6] + { PORTA, 21, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + + // Digital High + { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] + { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] + { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // TCC0/WO[3] + + // 13 (LED) + { PORTA, 17, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // TCC2/WO[1] + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel2, PWM4_CH0, TC4_CH0, EXTERNAL_INT_8 }, // ADC/AIN[2] + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel3, PWM4_CH1, TC4_CH1, EXTERNAL_INT_9 }, // ADC/AIN[3] + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // ADC/AIN[5] + { PORTB, 2, PIO_ANALOG, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[10] + + // 20..21 I2C pins (SDA/SCL and also EDBG:SDA/SCL) + // ---------------------- + { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // SCL: SERCOM3/PAD[1] + + // 22..24 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0] + { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2] + { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3] + + // 25..26 - RX/TX LEDS (PB03/PA27) + // -------------------- + { PORTB, 3, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + { PORTA, 27, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + + // 27..29 - USB + // -------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 30..41 - EDBG + // ---------------------- + // 30/31 - EDBG/UART + { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // TX: SERCOM5/PAD[2] + { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // RX: SERCOM5/PAD[3] + + // 32/33 I2C (SDA/SCL and also EDBG:SDA/SCL) + { PORTA, 22, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCL: SERCOM3/PAD[1] + + // 34..37 - EDBG/SPI + { PORTA, 19, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MISO: SERCOM1/PAD[3] + { PORTA, 16, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MOSI: SERCOM1/PAD[0] + { PORTA, 18, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SS: SERCOM1/PAD[2] + { PORTA, 17, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCK: SERCOM1/PAD[1] + + // 38..41 - EDBG/Digital + { PORTA, 13, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH5, NOT_ON_TIMER, EXTERNAL_INT_13 }, // EIC/EXTINT[13] *TCC2/WO[1] TCC0/WO[7] + { PORTA, 21, PIO_PWM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH7, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 7 + { PORTA, 6, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH0, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 8 + { PORTA, 7, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH1, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 9 + + // 42 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 43 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT + + // 44 & 45 - A6 & A7 (same as D8 and D9 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; +Uart Serial5( &sercom5, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ) ; +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); +} + +void SERCOM5_Handler() +{ + Serial5.IrqHandler(); +} + diff --git a/variants/feather_m0/variant.h b/variants/feather_m0/variant.h new file mode 100644 index 000000000..20ecbbbaf --- /dev/null +++ b/variants/feather_m0/variant.h @@ -0,0 +1,228 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ARDUINO_ZERO_ +#define _VARIANT_ARDUINO_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (26u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (25u) +#define PIN_LED_TXL (26u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (15ul) +#define PIN_A2 (16ul) +#define PIN_A3 (17ul) +#define PIN_A4 (18ul) +#define PIN_A5 (19ul) +#define PIN_A6 (44ul) +#define PIN_A7 (45ul) +#define PIN_DAC0 (14ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (38ul) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ +// Serial (EDBG) +#define PIN_SERIAL_RX (31ul) +#define PIN_SERIAL_TX (30ul) +#define PAD_SERIAL_TX (UART_TX_PAD_2) +#define PAD_SERIAL_RX (SERCOM_RX_PAD_3) + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_2) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (22u) +#define PIN_SPI_MOSI (23u) +#define PIN_SPI_SCK (24u) +#define PERIPH_SPI sercom4 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (20u) +#define PIN_WIRE_SCL (21u) +#define PERIPH_WIRE sercom3 +#define WIRE_IT_HANDLER SERCOM3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (27ul) +#define PIN_USB_DM (28ul) +#define PIN_USB_DP (29ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 +#define PIN_I2S_SD (9u) +#define PIN_I2S_SCK (1u) +#define PIN_I2S_FS (0u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial5; +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/feather_m0_express/debug_scripts/variant.gdb b/variants/feather_m0_express/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/feather_m0_express/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/feather_m0_express/linker_scripts/gcc/flash_with_bootloader.ld b/variants/feather_m0_express/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..7d75f819d --- /dev/null +++ b/variants/feather_m0_express/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,213 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/mkrwifi1010/linker_scripts/gcc/flash_without_bootloader.ld b/variants/feather_m0_express/linker_scripts/gcc/flash_without_bootloader.ld similarity index 100% rename from variants/mkrwifi1010/linker_scripts/gcc/flash_without_bootloader.ld rename to variants/feather_m0_express/linker_scripts/gcc/flash_without_bootloader.ld diff --git a/variants/feather_m0_express/openocd_scripts/feather_m0_express.cfg b/variants/feather_m0_express/openocd_scripts/feather_m0_express.cfg new file mode 100644 index 000000000..9d2a9d3ca --- /dev/null +++ b/variants/feather_m0_express/openocd_scripts/feather_m0_express.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Feather M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/feather_m0_express/pins_arduino.h b/variants/feather_m0_express/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/feather_m0_express/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/feather_m0_express/variant.cpp b/variants/feather_m0_express/variant.cpp new file mode 100644 index 000000000..a3e87b89e --- /dev/null +++ b/variants/feather_m0_express/variant.cpp @@ -0,0 +1,128 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // RX: SERCOM0/PAD[3] + { PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // TX: SERCOM0/PAD[2] + + // 2..12 + // Digital Low + { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + { PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // TC3/WO[1] + { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // TCC0/WO[6] + { PORTA, 21, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + + // Digital High + { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] + { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] + { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // TCC0/WO[3] + + // 13 (LED) + { PORTA, 17, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // TCC2/WO[1] + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel2, PWM4_CH0, TC4_CH0, EXTERNAL_INT_8 }, // ADC/AIN[2] + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel3, PWM4_CH1, TC4_CH1, EXTERNAL_INT_9 }, // ADC/AIN[3] + { PORTA, 4, PIO_ANALOG, 0, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, 0, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // ADC/AIN[5] + { PORTB, 2, PIO_ANALOG, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[10] + + + // Extra Analog pins! 20..25 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // A6 same as D8 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // A7 same as D9 + { PORTA, 8, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // A8 same as D4 + { PORTA, 9, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // A9 same as D5 + { PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel19, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // A10 same as D0 + { PORTA, 10, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel18, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // A11 same as D1 + + // 26..27 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // SCL: SERCOM3/PAD[1] + + // 28..30 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0] + { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2] + { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3] + + // 31..32 - RX/TX LEDS (PB03/PA27) -- unused + // -------------------- + { PORTB, 3, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + { PORTA, 27, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + + // 33..35 - USB + // -------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 36..38 - Secondary SPI + // ---------------------- + { PORTA, 14, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash MISO SERCOM2.2 + { PORTA, 8, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash MOSI SERCOM2.0 + { PORTA, 9, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash SCK SERCOM2.1 + + // 39 Secondary SPI SS + { PORTA, 13, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // SPI Flash SS + + // 40 same as #8 - Internal NeoPixel (to match Metro M0) + { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + + // 41 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 42 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); +} + diff --git a/variants/feather_m0_express/variant.h b/variants/feather_m0_express/variant.h new file mode 100644 index 000000000..f4d3ae9bf --- /dev/null +++ b/variants/feather_m0_express/variant.h @@ -0,0 +1,255 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ARDUINO_ZERO_ +#define _VARIANT_ARDUINO_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (42u) +#define NUM_DIGITAL_PINS (42u) +#define NUM_ANALOG_INPUTS (12u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (31u) +#define PIN_LED_TXL (32u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +#define NEOPIXEL_BUILTIN (8u) +#define PIN_NEOPIXEL NEOPIXEL_BUILTIN + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_A10 (PIN_A0 + 10) +#define PIN_A11 (PIN_A0 + 11) +#define PIN_A12 (41ul) // AREF +#define PIN_DAC0 (14ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; +static const uint8_t A8 = PIN_A8 ; +static const uint8_t A9 = PIN_A9 ; +static const uint8_t A10 = PIN_A10 ; +static const uint8_t A11 = PIN_A11 ; +static const uint8_t A12 = PIN_A12 ; + +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (38ul) +static const uint8_t ATN = PIN_ATN; + + +// On-board SPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_SPI SPI1 +#define EXTERNAL_FLASH_USE_CS SS1 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_2) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (28u) +#define PIN_SPI_MOSI (29u) +#define PIN_SPI_SCK (30u) +#define PERIPH_SPI sercom4 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +#define PIN_SPI1_MISO (36u) +#define PIN_SPI1_MOSI (37u) +#define PIN_SPI1_SCK (38u) +#define PERIPH_SPI1 sercom2 +#define PAD_SPI1_TX SPI_PAD_0_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_2 + +static const uint8_t SS1 = 39 ; // HW SS isn't used. Set here only for reference. +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (26u) +#define PIN_WIRE_SCL (27u) +#define PERIPH_WIRE sercom3 +#define WIRE_IT_HANDLER SERCOM3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (33ul) +#define PIN_USB_DM (34ul) +#define PIN_USB_DP (35ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 +#define PIN_I2S_SD (9u) +#define PIN_I2S_SCK (1u) +#define PIN_I2S_FS (0u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/feather_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/feather_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..2c7e62a53 --- /dev/null +++ b/variants/feather_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,220 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + . = ALIGN(4); + /* Keep .ramfunc functions in RAM */ + KEEP(*(.ramfunc)) + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/feather_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/feather_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..9c0c4e06d --- /dev/null +++ b/variants/feather_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/feather_m4/pins_arduino.h b/variants/feather_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/feather_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/feather_m4/variant.cpp b/variants/feather_m4/variant.cpp new file mode 100644 index 000000000..88ba1ff6c --- /dev/null +++ b/variants/feather_m4/variant.cpp @@ -0,0 +1,140 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ + +//TCC0 IOSET 6 +//TCC1 IOSET 1 +//TC0 IOSET 1 +//TC1 IOSET 1 +//TC2 IOSET 2 +//TC3 IOSET 1 +//TC4 IOSET 1 +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 17, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_1 }, // RX: SERCOM5/PAD[1] + { PORTB, 16, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_0 }, // TX: SERCOM5/PAD[0] + + // 2..12 + // Digital Low + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 14, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14 }, + { PORTA, 16, PIO_TIMER_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, + { PORTA, 18, PIO_TIMER_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH2, TC3_CH0, EXTERNAL_INT_2 }, + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_TIMER, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // Digital High + { PORTB, 3, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, //neopix + { PORTA, 19, PIO_TIMER_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH3, TC3_CH1, EXTERNAL_INT_3 }, + { PORTA, 20, PIO_TIMER_ALT, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH0, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH1, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTA, 22, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_6 }, + + // 13 (LED) + { PORTA, 23, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7 }, // TCC2/WO[1] + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel2, TC4_CH0, TC4_CH0, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel3, TC4_CH1, TC4_CH1, EXTERNAL_INT_9 }, + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4, TC0_CH0, TC0_CH0, EXTERNAL_INT_4 }, + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 }, + + // A6, D20 - VDiv! + { PORTB, 1, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel13, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, + + + // 21..22 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, // SDA: SERCOM2/PAD[0] + { PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, // SCL: SERCOM2/PAD[1] + + // 23..25 - SPI pins (MISO,MOSI,SCK) + // ---------------------- + { PORTB, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // MISO: SERCOM1/PAD[2] + { PORTB, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MOSI: SERCOM1/PAD[3] + { PORTA, 17, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // SCK: SERCOM1/PAD[1] + + // 26..27 - RX/TX LEDS -- unused + // -------------------- + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 28..30 - USB + // -------------------- + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable DOES NOT EXIST ON THIS BOARD + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 27, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 31 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 32..33 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT0 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT1 + + // ---------------------- + // 34..39 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM5_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/feather_m4/variant.h b/variants/feather_m4/variant.h new file mode 100644 index 000000000..6be35dccb --- /dev/null +++ b/variants/feather_m4/variant.h @@ -0,0 +1,253 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_FEATHER_M4_ +#define _VARIANT_FEATHER_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (40u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (6u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (25u) +#define PIN_LED_TXL (26u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +#define PIN_NEOPIXEL (8) + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) + +#define PIN_DAC0 (14ul) +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (31ul) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (23u) +#define PIN_SPI_MOSI (24u) +#define PIN_SPI_SCK (25u) +#define PERIPH_SPI sercom1 +#define PAD_SPI_TX SPI_PAD_3_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 9 ; // SERCOM1 last PAD is present on d9 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (21u) +#define PIN_WIRE_SCL (22u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler +#define WIRE_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (28ul) +#define PIN_USB_DM (29ul) +#define PIN_USB_DP (30ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 + +#define PIN_I2S_SDO (11u) +#define PIN_I2S_SDI (12u) +#define PIN_I2S_SCK PIN_SERIAL1_TX +#define PIN_I2S_FS (10u) +#define PIN_I2S_MCK PIN_SERIAL1_RX + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (34u) +#define PIN_QSPI_CS (35u) +#define PIN_QSPI_IO0 (36u) +#define PIN_QSPI_IO1 (37u) +#define PIN_QSPI_IO2 (38u) +#define PIN_QSPI_IO3 (39u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_FEATHER_M4_ */ + diff --git a/variants/feather_m4_can/linker_scripts/gcc/flash_with_bootloader.ld b/variants/feather_m4_can/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..379e54ed3 --- /dev/null +++ b/variants/feather_m4_can/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,225 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + /* Data accessed by the CAN peripheral must be in the first 64kB RAM */ + /* place it at the very start of RAM, before the .data section */ + /* *NOTE* it is not expliclty zeroed */ + .canram (NOLOAD) : + { + . = ALIGN(4); + *(.canram) + } > RAM + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/feather_m4_can/linker_scripts/gcc/flash_without_bootloader.ld b/variants/feather_m4_can/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..9e81bbab8 --- /dev/null +++ b/variants/feather_m4_can/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,223 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + /* Data accessed by the CAN peripheral must be in the first 64kB RAM */ + /* place it at the very start of RAM, before the .data section */ + /* *NOTE* it is not expliclty zeroed */ + .canram (NOLOAD) : + { + . = ALIGN(4); + *(.canram) + } > RAM + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/feather_m4_can/pins_arduino.h b/variants/feather_m4_can/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/feather_m4_can/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/feather_m4_can/variant.cpp b/variants/feather_m4_can/variant.cpp new file mode 100644 index 000000000..64d982e5e --- /dev/null +++ b/variants/feather_m4_can/variant.cpp @@ -0,0 +1,156 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" + +/* + * Pins descriptions + */ + +//TCC0 IOSET 6 +//TCC1 IOSET 1 +//TC0 IOSET 1 +//TC1 IOSET 1 +//TC2 IOSET 2 +//TC3 IOSET 1 +//TC4 IOSET 1 +const PinDescription g_APinDescription[PINS_COUNT]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 17, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_1 }, // RX: SERCOM5/PAD[1] + { PORTB, 16, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_0 }, // TX: SERCOM5/PAD[0] + + // 2..12 + // Digital Low + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 14, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14 }, + { PORTA, 16, PIO_TIMER_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, + { PORTA, 18, PIO_TIMER_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH2, TC3_CH0, EXTERNAL_INT_2 }, + { PORTB, 3, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // 7: neopixel power + + // Digital High + { PORTB, 2, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // 8: neopixel + { PORTA, 19, PIO_TIMER_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH3, TC3_CH1, EXTERNAL_INT_3 }, + { PORTA, 20, PIO_TIMER_ALT, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH0, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH1, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTA, 22, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_6 }, + + // 13 (LED) + { PORTA, 23, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7 }, + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel2, TC4_CH0, TC4_CH0, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel3, TC4_CH1, TC4_CH1, EXTERNAL_INT_9 }, + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4, TC0_CH0, TC0_CH0, EXTERNAL_INT_4 }, + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 }, + + // A6, D20 - VDiv! + { PORTB, 0, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel12, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, + + + // 21..22 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, // SDA: SERCOM2/PAD[0] + { PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, // SCL: SERCOM2/PAD[1] + + // 23..25 - SPI pins (MISO,MOSI,SCK) + // ---------------------- + { PORTB, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // MISO: SERCOM1/PAD[2] + { PORTB, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MOSI: SERCOM1/PAD[3] + { PORTA, 17, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // SCK: SERCOM1/PAD[1] + + // 26..27 - RX/TX LEDS -- unused + // -------------------- + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 28..30 - USB + // -------------------- + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable DOES NOT EXIST ON THIS BOARD + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 27, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 31 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 32..33 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT0 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT1 + + // ---------------------- + // 34..39 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // ---------------------- + // 40..43 CAN (STANDBY, BOOST, TX, RX) + { PORTB, 12, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 13, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 14, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 15, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM5_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_3_Handler() +{ + Serial1.IrqHandler(); +} + +void initVariant(void) { + // special initialization code just for us + + // turn on neopixel + pinMode(7, OUTPUT); + digitalWrite(7, HIGH); +} diff --git a/variants/feather_m4_can/variant.h b/variants/feather_m4_can/variant.h new file mode 100644 index 000000000..853086c65 --- /dev/null +++ b/variants/feather_m4_can/variant.h @@ -0,0 +1,266 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_FEATHER_M4_ +#define _VARIANT_FEATHER_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (44u) +#define NUM_DIGITAL_PINS (23u) +#define NUM_ANALOG_INPUTS (6u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (25u) +#define PIN_LED_TXL (26u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +#define PIN_NEOPIXEL (8) +#define PIN_NEOPIXEL_POWER (7) + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) + +#define PIN_DAC0 (14ul) +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (31ul) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (23u) +#define PIN_SPI_MOSI (24u) +#define PIN_SPI_SCK (25u) +#define PERIPH_SPI sercom1 +#define PAD_SPI_TX SPI_PAD_3_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 9 ; // SERCOM1 last PAD is present on d9 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (21u) +#define PIN_WIRE_SCL (22u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler +#define WIRE_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (28ul) +#define PIN_USB_DM (29ul) +#define PIN_USB_DP (30ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 + +#define PIN_I2S_SDO (11u) +#define PIN_I2S_SDI (12u) +#define PIN_I2S_SCK PIN_SERIAL1_TX +#define PIN_I2S_FS (10u) +#define PIN_I2S_MCK PIN_SERIAL1_RX + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (34u) +#define PIN_QSPI_CS (35u) +#define PIN_QSPI_IO0 (36u) +#define PIN_QSPI_IO1 (37u) +#define PIN_QSPI_IO2 (38u) +#define PIN_QSPI_IO3 (39u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +/* + * CAN + */ +#define PIN_CAN_STANDBY (40) +#define PIN_CAN_BOOSTEN (41) +#define PIN_CAN_TX (42) +#define PIN_CAN_RX (43) + +#define PIN_CAN1_TX (12) +#define PIN_CAN1_RX (13) + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_FEATHER_M4_ */ + diff --git a/variants/gemma_m0/debug_scripts/variant.gdb b/variants/gemma_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/gemma_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/gemma_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/gemma_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..4475f9511 --- /dev/null +++ b/variants/gemma_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,211 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/gemma_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/gemma_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0162f0774 --- /dev/null +++ b/variants/gemma_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,212 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/gemma_m0/openocd_scripts/gemma_m0.cfg b/variants/gemma_m0/openocd_scripts/gemma_m0.cfg new file mode 100644 index 000000000..93d782d39 --- /dev/null +++ b/variants/gemma_m0/openocd_scripts/gemma_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Gemma M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/gemma_m0/pins_arduino.h b/variants/gemma_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/gemma_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/gemma_m0/variant.cpp b/variants/gemma_m0/variant.cpp new file mode 100644 index 000000000..c0fa9700e --- /dev/null +++ b/variants/gemma_m0/variant.cpp @@ -0,0 +1,97 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // GPIO 0, 1, 2 on external pads + // 0 - SERCOM0.0 for I2C SDA, UART TX, SPI MOSI, Captouch, IRQ, PWM out TCC0/WO[0], and gen purpose pin + { PORTA, 4, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // TCC0/WO[0] + + // 1 - ADC, DAC, IRQ, Captouch and general purpose pin - no timer + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + + // 2 - SERCOM0 for I2C SCL, UART RX, SPI CLK, Captouch, IRQ, PWM out TCC0/WO[1], and gen purpose pin + { PORTA, 5, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // TCC0/WO[1] + + // GPIO 3 & 4 - DotStar internal data/clock + // ---------------------------------------- + { PORTA, 0, PIO_DIGITAL, 0, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // ADC/AIN[4] + { PORTA, 1, PIO_DIGITAL, 0, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // ADC/AIN[5] + + // GPIO 5, 6, 7 (USB interface) + // ---------------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable - GPIO #5 + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM - GPIO #6 + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP - GPIO #7 + + // GPIO 8, 9, 10 - analog inputs which are 'clones' of the analog pins + // A0 (D8 same as D1) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + // A1 (D9 same as D2) + { PORTA, 5, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // TCC0/WO[1] + // A2 (D10 same as D0) + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // TCC0/WO[0] + + // GPIO 11 & 12 (SWCLK & SWDIO) + // -------------------------- + { PORTA, 30, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 31, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // GPIO 13 (LED) + { PORTA, 23, PIO_TIMER, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // Digital #13 + + // Placeholder #14 & 15 for 'txled' + { PORTA, 10, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTA, 11, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + + // Placeholder #16 - extra Sercom/SPI pin that doesnt actually get used + { PORTA, 6, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC0/WO[1] + + // For unknown reasons we need to have gpio 17-21 so here are extra pins (shrug) + { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + { PORTA, 15, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, + { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] + { PORTA, 17, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // TCC2/WO[1] +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + + +// If wire.h isnt included, just do nothing +void WIRE_IT_HANDLER(void) __attribute__ ((weak)); + +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); + WIRE_IT_HANDLER(); +} + diff --git a/variants/gemma_m0/variant.h b/variants/gemma_m0/variant.h new file mode 100644 index 000000000..ee1273b55 --- /dev/null +++ b/variants/gemma_m0/variant.h @@ -0,0 +1,203 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ARDUINO_ZERO_ +#define _VARIANT_ARDUINO_ZERO_ + +// The definitions here needs a SAMD core >=1.6.6 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10606 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (16u) +#define NUM_DIGITAL_PINS (16u) +#define NUM_ANALOG_INPUTS (3u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 3u) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (14u) +#define PIN_LED_TXL (15u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +// DotStar LED +#define INTERNAL_DS_DATA (3u) +#define INTERNAL_DS_CLK (4u) +#define PIN_DOTSTAR_DATA (3u) +#define PIN_DOTSTAR_CLK (4u) +#define PIN_DOTSTAR_CLOCK PIN_DOTSTAR_CLK +#define DOTSTAR_NUM (1u) + +/* + * Analog pins + */ +#define PIN_A0 (8ul) +#define PIN_A1 (9ul) +#define PIN_A2 (10ul) +#define PIN_DAC0 (8ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +/* + * Serial interfaces + */ + +// Serial1 (sercom 0) +#define PIN_SERIAL1_RX (2ul) // PA05 +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PIN_SERIAL1_TX (0ul) // PA04 +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 // we'll just have SPI CLK and MOSI on sercom 0, no MISO + +#define PIN_SPI_MISO (6u) // PA06, not actually available +#define PIN_SPI_MOSI (0ul) // PA04 +#define PIN_SPI_SCK (2ul) // PA05 +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 1 ; // only pin remaining (shrug) +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (0u) +#define PIN_WIRE_SCL (2u) +#define PERIPH_WIRE sercom0 +//#define WIRE_IT_HANDLER // hack! we call the i2c handler from within the serial handler! + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (5ul) +#define PIN_USB_DM (6ul) +#define PIN_USB_DP (7ul) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/grand_central_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/grand_central_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..39c2a889a --- /dev/null +++ b/variants/grand_central_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x100000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/grand_central_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/grand_central_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ec0416a03 --- /dev/null +++ b/variants/grand_central_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,215 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + . = ALIGN(4); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/grand_central_m4/pins_arduino.h b/variants/grand_central_m4/pins_arduino.h new file mode 100644 index 000000000..0595fda01 --- /dev/null +++ b/variants/grand_central_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "../grand_central_m4/variant.h" + diff --git a/variants/grand_central_m4/variant.cpp b/variants/grand_central_m4/variant.cpp new file mode 100644 index 000000000..78aa1495d --- /dev/null +++ b/variants/grand_central_m4/variant.cpp @@ -0,0 +1,219 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + * TCC0 IOSET4 + * TCC1 IOSET2 + * TCC2 IOSET1 + * TCC3 IOSET1 + * TCC4 IOSET1 + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 25, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // RX: SERCOMX/PAD[1] + { PORTB, 24, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // TX: SERCOMX/PAD[0] + + // 2..12 + // Digital Low + { PORTC, 18, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTC, 19, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC0_CH3, NOT_ON_TIMER, EXTERNAL_INT_3 }, + { PORTC, 20, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTC, 21, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTD, 20, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTD, 21, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH1, NOT_ON_TIMER, EXTERNAL_INT_11 }, + + // Digital High + { PORTB, 18, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTB, 2, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC6_CH0, TC6_CH0, EXTERNAL_INT_3 }, + { PORTB, 22, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC7_CH0, TC7_CH0, EXTERNAL_INT_6 }, + { PORTB, 23, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, + { PORTB, 0, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC7_CH0, TC7_CH0, EXTERNAL_INT_0 }, + + // 13 (LED) + { PORTB, 1, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC7_CH1, TC7_CH1, EXTERNAL_INT_1 }, + + // 14..21 - UARTS + { PORTB, 16, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC6_CH0, TC6_CH0, EXTERNAL_INT_0 }, // UART3_TX + { PORTB, 17, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // UART3_RX + { PORTC, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // UART2_TX + { PORTC, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // UART2_RX + { PORTB, 12, PIO_SERCOM, PIN_ATTR_PWM_F, No_ADC_Channel, TCC3_CH0, NOT_ON_TIMER, EXTERNAL_INT_12 }, // UART1_TX + { PORTB, 13, PIO_SERCOM, PIN_ATTR_PWM_F, No_ADC_Channel, TCC3_CH1, NOT_ON_TIMER, EXTERNAL_INT_13 }, // UART1_RX + { PORTB, 20, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, //same as SDA + { PORTB, 21, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, //same as SCL + + // 22..53 - Extra Digital Pins + // ---------------------- + // 22..29 + { PORTD, 12, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC2_CH1, NOT_ON_TIMER, EXTERNAL_INT_15 }, + { PORTC, 17, PIO_SERCOM, PIN_ATTR_PWM_F, No_ADC_Channel, TCC0_CH1, NOT_ON_TIMER, EXTERNAL_INT_1 }, // SCL_1 + { PORTC, 16, PIO_SERCOM, PIN_ATTR_PWM_F, No_ADC_Channel, TCC0_CH0, NOT_ON_TIMER, EXTERNAL_INT_0 }, // SDA_1 + { PORTA, 12, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, // DEN1 + { PORTA, 13, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, // DEN2 + { PORTA, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC2_CH0, NOT_ON_TIMER, EXTERNAL_INT_14 }, // CLK + { PORTB, 19, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // XCLK + + // 30..37 + { PORTA, 23, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC4_CH1, TC4_CH1, EXTERNAL_INT_7 }, + { PORTA, 22, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC4_CH0, TC4_CH0, EXTERNAL_INT_6 }, + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH1, TC3_CH1, EXTERNAL_INT_3 }, + { PORTA, 18, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_2 }, + { PORTA, 17, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, + + // 38..45 + { PORTB, 15, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH1, NOT_ON_TIMER, EXTERNAL_INT_15 }, + { PORTB, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH0, NOT_ON_TIMER, EXTERNAL_INT_14 }, + { PORTC, 13, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, + { PORTC, 12, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, + { PORTC, 15, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, + { PORTC, 14, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + { PORTC, 11, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + { PORTC, 10, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + + // 46..53 + { PORTC, 6, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, + { PORTC, 7, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTC, 4, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTC, 5, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTD, 11, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, //same as MISO + { PORTD, 8, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, //same as MOSI + { PORTD, 9, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, //same as SCK + { PORTD, 10, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, //same as SS + + // 54..61 - Additional ADC + { PORTB, 5, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel7, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 6, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel8, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, + { PORTB, 7, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel9, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4, TC0_CH0, TC0_CH0, EXTERNAL_INT_4 }, + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, NOT_ON_TIMER, EXTERNAL_INT_6 }, + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel7, TC1_CH1, NOT_ON_TIMER, EXTERNAL_INT_7 }, + + // 62..63 - I2C pins (SDA/SCL) + // ---------------------- + { PORTB, 20, PIO_SERCOM, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH2, NOT_ON_TIMER, EXTERNAL_INT_4 }, // SDA + { PORTB, 21, PIO_SERCOM, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH3, NOT_ON_TIMER, EXTERNAL_INT_5 }, // SCL + + // 64..66 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTD, 11, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // MISO + { PORTD, 8, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // MOSI + { PORTD, 9, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // SCK + + // 67..74 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 3, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel15, TC6_CH1, TC6_CH1, EXTERNAL_INT_3 }, + { PORTC, 0, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, + { PORTC, 1, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel11, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, + { PORTC, 2, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTC, 3, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, + { PORTB, 4, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + + // 75..76 - RX/TX LEDS + // -------------------- + { PORTC, 31, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + { PORTC, 30, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + + // 77..79 - USB + // -------------------- + { PORTA, 27, PIO_COM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // USB/DP + + // 80..83 - SD SPI pins (SD:MISO,SCK,MOSI,CS) + // ---------------------- + { PORTB, 29, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 27, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 26, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 28, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 84 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // DAC/VREFP + + // ---------------------- + // 85..86 - Alternate use of A0 and A1 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT[0] + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // DAC/VOUT[1] + + // 87 - LED #13 duplicate placeholder + { PORTB, 1, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC7_CH1, TC7_CH1, EXTERNAL_INT_1 }, + + // 88 - Internal NeoPixel + { PORTC, 24, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + + // ---------------------- + // 89 - 94 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + + // ---------------------- + // 95 SD detect + { PORTB, 31, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, + // 96 SWO (on debug header) + { PORTB, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID, TC6_GCLK_ID, TC7_GCLK_ID } ; + + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; +SERCOM sercom6( SERCOM6 ) ; +SERCOM sercom7( SERCOM7 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM0_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM0_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM0_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM0_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/grand_central_m4/variant.h b/variants/grand_central_m4/variant.h new file mode 100644 index 000000000..3092191b1 --- /dev/null +++ b/variants/grand_central_m4/variant.h @@ -0,0 +1,346 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_GRAND_CENTRAL_M4_ +#define _VARIANT_GRAND_CENTRAL_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (96) +#define NUM_DIGITAL_PINS (53) +#define NUM_ANALOG_INPUTS (19) +#define NUM_ANALOG_OUTPUTS (2) +#define analogInputToDigitalPin(p) ((p < 8) ? 67 + (p) : (p < 16) ? 54 + (p) - 8 : (p < 18) ? 12 + (p) - 16 : (p == 18) ? 9 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13) +#define PIN_LED_RXL (75) +#define PIN_LED_TXL (76) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +#define PIN_NEOPIXEL (88) + +/* + * Analog pins + */ +#define PIN_A0 (67) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) + +#define PIN_A8 (54) +#define PIN_A9 (PIN_A8 + 1) +#define PIN_A10 (PIN_A8 + 2) +#define PIN_A11 (PIN_A8 + 3) +#define PIN_A12 (PIN_A8 + 4) +#define PIN_A13 (PIN_A8 + 5) +#define PIN_A14 (PIN_A8 + 6) +#define PIN_A15 (PIN_A8 + 7) + +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; + +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; +static const uint8_t A10 = PIN_A10; +static const uint8_t A11 = PIN_A11; +static const uint8_t A12 = PIN_A12; +static const uint8_t A13 = PIN_A13; +static const uint8_t A14 = PIN_A14; +static const uint8_t A15 = PIN_A15; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (39) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0) +#define PIN_SERIAL1_TX (1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) + +// Serial2 +#define PIN_SERIAL2_RX (19) +#define PIN_SERIAL2_TX (18) +#define PAD_SERIAL2_TX (UART_TX_PAD_0) +#define PAD_SERIAL2_RX (SERCOM_RX_PAD_1) +#define SERCOM_SERIAL2 sercom4 + +// Serial3 +#define PIN_SERIAL3_RX (17) +#define PIN_SERIAL3_TX (16) +#define PAD_SERIAL3_TX (UART_TX_PAD_0) +#define PAD_SERIAL3_RX (SERCOM_RX_PAD_1) +#define SERCOM_SERIAL3 sercom1 + +// Serial4 +#define PIN_SERIAL4_RX (15) +#define PIN_SERIAL4_TX (14) +#define PAD_SERIAL4_TX (UART_TX_PAD_0) +#define PAD_SERIAL4_RX (SERCOM_RX_PAD_1) +#define SERCOM_SERIAL4 sercom5 +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (64) +#define PIN_SPI_MOSI (66) +#define PIN_SPI_SCK (65) +#define PERIPH_SPI sercom7 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_3 + +static const uint8_t SS = (53); +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +#define PIN_SPI1_MISO (80) +#define PIN_SPI1_MOSI (82) +#define PIN_SPI1_SCK (81) +#define PIN_SPI1_SS (83) +#define PERIPH_SPI1 sercom2 +#define PAD_SPI1_TX SPI_PAD_0_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_3 + +static const uint8_t SS1 = PIN_SPI1_SS; +static const uint8_t MOSI1 = PIN_SPI1_MOSI; +static const uint8_t MISO1 = PIN_SPI1_MISO; +static const uint8_t SCK1 = PIN_SPI1_SCK; + +// Needed for SD library +#define SDCARD_SPI SPI1 +#define SDCARD_MISO_PIN PIN_SPI1_MISO +#define SDCARD_MOSI_PIN PIN_SPI1_MOSI +#define SDCARD_SCK_PIN PIN_SPI1_SCK +#define SDCARD_SS_PIN PIN_SPI1_SS + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 2 + +#define PIN_WIRE_SDA (62) +#define PIN_WIRE_SCL (63) +#define PERIPH_WIRE sercom3 +#define WIRE_IT_HANDLER SERCOM3_Handler +#define WIRE_IT_HANDLER_0 SERCOM3_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM3_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM3_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM3_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +#define PIN_WIRE1_SDA (25) +#define PIN_WIRE1_SCL (24) +#define PERIPH_WIRE1 sercom6 +#define WIRE1_IT_HANDLER SERCOM6_Handler +#define WIRE1_IT_HANDLER_0 SERCOM6_0_Handler +#define WIRE1_IT_HANDLER_1 SERCOM6_1_Handler +#define WIRE1_IT_HANDLER_2 SERCOM6_2_Handler +#define WIRE1_IT_HANDLER_3 SERCOM6_3_Handler + +static const uint8_t SDA1 = PIN_WIRE1_SDA; +static const uint8_t SCL1 = PIN_WIRE1_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (77) +#define PIN_USB_DM (78) +#define PIN_USB_DP (79) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 + +#define PIN_I2S_SDO (32) +#define PIN_I2S_SDI (31) +#define PIN_I2S_SCK PIN_SERIAL4_TX +#define PIN_I2S_FS (33) +#define PIN_I2S_MCK PIN_SERIAL4_RX + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (89) +#define PIN_QSPI_CS (90) +#define PIN_QSPI_IO0 (91) +#define PIN_QSPI_IO1 (92) +#define PIN_QSPI_IO2 (93) +#define PIN_QSPI_IO3 (94) + +//PCC Pins +#define PIN_PCC_DEN1 (26) +#define PIN_PCC_DEN2 (27) +#define PIN_PCC_CLK (28) +#define PIN_PCC_XCLK (29) +#define PIN_PCC_D0 (37) +#define PIN_PCC_D1 (36) +#define PIN_PCC_D2 (35) +#define PIN_PCC_D3 (34) +#define PIN_PCC_D4 (33) +#define PIN_PCC_D5 (32) +#define PIN_PCC_D6 (31) +#define PIN_PCC_D7 (30) +#define PIN_PCC_D8 (39) +#define PIN_PCC_D9 (38) +#define PIN_PCC_D10 (41) +#define PIN_PCC_D11 (40) +#define PIN_PCC_D12 (43) +#define PIN_PCC_D13 (42) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; +extern SERCOM sercom6; +extern SERCOM sercom7; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_GRAND_CENTRAL_M4_ */ diff --git a/variants/hallowing_m0_express/debug_scripts/variant.gdb b/variants/hallowing_m0_express/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/hallowing_m0_express/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/hallowing_m0_express/linker_scripts/gcc/flash_with_bootloader.ld b/variants/hallowing_m0_express/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..7d75f819d --- /dev/null +++ b/variants/hallowing_m0_express/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,213 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/hallowing_m0_express/linker_scripts/gcc/flash_without_bootloader.ld b/variants/hallowing_m0_express/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/hallowing_m0_express/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/hallowing_m0_express/openocd_scripts/hallowing_m0_express.cfg b/variants/hallowing_m0_express/openocd_scripts/hallowing_m0_express.cfg new file mode 100644 index 000000000..251f77aca --- /dev/null +++ b/variants/hallowing_m0_express/openocd_scripts/hallowing_m0_express.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Hallowing M0 Express OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/hallowing_m0_express/pins_arduino.h b/variants/hallowing_m0_express/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/hallowing_m0_express/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/hallowing_m0_express/variant.cpp b/variants/hallowing_m0_express/variant.cpp new file mode 100644 index 000000000..441e2faee --- /dev/null +++ b/variants/hallowing_m0_express/variant.cpp @@ -0,0 +1,130 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 9, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // RX: SERCOM2/PAD[1] TCC0/WO[1] + { PORTA, 10, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH2, TCC0_CH2, EXTERNAL_INT_10 }, // TX: SERCOM2/PAD[3] TCC0/WO[2] + + // 2..12 + // Digital Low + { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // D2 + { PORTA, 11, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_11 }, // D3 TCC0/WO[3] + { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // D4 TCC0/WO[0] + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // D5 TC3/WO[1] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // D6 TC3/WO[0] + { PORTA, 0, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_NONE }, // D7 - backlight TCC2/WO[0] + + // Digital High + { PORTA, 12, PIO_TIMER, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // D8 + { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // D9 TCC0/WO[3] + { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // D10 TCC0/WO[6] + { PORTA, 21, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_5 }, // D11 TCC0/WO[7] + { PORTA, 22, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH4, TCC0_CH4, EXTERNAL_INT_6 }, // D12 TCC0/WO[4] + + // 13 (LED) + { PORTA, 23, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH5, TCC0_CH5, EXTERNAL_INT_7 }, // D13 TCC0/WO[5] + + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A0 - ADC/AIN[0] + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel2, PWM4_CH0, TC4_CH0, EXTERNAL_INT_8 }, // A1 - ADC/AIN[2] + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel3, PWM4_CH1, TC4_CH1, EXTERNAL_INT_9 }, // A2 - ADC/AIN[3] + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // A3 - ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // A4 - ADC/AIN[5] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // A5 - TCC1/WO[0] + + // Extra Analog pins! 20..25 + { PORTB, 2, PIO_ANALOG, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A6 - VBATT - ADC/AIN[10] + { PORTB, 3, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel11, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // A7 - same as MISO + { PORTA, 8, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // A8 same as D4 + { PORTA, 9, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // A9 same as RX + { PORTA, 10, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel18, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // A10 same as TX + { PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel19, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // A11 same as D3 + + // 26..27 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 16, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // Sercom 3.0 SDA + { PORTA, 17, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // Sercom 3.0 SCL + + + // 28..30 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTB, 03, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash MISO + { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash MOSI + { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash SCK + + // 31..32 - USB + // -------------------- + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 33..35 - Secondary SPI + // ---------------------- + { PORTA, 13, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // MISO: SERCOM4/PAD[1] + { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2] + { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3] + // 36 Secondary SPI SS + { PORTA, 7, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // FlashCS + + // 37 TFT reset + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // SPI Flash SS + // 38 TFT DC + { PORTA, 28, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + // 39 TFT CS + { PORTA, 1, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Dotstar Data + + // D40 dup of D8 + { PORTA, 12, PIO_TIMER, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // D8 + + // 41 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 42 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom2, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM2_Handler() +{ + Serial1.IrqHandler(); +} + diff --git a/variants/hallowing_m0_express/variant.h b/variants/hallowing_m0_express/variant.h new file mode 100644 index 000000000..8a84c6023 --- /dev/null +++ b/variants/hallowing_m0_express/variant.h @@ -0,0 +1,252 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ARDUINO_ZERO_ +#define _VARIANT_ARDUINO_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (42u) +#define NUM_DIGITAL_PINS (42u) +#define NUM_ANALOG_INPUTS (12u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) + //#define PIN_LED_RXL (31u) + //#define PIN_LED_TXL (32u) +#define PIN_LED PIN_LED_13 +//#define PIN_LED2 PIN_LED_RXL +//#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +#define NEOPIXEL_BUILTIN (8u) +#define PIN_NEOPIXEL NEOPIXEL_BUILTIN + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_A10 (PIN_A0 + 10) +#define PIN_A11 (PIN_A0 + 11) +#define PIN_DAC0 (14ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; +static const uint8_t A8 = PIN_A8 ; +static const uint8_t A9 = PIN_A9 ; +static const uint8_t A10 = PIN_A10 ; +static const uint8_t A11 = PIN_A11 ; + +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (38ul) +static const uint8_t ATN = PIN_ATN; + +// On-board SPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_SPI SPI1 +#define EXTERNAL_FLASH_USE_CS SS1 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_2) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (28u) +#define PIN_SPI_MOSI (29u) +#define PIN_SPI_SCK (30u) +#define PERIPH_SPI sercom5 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_1 + +static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +#define PIN_SPI1_MISO (33u) +#define PIN_SPI1_MOSI (34u) +#define PIN_SPI1_SCK (35u) +#define PERIPH_SPI1 sercom4 +#define PAD_SPI1_TX SPI_PAD_2_SCK_3 +#define PAD_SPI1_RX SERCOM_RX_PAD_1 + +static const uint8_t SS1 = 36; +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (26u) +#define PIN_WIRE_SCL (27u) +#define PERIPH_WIRE sercom3 +#define WIRE_IT_HANDLER SERCOM3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (40ul) +#define PIN_USB_DM (31ul) +#define PIN_USB_DP (32ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 +#define PIN_I2S_SD (9u) +#define PIN_I2S_SCK (1u) +#define PIN_I2S_FS (0u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/hallowing_m4/debug_scripts/variant.gdb b/variants/hallowing_m4/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/hallowing_m4/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/hallowing_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/hallowing_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..1bdea69ae --- /dev/null +++ b/variants/hallowing_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/hallowing_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/hallowing_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..9c0c4e06d --- /dev/null +++ b/variants/hallowing_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/circuitplay/openocd_scripts/arduino_zero.cfg b/variants/hallowing_m4/openocd_scripts/arduino_zero.cfg similarity index 100% rename from variants/circuitplay/openocd_scripts/arduino_zero.cfg rename to variants/hallowing_m4/openocd_scripts/arduino_zero.cfg diff --git a/variants/hallowing_m4/pins_arduino.h b/variants/hallowing_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/hallowing_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/hallowing_m4/variant.cpp b/variants/hallowing_m4/variant.cpp new file mode 100644 index 000000000..8f9ab0838 --- /dev/null +++ b/variants/hallowing_m4/variant.cpp @@ -0,0 +1,148 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // TX SERCOM 4.0 + { PORTB, 13, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // RX SERCOM 4.1 + + // 2..12 + // Digital Low + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // D2 + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // D3 + { PORTA, 14, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14 }, // D4 + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // D5 + { PORTA, 17, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // D6 + { PORTB, 15, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH0, TC5_CH0, EXTERNAL_INT_15 }, // D7 (LISIRQ) + + // Digital High + + { PORTB, 16, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_0 }, // D8 (NEOPIX) + { PORTA, 18, PIO_SERCOM, PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // D9 + { PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH1, TC3_CH1, EXTERNAL_INT_3 }, // D10 + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // D11 + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D12 + + // 13 (LED) + { PORTA, 23, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7 }, + + + // 14..23 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A0 (DAC0) + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // A1 (DAC1) + { PORTA, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // A2 + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // A3 + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // A4 + { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // A5 + + { PORTB, 1, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel13, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // A6, D20 - vbatt + { PORTB, 4, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // A7, D21 - Light + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // A8 / D2 + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A9 / D3 + + // 24..25 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, // SDA + { PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, // SCL + + + // 26..28 - SPI pins (MISO,MOSI,SCK) + // ---------------------- + { PORTB, 22, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // MISO: SERCOM5.2 + { PORTB, 23, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MOSI: SERCOM5.3 + { PORTA, 22, PIO_SERCOM_ALT, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, TC4_CH0, EXTERNAL_INT_6 }, // SCK: SERCOM 5.1 + + // 29..31 - USB + // -------------------- + { NOT_A_PORT, PIN_NOT_A_PIN, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable DOES NOT EXIST ON THIS BOARD + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 32 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 33..34 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT0 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT1 + + // ---------------------- + // 35..40 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + + // 41..46 - TFT SPI port + control pins + // -------------------- + { PORTA, 0, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_0 }, // D41 TFT MOSI (SERCOM1.0) + { PORTA, 1, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_1 }, // D42 TFT SCK (SERCOM1.1) + { NOT_A_PORT, PIN_NOT_A_PIN, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // D43 TFT MISO (unused) + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // D44 TFT CS + { PORTB, 31, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D45 TFT DC + { PORTB, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // D46 TFT RST + + { PORTB, 14, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D47 Backlight (not connected rev B) + + + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D48 - Cap Pin + { PORTB, 5, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D49 Speaker enable + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom4, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM4_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/hallowing_m4/variant.h b/variants/hallowing_m4/variant.h new file mode 100644 index 000000000..221821d59 --- /dev/null +++ b/variants/hallowing_m4/variant.h @@ -0,0 +1,254 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_HALLOWING_M4_ +#define _VARIANT_HALLOWING_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (50u) +#define NUM_DIGITAL_PINS (50u) +#define NUM_ANALOG_INPUTS (10u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) + +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (26u) +#define PIN_SPI_MOSI (27u) +#define PIN_SPI_SCK (28u) +#define PERIPH_SPI sercom5 +#define PAD_SPI_TX SPI_PAD_3_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 10 ; +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + // Internal SPI for TFT +#define PIN_SPI1_MOSI (41u) +#define PIN_SPI1_SCK (42u) +#define PIN_SPI1_MISO (43u) +#define PERIPH_SPI1 sercom1 +#define PAD_SPI1_TX SPI_PAD_0_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_2 + +static const uint8_t SS1 = 44 ; +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (24u) +#define PIN_WIRE_SCL (25u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler +#define WIRE_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (29ul) +#define PIN_USB_DM (30ul) +#define PIN_USB_DP (31ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (35u) +#define PIN_QSPI_CS (36u) +#define PIN_QSPI_IO0 (37u) +#define PIN_QSPI_IO1 (38u) +#define PIN_QSPI_IO2 (39u) +#define PIN_QSPI_IO3 (40u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_HALLOWING_M4_ */ + diff --git a/variants/itsybitsy_m0/debug_scripts/variant.gdb b/variants/itsybitsy_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/itsybitsy_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/mkrwifi1010/linker_scripts/gcc/flash_with_bootloader.ld b/variants/itsybitsy_m0/linker_scripts/gcc/flash_with_bootloader.ld similarity index 99% rename from variants/mkrwifi1010/linker_scripts/gcc/flash_with_bootloader.ld rename to variants/itsybitsy_m0/linker_scripts/gcc/flash_with_bootloader.ld index 5c0dcb4e0..357946455 100644 --- a/variants/mkrwifi1010/linker_scripts/gcc/flash_with_bootloader.ld +++ b/variants/itsybitsy_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -83,7 +83,6 @@ SECTIONS *(SORT(.ctors.*)) *(.ctors) - /* .dtors */ *crtbegin.o(.dtors) *crtbegin?.o(.dtors) diff --git a/variants/itsybitsy_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/itsybitsy_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/itsybitsy_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/itsybitsy_m0/openocd_scripts/itsybitsy_m0.cfg b/variants/itsybitsy_m0/openocd_scripts/itsybitsy_m0.cfg new file mode 100644 index 000000000..bdb6fd94c --- /dev/null +++ b/variants/itsybitsy_m0/openocd_scripts/itsybitsy_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/itsybitsy_m0/pins_arduino.h b/variants/itsybitsy_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/itsybitsy_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/itsybitsy_m0/variant.cpp b/variants/itsybitsy_m0/variant.cpp new file mode 100644 index 000000000..fa35301d7 --- /dev/null +++ b/variants/itsybitsy_m0/variant.cpp @@ -0,0 +1,126 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // RX: SERCOM0/PAD[3] + { PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // TX: SERCOM0/PAD[2] + + // 2..12 + // Digital Low + { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + { PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // TC3/WO[1] + { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // TCC0/WO[6] + { PORTA, 21, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + + // Digital High + { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] + { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] + { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // TCC0/WO[3] + + // 13 (LED) + { PORTA, 17, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // TCC2/WO[1] + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel2, PWM4_CH0, TC4_CH0, EXTERNAL_INT_8 }, // ADC/AIN[2] + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel3, PWM4_CH1, TC4_CH1, EXTERNAL_INT_9 }, // ADC/AIN[3] + { PORTA, 4, PIO_ANALOG, 0, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, 0, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // ADC/AIN[5] + { PORTB, 2, PIO_ANALOG, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[10] + + // Extra Analog pins! 20..25 + { PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel19, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // A6 same as D0 + { PORTA, 10, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel18, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // A7 same as D1 + { PORTA, 8, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // A8 same as D4 + { PORTA, 9, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // A9 same as D3 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // A10 (unavailable) + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // A11 same as D9 + + // 26..27 I2C pins (SDA/SCL and also EDBG:SDA/SCL) + // ---------------------- + { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // SCL: SERCOM3/PAD[1] + + // 28..30 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0] + { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2] + { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3] + + // 31..32 - RX/TX LEDS (PA31/PA28) (unused) + // -------------------- + { PORTA, 31, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + { PORTA, 28, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + + // 33..35 - USB + // -------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 36..38 - Secondary SPI + // ---------------------- + { PORTB, 03, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash MISO + { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI FLash MOSI + { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI FLash SCK + // 39 Secondary SPI SS + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // SPI Flash SS + + // 40 & 41 - internal DotStar + { PORTA, 0, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Dotstar Clock + { PORTA, 1, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Dotstar Data + + // 42 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 43 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); +} + diff --git a/variants/itsybitsy_m0/variant.h b/variants/itsybitsy_m0/variant.h new file mode 100644 index 000000000..e9b945fed --- /dev/null +++ b/variants/itsybitsy_m0/variant.h @@ -0,0 +1,248 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ITSYBITSY_ZERO_ +#define _VARIANT_ITSYBITSY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (26u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (12u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 12u) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 +// DotStar LED +#define PIN_DOTSTAR_DATA (41u) +#define PIN_DOTSTAR_CLK (40u) +#define PIN_DOTSTAR_CLOCK PIN_DOTSTAR_CLK +#define DOTSTAR_NUM (1u) + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_A10 (PIN_A0 + 10) +#define PIN_A11 (PIN_A0 + 11) +#define PIN_DAC0 (14ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; +static const uint8_t A8 = PIN_A8 ; +static const uint8_t A9 = PIN_A9 ; +static const uint8_t A10 = PIN_A10 ; +static const uint8_t A11 = PIN_A11 ; +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (38ul) +static const uint8_t ATN = PIN_ATN; + +// On-board SPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_SPI SPI1 +#define EXTERNAL_FLASH_USE_CS SS1 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_2) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (28u) +#define PIN_SPI_MOSI (29u) +#define PIN_SPI_SCK (30u) +#define PERIPH_SPI sercom4 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +#define PIN_SPI1_MISO (36u) +#define PIN_SPI1_MOSI (37u) +#define PIN_SPI1_SCK (38u) +#define PERIPH_SPI1 sercom5 +#define PAD_SPI1_TX SPI_PAD_2_SCK_3 +#define PAD_SPI1_RX SERCOM_RX_PAD_1 + +static const uint8_t SS1 = 39 ; // HW SS isn't used. Set here only for reference. +static const uint8_t MOSI1 = PIN_SPI_MOSI ; +static const uint8_t MISO1 = PIN_SPI_MISO ; +static const uint8_t SCK1 = PIN_SPI_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (26u) +#define PIN_WIRE_SCL (27u) +#define PERIPH_WIRE sercom3 +#define WIRE_IT_HANDLER SERCOM3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (33ul) +#define PIN_USB_DM (34ul) +#define PIN_USB_DP (35ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 +#define PIN_I2S_SD (9u) +#define PIN_I2S_SCK (1u) +#define PIN_I2S_FS (0u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/itsybitsy_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/itsybitsy_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..5fe575a0d --- /dev/null +++ b/variants/itsybitsy_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x80000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/itsybitsy_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/itsybitsy_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0123a0a23 --- /dev/null +++ b/variants/itsybitsy_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,215 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + . = ALIGN(4); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/itsybitsy_m4/pins_arduino.h b/variants/itsybitsy_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/itsybitsy_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/itsybitsy_m4/variant.cpp b/variants/itsybitsy_m4/variant.cpp new file mode 100644 index 000000000..35323cfcd --- /dev/null +++ b/variants/itsybitsy_m4/variant.cpp @@ -0,0 +1,131 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ + +// TCC0 IOSET6 +// TCC1 IOSET1 +// TCC2 IOSET1 +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 16, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, // SERCOM 3.1 + { PORTA, 17, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH1, TC2_CH1, EXTERNAL_INT_1 }, // SERCOM 3.0 + + // 2..12 + // Digital Low + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel7, TC1_CH1, TC1_CH1, EXTERNAL_INT_7 }, // D2 + { PORTB, 22, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // D3 + { PORTA, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC2_CH0, TC3_CH0, EXTERNAL_INT_14 }, // D4 + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC2_CH1, TC3_CH1, EXTERNAL_INT_15 }, // D5 + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // Dotstar Clock (D6) + { PORTA, 18, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH2, TC3_CH0, EXTERNAL_INT_2 }, // D7 + + // Digital High + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // Dotstar Data (D8) + { PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH3, TC3_CH1, EXTERNAL_INT_3 }, // D9 + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH0, NOT_ON_TIMER, EXTERNAL_INT_4 }, // D10 + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH1, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D11 + { PORTA, 23, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, NOT_ON_TIMER, EXTERNAL_INT_7 }, // D12 + + // 13 (LED) + { PORTA, 22, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_6 }, // D13 + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4, TC0_CH0, TC0_CH0, EXTERNAL_INT_4 }, + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 }, + + // Extra Analog pin #20 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel7, TC1_CH1, TC1_CH1, EXTERNAL_INT_7 }, // A6 aka D2 + + // 21..22 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, TC2_CH0, EXTERNAL_INT_12 }, // SERCOM 2.0 + { PORTA, 13, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, TC2_CH1, EXTERNAL_INT_13 }, // SERCOM 2.1 + + // 23..25 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTB, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MISO SERCOM 1.3 + { PORTA, 1, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_1 }, // SCK SERCOM 1.1 + { PORTA, 0, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_0 }, // MOSI SERCOM 1.0 + + // 26..28 - USB + // -------------------- + { PORTA, 27, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // USB/DP + + // 29 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // DAC/VREFP + + // ---------------------- + // 30 - 31 Alternate use of A0 and A1 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT[0] + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // DAC/VOUT[1] + + + // ---------------------- + // 32 - 37 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC0, TC1, TC2, TC3 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom3, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM3_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/itsybitsy_m4/variant.h b/variants/itsybitsy_m4/variant.h new file mode 100644 index 000000000..dd6da9ba7 --- /dev/null +++ b/variants/itsybitsy_m4/variant.h @@ -0,0 +1,261 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ITSYBITSY_M4_ +#define _VARIANT_ITSYBITSY_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (38u) +#define NUM_DIGITAL_PINS (26u) +#define NUM_ANALOG_INPUTS (7u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 +// DotStar LED +#define PIN_DOTSTAR_DATA (8u) +#define PIN_DOTSTAR_CLK (6u) +#define PIN_DOTSTAR_CLOCK PIN_DOTSTAR_CLK +#define DOTSTAR_NUM (1u) + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (26ul) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (23u) +#define PIN_SPI_SCK (24u) +#define PIN_SPI_MOSI (25u) +#define PERIPH_SPI sercom1 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_3 + +static const uint8_t SS = PIN_A2 ; +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (21u) +#define PIN_WIRE_SCL (22u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler +#define WIRE_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (26ul) +#define PIN_USB_DM (27ul) +#define PIN_USB_DP (28ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +#define I2S_DEVICE 0 +// no I2S on G19! + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (32u) +#define PIN_QSPI_CS (33u) +#define PIN_QSPI_IO0 (34u) +#define PIN_QSPI_IO1 (35u) +#define PIN_QSPI_IO2 (36u) +#define PIN_QSPI_IO3 (37u) + +//PCC Pins +#define PIN_PCC_DEN1 (PIN_SPI_MOSI) +#define PIN_PCC_DEN2 (PIN_SPI_SCK) +#define PIN_PCC_CLK (PIN_SPI_MISO) +#define PIN_PCC_D0 (13u) +#define PIN_PCC_D1 (12u) +#define PIN_PCC_D2 (10u) +#define PIN_PCC_D3 (11u) +#define PIN_PCC_D4 (9u) +#define PIN_PCC_D5 (8u) +#define PIN_PCC_D6 (1u) +#define PIN_PCC_D7 (0u) +#define PIN_PCC_D8 (5u) +#define PIN_PCC_D9 (6u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ITSYBITSY_M4_ */ + diff --git a/variants/matrixportal_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/matrixportal_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..1bdea69ae --- /dev/null +++ b/variants/matrixportal_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/matrixportal_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/matrixportal_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..9c0c4e06d --- /dev/null +++ b/variants/matrixportal_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/matrixportal_m4/pins_arduino.h b/variants/matrixportal_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/matrixportal_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/matrixportal_m4/variant.cpp b/variants/matrixportal_m4/variant.cpp new file mode 100644 index 000000000..df23508fe --- /dev/null +++ b/variants/matrixportal_m4/variant.cpp @@ -0,0 +1,173 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ + +//TCC0 IOSET 6 +//TCC1 IOSET 1 +//TC0 IOSET 1 +//TC1 IOSET 1 +//TC2 IOSET 2 +//TC3 IOSET 1 +//TC4 IOSET 1 +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 1, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_1 }, // RX: SERCOM1/PAD[1] + { PORTA, 0, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_0 }, // TX: SERCOM1/PAD[0] + + // 2..3 buttons + { PORTB, 22, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // Up + { PORTB, 23, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // Down + + // 4 neopixel + { PORTA, 23, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // NeoPixel + + // 5..6 I2C + { PORTB, 31, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // SERCOM5.1 SDA + { PORTB, 30, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // SERCOM5.0 SCL + + // 7..12 RGBRGB pins + { PORTB, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // R1 + { PORTB, 1, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // G1 + { PORTB, 2, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // B1 + { PORTB, 3, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // R2 + { PORTB, 4, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // G2 + { PORTB, 5, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // B2 + + // 13 LED + { PORTA, 14, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC1_CH2, TCC1_CH2, EXTERNAL_INT_14 }, // Red LED + + // 14..21 Control pins + { PORTB, 6, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // CLK + { PORTB, 14, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // LAT + { PORTB, 12, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // OE + { PORTB, 7, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // ADDR A + { PORTB, 8, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // ADDR B + { PORTB, 9, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // ADDR C + { PORTB, 15, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // ADDR D + { PORTB, 13, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // ADDR E + + // 22..26 Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A0 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // A1 + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4, TC0_CH0, TC0_CH0, EXTERNAL_INT_4 }, // A2 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 }, // A3 + { PORTA, 7, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel7, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // A4 + + // 27..28 ESP UART + // ---------------------- + { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, // RX: SERCOM4/PAD[1] + { PORTA, 13, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, // TX: SERCOM4/PAD[0] + + // 29..33 ESP control + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH0, NOT_ON_TIMER, EXTERNAL_INT_4 }, // ESP GPIO0 + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH1, NOT_ON_TIMER, EXTERNAL_INT_5 }, // ESP Reset + { PORTA, 22, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_6 }, // ESP Busy + { PORTA, 18, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH2, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ESP RTS + { PORTB, 17, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_1 }, // ESP CS + + // 34..36 ESP SPI + { PORTA, 16, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, // SCK: SERCOM3/PAD[1] + { PORTA, 17, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH1, TC2_CH1, EXTERNAL_INT_1 }, // MISO: SERCOM3/PAD[0] + { PORTA, 19, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH3, TC3_CH1, EXTERNAL_INT_3 }, // MOSI: SERCOM1/PAD[3] + + // 37..39 - USB + // -------------------- + { NOT_A_PORT, 0, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable DOES NOT EXIST ON THIS BOARD + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 27, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 40 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 41..46 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 47 LIS IRQ + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // IRQ + + // 48..50 external SPI #2 on sercom 0 + { PORTA, 5, PIO_SERCOM_ALT, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // SCK SERCOM 0.1 + { PORTA, 4, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4, TC0_CH0, TC0_CH0, EXTERNAL_INT_4 }, // MOSI SERCOM 0.0 + { PORTA, 7, PIO_SERCOM_ALT, PIN_ATTR_ANALOG, ADC_Channel7, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MISO SERCOM 0.3 +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom1, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM1_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM1_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM1_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM1_3_Handler() +{ + Serial1.IrqHandler(); +} + + +// sercom for internal ESP32 UART connection +Uart Serial2( &sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX ) ; + +void SERCOM4_0_Handler() +{ + Serial2.IrqHandler(); +} +void SERCOM4_1_Handler() +{ + Serial2.IrqHandler(); +} +void SERCOM4_2_Handler() +{ + Serial2.IrqHandler(); +} +void SERCOM4_3_Handler() +{ + Serial2.IrqHandler(); +} diff --git a/variants/matrixportal_m4/variant.h b/variants/matrixportal_m4/variant.h new file mode 100644 index 000000000..deedf8502 --- /dev/null +++ b/variants/matrixportal_m4/variant.h @@ -0,0 +1,275 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_MATRIXPORTAL_M4_ +#define _VARIANT_MATRIXPORTAL_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (40u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (6u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +//#define PIN_LED_RXL (25u) +//#define PIN_LED_TXL (26u) +#define PIN_LED PIN_LED_13 +//#define PIN_LED2 PIN_LED_RXL +//#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +#define PIN_NEOPIXEL (4) + +/* + * Analog pins + */ +#define PIN_A0 (22ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) + +#define PIN_DAC0 (22ul) +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + + + +/* WiFi interfaces */ +#define SerialESP32 Serial2 +#define SerialNina SerialESP32 +#define SPIWIFI SPI +#define ESP32_GPIO0 29 +#define ESP32_RESETN 30 +#define SPIWIFI_SS 33 +#define SPIWIFI_ACK 31 +#define SPIWIFI_RESET ESP32_RESETN +#define NINA_GPIO0 ESP32_GPIO0 +#define NINA_RESETN ESP32_RESETN +#define NINA_ACK SPIWIFI_ACK +#define NINA_CTS SPIWIFI_ACK +#define NINA_RTS NINA_GPIO0 + + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +// Serial2 +#define PIN_SERIAL2_RX (27ul) +#define PIN_SERIAL2_TX (28ul) +#define PAD_SERIAL2_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL2_TX (UART_TX_PAD_0) + + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_SCK (34u) +#define PIN_SPI_MISO (35u) +#define PIN_SPI_MOSI (36u) +#define PERIPH_SPI sercom3 +#define PAD_SPI_TX SPI_PAD_3_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = 33 ; +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +#define PIN_SPI1_SCK (48u) +#define PIN_SPI1_MOSI (49u) +#define PIN_SPI1_MISO (50u) +#define PERIPH_SPI1 sercom0 +#define PAD_SPI1_TX SPI_PAD_0_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_3 + +static const uint8_t SS1 = PIN_A3 ; +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (5u) +#define PIN_WIRE_SCL (6u) +#define PERIPH_WIRE sercom5 +#define WIRE_IT_HANDLER SERCOM5_Handler +#define WIRE_IT_HANDLER_0 SERCOM5_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM5_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM5_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM5_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (37ul) +#define PIN_USB_DM (38ul) +#define PIN_USB_DP (39ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (41u) +#define PIN_QSPI_CS (42u) +#define PIN_QSPI_IO0 (43u) +#define PIN_QSPI_IO1 (44u) +#define PIN_QSPI_IO2 (45u) +#define PIN_QSPI_IO3 (46u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; +extern Uart Serial2; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_MATRIX_PORTAL_M4_ */ + diff --git a/variants/metro_m0/debug_scripts/variant.gdb b/variants/metro_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/metro_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/metro_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/metro_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..7d75f819d --- /dev/null +++ b/variants/metro_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,213 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/metro_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/metro_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/metro_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/metro_m0/openocd_scripts/metro_m0.cfg b/variants/metro_m0/openocd_scripts/metro_m0.cfg new file mode 100644 index 000000000..06b66f57a --- /dev/null +++ b/variants/metro_m0/openocd_scripts/metro_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Metro M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/metro_m0/pins_arduino.h b/variants/metro_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/metro_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/metro_m0/variant.cpp b/variants/metro_m0/variant.cpp new file mode 100644 index 000000000..b4836efe8 --- /dev/null +++ b/variants/metro_m0/variant.cpp @@ -0,0 +1,127 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // RX: SERCOM0/PAD[3] + { PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // TX: SERCOM0/PAD[2] + + // 2..12 + // Digital Low + { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + { PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // TC3/WO[1] + { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // TCC0/WO[6] + { PORTA, 21, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + + // Digital High + { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] + { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] + { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // TCC0/WO[3] + + // 13 (LED) + { PORTA, 17, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // TCC2/WO[1] + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel2, PWM4_CH0, TC4_CH0, EXTERNAL_INT_8 }, // ADC/AIN[2] + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel3, PWM4_CH1, TC4_CH1, EXTERNAL_INT_9 }, // ADC/AIN[3] + { PORTA, 4, PIO_ANALOG, 0, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, 0, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // ADC/AIN[5] + { PORTB, 2, PIO_ANALOG, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[10] + + + // Extra Analog pins! 20..25 + { PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel19, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // A6 same as D0 + { PORTA, 10, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel18, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // A7 same as D1 + { PORTA, 8, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // A8 same as D4 + { PORTA, 9, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // A9 same as D5 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // A10 same as D8 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // A11 same as D9 + + // 26..27 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // SCL: SERCOM3/PAD[1] + + // 28..30 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0] + { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2] + { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3] + + // 31..32 - RX/TX LEDS (PA31/PA27) + // -------------------- + { PORTA, 31, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + { PORTA, 27, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + + // 33..35 - USB + // -------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 36..38 - Secondary SPI + // ---------------------- + { PORTB, 03, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI Flash MISO + { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI FLash MOSI + { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SPI FLash SCK + // 39 Secondary SPI SS + { PORTA, 13, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // SPI Flash SS + + // 40 - Internal NeoPixel + { PORTA, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + + // 41 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 42 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); +} + diff --git a/variants/metro_m0/variant.h b/variants/metro_m0/variant.h new file mode 100644 index 000000000..5aa2e8525 --- /dev/null +++ b/variants/metro_m0/variant.h @@ -0,0 +1,253 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ARDUINO_ZERO_ +#define _VARIANT_ARDUINO_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (26u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (31u) +#define PIN_LED_TXL (32u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +#define NEOPIXEL_BUILTIN (40u) +#define PIN_NEOPIXEL NEOPIXEL_BUILTIN + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_A10 (PIN_A0 + 10) +#define PIN_A11 (PIN_A0 + 11) +#define PIN_DAC0 (14ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; +static const uint8_t A8 = PIN_A8 ; +static const uint8_t A9 = PIN_A9 ; +static const uint8_t A10 = PIN_A10 ; +static const uint8_t A11 = PIN_A11 ; + +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (38ul) +static const uint8_t ATN = PIN_ATN; + +// On-board SPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_SPI SPI1 +#define EXTERNAL_FLASH_USE_CS SS1 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_2) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (28u) +#define PIN_SPI_MOSI (29u) +#define PIN_SPI_SCK (30u) +#define PERIPH_SPI sercom4 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +#define PIN_SPI1_MISO (36u) +#define PIN_SPI1_MOSI (37u) +#define PIN_SPI1_SCK (38u) +#define PERIPH_SPI1 sercom5 +#define PAD_SPI1_TX SPI_PAD_2_SCK_3 +#define PAD_SPI1_RX SERCOM_RX_PAD_1 + +static const uint8_t SS1 = 39 ; // HW SS isn't used. Set here only for reference. +static const uint8_t MOSI1 = PIN_SPI_MOSI ; +static const uint8_t MISO1 = PIN_SPI_MISO ; +static const uint8_t SCK1 = PIN_SPI_SCK ; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (26u) +#define PIN_WIRE_SCL (27u) +#define PERIPH_WIRE sercom3 +#define WIRE_IT_HANDLER SERCOM3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (33ul) +#define PIN_USB_DM (34ul) +#define PIN_USB_DP (35ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 +#define PIN_I2S_SD (9u) +#define PIN_I2S_SCK (1u) +#define PIN_I2S_FS (0u) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial5; +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/metro_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/metro_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..5fe575a0d --- /dev/null +++ b/variants/metro_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x80000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/metro_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/metro_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0123a0a23 --- /dev/null +++ b/variants/metro_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,215 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + . = ALIGN(4); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/metro_m4/pins_arduino.h b/variants/metro_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/metro_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/metro_m4/variant.cpp b/variants/metro_m4/variant.cpp new file mode 100644 index 000000000..528a25ce7 --- /dev/null +++ b/variants/metro_m4/variant.cpp @@ -0,0 +1,148 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 23, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7 }, // RX: SERCOM3/PAD[1] + { PORTA, 22, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, TC4_CH0, EXTERNAL_INT_6 }, // TX: SERCOM3/PAD[0] + + // 2..12 + // Digital Low + { PORTB, 17, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_1 }, // d2 + { PORTB, 16, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_0 }, // d3 + { PORTB, 13, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC3_CH1, TC4_CH1, EXTERNAL_INT_13 }, // d4 + { PORTB, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH0, TC5_CH0, EXTERNAL_INT_14 }, // d5 + { PORTB, 15, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH1, TC5_CH1, EXTERNAL_INT_15 }, // d6 + { PORTB, 12, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC3_CH0, TC4_CH0, EXTERNAL_INT_12 }, // d7 + + // Digital High + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH1, NOT_ON_TIMER, EXTERNAL_INT_5 }, // d8 + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH0, NOT_ON_TIMER, EXTERNAL_INT_4 }, // d9 + { PORTA, 18, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH2, TC3_CH0, EXTERNAL_INT_2 }, // d10 + { PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH3, TC3_CH1, EXTERNAL_INT_3 }, // d11 + { PORTA, 17, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH1, TC2_CH1, EXTERNAL_INT_1 }, // d12 + + // 13 (LED) + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, TC0_CH1, EXTERNAL_INT_5 }, + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 }, + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4, TC0_CH0, TC0_CH0, EXTERNAL_INT_4 }, + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel2, TC4_CH0, TC4_CH0, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel3, TC4_CH1, TC4_CH1, EXTERNAL_INT_9 }, + + // Extra Analog pins! 20..21 + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // same as sda + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, //same as scl + + // 22..23 I2C pins (SDA/SCL) + // ---------------------- + { PORTB, 2, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC2_CH2, NOT_ON_TIMER, EXTERNAL_INT_2 }, //sda + { PORTB, 3, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, //scl + + // 24..26 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTA, 14, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14 }, + { PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, + { PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, + + // 27..28 - RX/TX LEDS (PB06/PA27) + // -------------------- + { PORTB, 6, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // used as output only + { PORTA, 27, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // used as output only + + // 29..31 - USB + // -------------------- + { PORTB, 7, PIO_COM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // USB/DP + + // 32..34 - Secondary SPI + // ---------------------- + { PORTA, 18, PIO_SERCOM, PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, //same as d10 + { PORTA, 19, PIO_SERCOM, PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, //same as d11 + { PORTA, 17, PIO_SERCOM, PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, //same as d12 + + // 35 - Secondary SPI cs + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, //same as d10 + + // 36 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // DAC/VREFP + + // ---------------------- + // 37 - 38 Alternate use of A0 and A1 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT[0] + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // DAC/VOUT[1] + + // 39 - LED #13 duplicate placeholder + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, + + // 40 - Internal NeoPixel + { PORTB, 22, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // used as output only + + // ---------------------- + // 41 - 46 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom3, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM3_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/metro_m4/variant.h b/variants/metro_m4/variant.h new file mode 100644 index 000000000..2b510e744 --- /dev/null +++ b/variants/metro_m4/variant.h @@ -0,0 +1,270 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_METRO_M4_ +#define _VARIANT_METRO_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (26u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (27u) +#define PIN_LED_TXL (28u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +#define PIN_NEOPIXEL (40) + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (39ul) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (24u) +#define PIN_SPI_MOSI (26u) +#define PIN_SPI_SCK (25u) +#define PERIPH_SPI sercom2 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = PIN_A2 ; +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (22u) +#define PIN_WIRE_SCL (23u) +#define PERIPH_WIRE sercom5 +#define WIRE_IT_HANDLER SERCOM5_Handler +#define WIRE_IT_HANDLER_0 SERCOM5_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM5_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM5_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM5_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (29ul) +#define PIN_USB_DM (30ul) +#define PIN_USB_DP (31ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 + +#define PIN_I2S_SDO (8u) +#define PIN_I2S_SDI (1u) +#define PIN_I2S_SCK (3u) +#define PIN_I2S_FS (9u) +#define PIN_I2S_MCK (2u) + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (41u) +#define PIN_QSPI_CS (42u) +#define PIN_QSPI_IO0 (43u) +#define PIN_QSPI_IO1 (44u) +#define PIN_QSPI_IO2 (45u) +#define PIN_QSPI_IO3 (46u) + +//PCC Pins +#define PIN_PCC_DEN1 (PIN_SPI_MOSI) +#define PIN_PCC_DEN2 (PIN_SPI_SCK) +#define PIN_PCC_CLK (PIN_SPI_MISO) +#define PIN_PCC_D0 (13u) +#define PIN_PCC_D1 (12u) +#define PIN_PCC_D2 (10u) +#define PIN_PCC_D3 (11u) +#define PIN_PCC_D4 (9u) +#define PIN_PCC_D5 (8u) +#define PIN_PCC_D6 (1u) +#define PIN_PCC_D7 (0u) +#define PIN_PCC_D8 (5u) +#define PIN_PCC_D9 (6u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_METRO_M4_ */ + diff --git a/variants/metro_m4_airlift/linker_scripts/gcc/flash_with_bootloader.ld b/variants/metro_m4_airlift/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..5fe575a0d --- /dev/null +++ b/variants/metro_m4_airlift/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x80000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/metro_m4_airlift/linker_scripts/gcc/flash_without_bootloader.ld b/variants/metro_m4_airlift/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0123a0a23 --- /dev/null +++ b/variants/metro_m4_airlift/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,215 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + . = ALIGN(4); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/metro_m4_airlift/pins_arduino.h b/variants/metro_m4_airlift/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/metro_m4_airlift/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/metro_m4_airlift/variant.cpp b/variants/metro_m4_airlift/variant.cpp new file mode 100644 index 000000000..a160346fd --- /dev/null +++ b/variants/metro_m4_airlift/variant.cpp @@ -0,0 +1,172 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 23, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7 }, // RX: SERCOM3/PAD[1] + { PORTA, 22, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, TC4_CH0, EXTERNAL_INT_6 }, // TX: SERCOM3/PAD[0] + + // 2..12 + // Digital Low + { PORTB, 17, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_1 }, + { PORTB, 16, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_0 }, + { PORTB, 13, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC3_CH1, TC4_CH1, EXTERNAL_INT_13 }, + { PORTB, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH0, TC5_CH0, EXTERNAL_INT_14 }, + { PORTB, 15, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH1, TC5_CH1, EXTERNAL_INT_15 }, + { PORTB, 12, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC3_CH0, TC4_CH0, EXTERNAL_INT_12 }, + + // Digital High + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH1, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH0, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 18, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH2, TC3_CH0, EXTERNAL_INT_2 }, + { PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH3, TC3_CH1, EXTERNAL_INT_3 }, + { PORTA, 17, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH1, TC2_CH1, EXTERNAL_INT_1 }, + + // 13 (LED) + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, + + // 14..19 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, TC0_CH1, EXTERNAL_INT_5 }, + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 }, + { PORTB, 0, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel12, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // NOT SAME AS METRO M4!! + { PORTB, 8, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel2, TC4_CH0, TC4_CH0, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel3, TC4_CH1, TC4_CH1, EXTERNAL_INT_9 }, + + // Extra Analog pins! 20..21 + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // same as sda + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, //same as scl + + // 22..23 I2C pins (SDA/SCL) + // ---------------------- + { PORTB, 2, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC2_CH2, NOT_ON_TIMER, EXTERNAL_INT_2 }, //sda + { PORTB, 3, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, //scl + + // 24..26 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTA, 14, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14 }, + { PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, + { PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, + + // 27..28 - RX/TX LEDS (PB06/PB07) NOT SAME AS METRO M4!!! + // -------------------- + { PORTB, 6, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // used as output only + { PORTB, 7, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // used as output only + + // 29..31 - USB + // -------------------- + { PORTA, 27, PIO_COM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // USB Host enable NOT SAME AS METRO M4!!! + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // USB/DP + + // ESP RX, TX, RTS (32-34) + { PORTA, 7, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // RX: SERCOM0.3 + { PORTA, 4, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // TX: SERCOM0.0 + { PORTB, 23, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, + + // ESP GPIO0, CS, BUSY, RESET (35-38) + { PORTB, 1, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC1_CH3, TC3_CH0, EXTERNAL_INT_15 }, + { PORTB, 4, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTB, 5, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + + // 39 - SWO + { PORTB, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // used as output only + + // 40 - Internal NeoPixel + { PORTB, 22, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // used as output only + + // ---------------------- + // 41 - 46 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + + // 47 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // DAC/VREFP + + // ---------------------- + // 48 - 49 Alternate use of A0 and A1 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // DAC/VOUT[0] + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // DAC/VOUT[1] + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +// sercom for pins 0 & 1 UART +Uart Serial1( &sercom3, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM3_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM3_3_Handler() +{ + Serial1.IrqHandler(); +} + +// sercom for internal ESP32 UART connection +Uart Serial2( &sercom0, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX ) ; + +void SERCOM0_0_Handler() +{ + Serial2.IrqHandler(); +} +void SERCOM0_1_Handler() +{ + Serial2.IrqHandler(); +} +void SERCOM0_2_Handler() +{ + Serial2.IrqHandler(); +} +void SERCOM0_3_Handler() +{ + Serial2.IrqHandler(); +} diff --git a/variants/metro_m4_airlift/variant.h b/variants/metro_m4_airlift/variant.h new file mode 100644 index 000000000..d078f2099 --- /dev/null +++ b/variants/metro_m4_airlift/variant.h @@ -0,0 +1,289 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_METRO_M4_WIFI_ +#define _VARIANT_METRO_M4_WIFI_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (49u) +#define NUM_DIGITAL_PINS (20u) +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (27u) +#define PIN_LED_TXL (28u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) + +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (39ul) +static const uint8_t ATN = PIN_ATN; + + +/* WiFi interfaces */ +#define SerialESP32 Serial2 +#define SerialNina SerialESP32 +#define SPIWIFI SPI +#define ESP32_GPIO0 35 +#define ESP32_RESETN 38 +#define SPIWIFI_SS 36 +#define SPIWIFI_ACK 37 +#define SPIWIFI_RESET ESP32_RESETN +#define NINA_GPIO0 ESP32_GPIO0 +#define NINA_RESETN ESP32_RESETN +#define NINA_ACK SPIWIFI_ACK +#define NINA_CTS SPIWIFI_ACK +#define NINA_RTS NINA_GPIO0 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +// Serial2 +#define PIN_SERIAL2_RX (32ul) +#define PIN_SERIAL2_TX (33ul) +#define PAD_SERIAL2_RX (SERCOM_RX_PAD_3) +#define PAD_SERIAL2_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (24u) +#define PIN_SPI_MOSI (26u) +#define PIN_SPI_SCK (25u) +#define PERIPH_SPI sercom2 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = SPIWIFI_SS ; +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (22u) +#define PIN_WIRE_SCL (23u) +#define PERIPH_WIRE sercom5 +#define WIRE_IT_HANDLER SERCOM5_Handler +#define WIRE_IT_HANDLER_0 SERCOM5_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM5_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM5_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM5_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (29ul) +#define PIN_USB_DM (30ul) +#define PIN_USB_DP (31ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 + +#define PIN_I2S_SDO (8u) +#define PIN_I2S_SDI (1u) +#define PIN_I2S_SCK (3u) +#define PIN_I2S_FS (9u) +#define PIN_I2S_MCK (2u) + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (41u) +#define PIN_QSPI_CS (42u) +#define PIN_QSPI_IO0 (43u) +#define PIN_QSPI_IO1 (44u) +#define PIN_QSPI_IO2 (45u) +#define PIN_QSPI_IO3 (46u) + +//PCC Pins +#define PIN_PCC_DEN1 (PIN_SPI_MOSI) +#define PIN_PCC_DEN2 (PIN_SPI_SCK) +#define PIN_PCC_CLK (PIN_SPI_MISO) +#define PIN_PCC_D0 (13u) +#define PIN_PCC_D1 (12u) +#define PIN_PCC_D2 (10u) +#define PIN_PCC_D3 (11u) +#define PIN_PCC_D4 (9u) +#define PIN_PCC_D5 (8u) +#define PIN_PCC_D6 (1u) +#define PIN_PCC_D7 (0u) +#define PIN_PCC_D8 (5u) +#define PIN_PCC_D9 (6u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; +extern Uart Serial2; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_METRO_M4_WIFI_ */ + diff --git a/variants/mkr1000/variant.h b/variants/mkr1000/variant.h index 1918dfadd..ce9f6c12c 100644 --- a/variants/mkr1000/variant.h +++ b/variants/mkr1000/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) // Master clock frequency -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) // Pins // ---- diff --git a/variants/mkrfox1200/variant.h b/variants/mkrfox1200/variant.h index a6d7cad20..ade82e8ba 100644 --- a/variants/mkrfox1200/variant.h +++ b/variants/mkrfox1200/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) // Master clock frequency -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) // Pins // ---- diff --git a/variants/mkrgsm1400/variant.h b/variants/mkrgsm1400/variant.h index d24aa23c0..f3c2832aa 100644 --- a/variants/mkrgsm1400/variant.h +++ b/variants/mkrgsm1400/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) // Master clock frequency -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) // Pins // ---- @@ -196,4 +196,4 @@ extern Uart Serial2; #define SerialGSM Serial2 #define ARDUINO_GSM_COMPATIBILITY_WRAPPER -#define GSM_DEFAULT_STREAM SerialGSM \ No newline at end of file +#define GSM_DEFAULT_STREAM SerialGSM diff --git a/variants/mkrnb1500/variant.h b/variants/mkrnb1500/variant.h index dd3e36742..3482528ce 100644 --- a/variants/mkrnb1500/variant.h +++ b/variants/mkrnb1500/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) // Master clock frequency -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) // Pins // ---- diff --git a/variants/mkrwan1300/variant.h b/variants/mkrwan1300/variant.h index d398bba2a..7368e02f5 100644 --- a/variants/mkrwan1300/variant.h +++ b/variants/mkrwan1300/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) // Master clock frequency -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) // Pins // ---- diff --git a/variants/mkrwifi1010/variant.h b/variants/mkrwifi1010/variant.h index af7742553..dcd7f7775 100644 --- a/variants/mkrwifi1010/variant.h +++ b/variants/mkrwifi1010/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) // Master clock frequency -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) // Pins // ---- diff --git a/variants/mkrzero/variant.h b/variants/mkrzero/variant.h index 04a92334d..ca59b5ab2 100644 --- a/variants/mkrzero/variant.h +++ b/variants/mkrzero/variant.h @@ -30,7 +30,7 @@ #define VARIANT_MAINOSC (32768ul) // Master clock frequency -#define VARIANT_MCK (48000000ul) +#define VARIANT_MCK (F_CPU) // Pins // ---- diff --git a/variants/monster_m4sk/linker_scripts/gcc/flash_with_bootloader.ld b/variants/monster_m4sk/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..5fe575a0d --- /dev/null +++ b/variants/monster_m4sk/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x80000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/monster_m4sk/linker_scripts/gcc/flash_without_bootloader.ld b/variants/monster_m4sk/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0123a0a23 --- /dev/null +++ b/variants/monster_m4sk/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,215 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + . = ALIGN(4); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/monster_m4sk/pins_arduino.h b/variants/monster_m4sk/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/monster_m4sk/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/monster_m4sk/variant.cpp b/variants/monster_m4sk/variant.cpp new file mode 100644 index 000000000..45a5dc0ce --- /dev/null +++ b/variants/monster_m4sk/variant.cpp @@ -0,0 +1,107 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ + +// TCC0 IOSET6 +// TCC1 IOSET1 +// TCC2 IOSET1 +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - PDM Mic (but could also be used for UART or serial) + { PORTA, 16, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, // Uart RX on PDM pins (sercom 3.1/1.0) + { PORTA, 17, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH1, TC2_CH1, EXTERNAL_INT_1 }, // Uart TX on PDM pins (sercom 3.0/1.1) + + // 2..12 + // Digital Low + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // D2/A2 + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // D3/A3 + { PORTA, 4, PIO_DIGITAL, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4, TC0_CH0, TC0_CH0, EXTERNAL_INT_4 }, // D4 Right TFT Reset + { PORTA, 6, PIO_DIGITAL, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 }, // D5 Right TFT Chip Select + { PORTA, 7, PIO_DIGITAL, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel7, TC1_CH1, TC1_CH1, EXTERNAL_INT_7 }, // D6 Right TFT DC + { PORTA, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, TC2_CH0, EXTERNAL_INT_12 }, // D7 Right TFT MOSI + { PORTA, 13, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, TC2_CH1, EXTERNAL_INT_13 }, // D8 Right TFT SCK + { PORTB, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // D9 Left TFT Chip Select + { PORTB, 22, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // D10 Left TFT DC + { PORTB, 2, PIO_SERCOM_ALT, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // D11 Left TFT MOSI + { PORTB, 3, PIO_SERCOM_ALT, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // D12 Left TFT SCK + + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // D13 Red LED + + // 14..17 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + + // 18..19 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 0, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_0 }, // SDA SERCOM 1.0 + { PORTA, 1, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_1 }, // SCL SERCOM 1.1 + + { PORTA, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC2_CH0, TC3_CH0, EXTERNAL_INT_14 }, // D20 - Speaker enable + { PORTA, 23, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, NOT_ON_TIMER, EXTERNAL_INT_7 }, // 21 - Backlight + { PORTA, 22, PIO_DIGITAL, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, NOT_ON_TIMER, EXTERNAL_INT_6 }, // 22 - LISIRQ + + // D23 & D24 - SPI for PDM + { PORTA, 16, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH0, TC2_CH0, EXTERNAL_INT_0 }, // SPI clock for PDM SERCOM 3.1 + { PORTA, 17, PIO_SERCOM_ALT, PIN_ATTR_PWM_F, No_ADC_Channel, TCC1_CH1, TC2_CH1, EXTERNAL_INT_1 }, // SPI MISO for PDM SERCOM 3.3 + + // 25..27 - USB + // -------------------- + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // not used + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // USB/DP + + // 28 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // DAC/VREFP + + + // ---------------------- + // 29 - 34 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + + // 35 - SWD Clock + { PORTA, 30, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + // 36- SWD Data + { PORTA, 31, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC0, TC1, TC2, TC3 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; diff --git a/variants/monster_m4sk/variant.h b/variants/monster_m4sk/variant.h new file mode 100644 index 000000000..eb3a283fe --- /dev/null +++ b/variants/monster_m4sk/variant.h @@ -0,0 +1,258 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_MONSTER_M4SK_ +#define _VARIANT_MONSTER_M4SK_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (37u) +#define NUM_DIGITAL_PINS (37u) +#define NUM_ANALOG_INPUTS (4u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (26ul) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) // sercom3 +#define PIN_SERIAL1_TX (1ul) // sercom3 +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 3 + + // Right TFT +#define PIN_SPI_MISO (6u) // actually DC pin, ignored +#define PIN_SPI_SCK (8u) +#define PIN_SPI_MOSI (7u) +#define PERIPH_SPI sercom2 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_3 + +static const uint8_t SS = 5 ; +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + // Left TFT +#define PIN_SPI1_MISO (10u) // actually DC pin, ignored +#define PIN_SPI1_SCK (12u) +#define PIN_SPI1_MOSI (11u) +#define PERIPH_SPI1 sercom5 +#define PAD_SPI1_TX SPI_PAD_0_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_3 + +static const uint8_t SS1 = 9 ; +static const uint8_t MOSI1 = PIN_SPI_MOSI ; +static const uint8_t MISO1 = PIN_SPI_MISO ; +static const uint8_t SCK1 = PIN_SPI_SCK ; + +// SPI for PDM +#define PIN_SPI2_MISO (23u) +#define PIN_SPI2_SCK (24u) +#define PIN_SPI2_MOSI (13u) // actually LED, ignored +#define PERIPH_SPI2 sercom3 +#define PAD_SPI2_TX SPI_PAD_3_SCK_1 +#define PAD_SPI2_RX SERCOM_RX_PAD_0 + +static const uint8_t SS2 = 13 ; // also ignored +static const uint8_t MOSI2 = PIN_SPI_MOSI ; +static const uint8_t MISO2 = PIN_SPI_MISO ; +static const uint8_t SCK2 = PIN_SPI_SCK ; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (18u) +#define PIN_WIRE_SCL (19u) +#define PERIPH_WIRE sercom1 +#define WIRE_IT_HANDLER SERCOM1_Handler +#define WIRE_IT_HANDLER_0 SERCOM1_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM1_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM1_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM1_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (25ul) +#define PIN_USB_DM (26ul) +#define PIN_USB_DP (27ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +#define I2S_DEVICE 0 +// no I2S on G19! + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q64C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (29u) +#define PIN_QSPI_CS (30u) +#define PIN_QSPI_IO0 (31u) +#define PIN_QSPI_IO1 (32u) +#define PIN_QSPI_IO2 (33u) +#define PIN_QSPI_IO3 (34u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial + +#endif /* _MONSTER_M4SK_ */ + diff --git a/variants/neokeytrinkey_m0/debug_scripts/variant.gdb b/variants/neokeytrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/neokeytrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/neokeytrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/neokeytrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/neokeytrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/neokeytrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/neokeytrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/neokeytrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/neokeytrinkey_m0/openocd_scripts/neokeytrinkey_m0.cfg b/variants/neokeytrinkey_m0/openocd_scripts/neokeytrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/neokeytrinkey_m0/openocd_scripts/neokeytrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/neokeytrinkey_m0/pins_arduino.h b/variants/neokeytrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/neokeytrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/neokeytrinkey_m0/variant.cpp b/variants/neokeytrinkey_m0/variant.cpp new file mode 100644 index 000000000..e64ad7b21 --- /dev/null +++ b/variants/neokeytrinkey_m0/variant.cpp @@ -0,0 +1,51 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // NeoPixel + { PORTA, 15, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, + + // Mechanical switch + { PORTA, 28, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, + + // Touch pad + { PORTA, 7, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, + + + // USB pins + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // Fake DAC pin just so we can compile stuff + { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; diff --git a/variants/neokeytrinkey_m0/variant.h b/variants/neokeytrinkey_m0/variant.h new file mode 100644 index 000000000..27e532bf4 --- /dev/null +++ b/variants/neokeytrinkey_m0/variant.h @@ -0,0 +1,185 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_NEOKEYTRINKEY_ZERO_ +#define _VARIANT_NEOKEYTRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (6u) +#define NUM_DIGITAL_PINS (6u) +#define NUM_ANALOG_INPUTS (1u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (0u) +#define NUM_NEOPIXEL (1u) + +#define PIN_SWITCH 1 +#define PIN_TOUCH 2 + +/* + * Analog pins + */ +#define PIN_A0 (6ul) +#define PIN_A1 (2) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + * Fake SPI Interface just so we can compile + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO PIN_A0 +#define PIN_SPI_MOSI PIN_A0 +#define PIN_SPI_SCK PIN_A0 +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A0; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 0 + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (3ul) +#define PIN_USB_DM (4ul) +#define PIN_USB_DP (5ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +/* + * Serial interfaces + */ + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/neotrinkey_m0/debug_scripts/variant.gdb b/variants/neotrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/neotrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/neotrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/neotrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/neotrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/neotrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/neotrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/neotrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/neotrinkey_m0/openocd_scripts/neotrinkey_m0.cfg b/variants/neotrinkey_m0/openocd_scripts/neotrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/neotrinkey_m0/openocd_scripts/neotrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/neotrinkey_m0/pins_arduino.h b/variants/neotrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/neotrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/neotrinkey_m0/variant.cpp b/variants/neotrinkey_m0/variant.cpp new file mode 100644 index 000000000..150034974 --- /dev/null +++ b/variants/neotrinkey_m0/variant.cpp @@ -0,0 +1,50 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // NeoPixels + { PORTA, 5, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, + + // Touch Pin 1 + { PORTA, 3, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, + + // Touch Pin 2 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, + + // USB pins + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // Fake DAC pin just so we can compile stuff + { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; diff --git a/variants/neotrinkey_m0/variant.h b/variants/neotrinkey_m0/variant.h new file mode 100644 index 000000000..3cf172c23 --- /dev/null +++ b/variants/neotrinkey_m0/variant.h @@ -0,0 +1,179 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_NEOTRINKEY_ZERO_ +#define _VARIANT_NEOTRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (7u) +#define NUM_DIGITAL_PINS (7u) +#define NUM_ANALOG_INPUTS (3u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (0u) +#define NUM_NEOPIXEL (4u) + +/* + * Analog pins + */ +#define PIN_A0 (6ul) +#define PIN_A1 (1) +#define PIN_A2 (2) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + * Fake SPI Interface just so we can compile + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO PIN_A0 +#define PIN_SPI_MOSI PIN_A0 +#define PIN_SPI_SCK PIN_A0 +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A0; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 0 + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (3ul) +#define PIN_USB_DM (4ul) +#define PIN_USB_DP (5ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/pirkey/debug_scripts/variant.gdb b/variants/pirkey/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/pirkey/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/pirkey/linker_scripts/gcc/flash_with_bootloader.ld b/variants/pirkey/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..4475f9511 --- /dev/null +++ b/variants/pirkey/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,211 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pirkey/linker_scripts/gcc/flash_without_bootloader.ld b/variants/pirkey/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0162f0774 --- /dev/null +++ b/variants/pirkey/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,212 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/mkrgsm1400/openocd_scripts/arduino_zero.cfg b/variants/pirkey/openocd_scripts/pirkey.cfg similarity index 100% rename from variants/mkrgsm1400/openocd_scripts/arduino_zero.cfg rename to variants/pirkey/openocd_scripts/pirkey.cfg diff --git a/variants/pirkey/pins_arduino.h b/variants/pirkey/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/pirkey/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/pirkey/variant.cpp b/variants/pirkey/variant.cpp new file mode 100644 index 000000000..61734c020 --- /dev/null +++ b/variants/pirkey/variant.cpp @@ -0,0 +1,96 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // GPIO 0 & 1 - DotStar internal data/clock + // ---------------------------------------- + { PORTA, 0, PIO_DIGITAL, 0, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // ADC/AIN[4] + { PORTA, 1, PIO_DIGITAL, 0, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // ADC/AIN[5] + + // GPIO 2 - Infrared In + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // USB Host enable - GPIO #2 + + // GPIO 3 & 4 (SWCLK & SWDIO) + // -------------------------- + { PORTA, 30, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 31, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // Placeholder #5 & 6 for 'txled' and 'rxled' + { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + { PORTA, 15, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, + + // GPIO 7, 8, 9 USB Host enable + // ---------------------------- + { PORTA, 27, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable - GPIO #7 + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM - GPIO #8 + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP - GPIO #9 + + + // Digital 10 - 14, Analog A0-A4 + // A0 + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + // A1 + { PORTA, 9, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + // A2 + { PORTA, 8, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + // A3 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + // A4 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; + +Uart Serial1( &sercom1, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM1_Handler() +{ + Serial1.IrqHandler(); +} + diff --git a/variants/pirkey/variant.h b/variants/pirkey/variant.h new file mode 100644 index 000000000..e6d0ce74a --- /dev/null +++ b/variants/pirkey/variant.h @@ -0,0 +1,183 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ARDUINO_ZERO_ +#define _VARIANT_ARDUINO_ZERO_ + +// The definitions here needs a SAMD core >=1.6.6 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10606 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (22u) +#define NUM_DIGITAL_PINS (22u) +#define NUM_ANALOG_INPUTS (5u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 5u) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (6u) +#define PIN_LED_TXL (5u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +// DotStar LED +#define INTERNAL_DS_DATA 0 +#define INTERNAL_DS_CLK 1 + +/* + * Analog pins + */ +#define PIN_A0 (10ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t DAC0 = PIN_DAC0; + + +#define ADC_RESOLUTION 12 + +/* + * Serial interfaces + */ + +// Serial1 (sercom 1) +#define PIN_SERIAL1_RX (4ul) // SWDIO PA31 +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) +#define PIN_SERIAL1_TX (3ul) // SWCLK PA30 +#define PAD_SERIAL1_TX (UART_TX_PAD_2) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 0 // shared with I2C/UART (can't do both) + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 0 + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (7ul) +#define PIN_USB_DM (8ul) +#define PIN_USB_DP (9ul) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/pixeltrinkey_m0/debug_scripts/variant.gdb b/variants/pixeltrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/pixeltrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/pixeltrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/pixeltrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/pixeltrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pixeltrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/pixeltrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/pixeltrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pixeltrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg b/variants/pixeltrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/pixeltrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/pixeltrinkey_m0/pins_arduino.h b/variants/pixeltrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/pixeltrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/pixeltrinkey_m0/variant.cpp b/variants/pixeltrinkey_m0/variant.cpp new file mode 100644 index 000000000..15c9cce9c --- /dev/null +++ b/variants/pixeltrinkey_m0/variant.cpp @@ -0,0 +1,52 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // DAC / A0 for monitoring 5V + { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC + + // Internal NeoPixel / D1 + { PORTA, 1, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // SPI MOSI/SCK + { PORTA, 4, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // D2 / MOSI + { PORTA, 5, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D3 / SCK + + // A6 / MISO + { PORTA, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // A6 / MISO + + // USB pins D5, D6, D7 + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; diff --git a/variants/pixeltrinkey_m0/variant.h b/variants/pixeltrinkey_m0/variant.h new file mode 100644 index 000000000..9a2b8222f --- /dev/null +++ b/variants/pixeltrinkey_m0/variant.h @@ -0,0 +1,189 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_PIXELTRINKEY_ZERO_ +#define _VARIANT_PIXELTRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (7u) +#define NUM_DIGITAL_PINS (4u) +#define NUM_ANALOG_INPUTS (1u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (1u) +#define NUM_NEOPIXEL (1u) + +#define PIN_DATA (2u) +#define PIN_CLOCK (3u) + +/* + * Analog pins + */ +#define PIN_A0 (0ul) +#define PIN_DAC0 PIN_A0 + +#define PIN_A6 (4ul) + +static const uint8_t A0 = PIN_A0; + +static const uint8_t A6 = PIN_A6; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (4ul) // off 3-pin JST, broken out +#define PIN_SPI_MOSI (2ul) +#define PIN_SPI_SCK (3ul) +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = (5ul); // not actually broken out +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces, fake just for compilation + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (2u) +#define PIN_WIRE_SCL (3u) +#define PERIPH_WIRE sercom0 +#define WIRE_IT_HANDLER SERCOM0_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (5ul) +#define PIN_USB_DM (6ul) +#define PIN_USB_DP (7ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/proxlighttrinkey_m0/debug_scripts/variant.gdb b/variants/proxlighttrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/proxlighttrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/proxlighttrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/proxlighttrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/proxlighttrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/proxlighttrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/proxlighttrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/proxlighttrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/proxlighttrinkey_m0/openocd_scripts/proxlighttrinkey_m0.cfg b/variants/proxlighttrinkey_m0/openocd_scripts/proxlighttrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/proxlighttrinkey_m0/openocd_scripts/proxlighttrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/proxlighttrinkey_m0/pins_arduino.h b/variants/proxlighttrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/proxlighttrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/proxlighttrinkey_m0/variant.cpp b/variants/proxlighttrinkey_m0/variant.cpp new file mode 100644 index 000000000..d9688d084 --- /dev/null +++ b/variants/proxlighttrinkey_m0/variant.cpp @@ -0,0 +1,57 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // Fake DAC A0 pin just so we can compile stuff + { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC + + // touch 1 / A1 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + // touch 2 / A2 + { PORTA, 3, PIO_ANALOG, (PIN_ATTR_ANALOG), ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // ADC/AIN[3] + + // NeoPixel / D3 + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // TC3/WO[1] + + // I2C SDA D4 & SCL D5 + { PORTA, 16, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_0 }, // D4 / SDA / PWM + { PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_1 }, // D5 / SCL / PWM + + // Interrupt D6 + { PORTA, 0, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, + + // USB pins D7, D8, D9 + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; diff --git a/variants/proxlighttrinkey_m0/variant.h b/variants/proxlighttrinkey_m0/variant.h new file mode 100644 index 000000000..93554eafc --- /dev/null +++ b/variants/proxlighttrinkey_m0/variant.h @@ -0,0 +1,193 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_PROXLIGHTTRINKEY_ZERO_ +#define _VARIANT_PROXLIGHTTRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (10u) +#define NUM_DIGITAL_PINS (6u) +#define NUM_ANALOG_INPUTS (3u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (3u) +#define NUM_NEOPIXEL (2u) + +// TOUCH PINS +#define PIN_TOUCH1 1 +#define PIN_TOUCH2 2 + +#define PIN_INTERRUPT 6 + +/* + * Analog pins + */ +#define PIN_A0 (0ul) +#define PIN_A1 (1) +#define PIN_A2 (2) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + * Fake SPI Interface just so we can compile + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO PIN_A0 +#define PIN_SPI_MOSI PIN_A0 +#define PIN_SPI_SCK PIN_A0 +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A0; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (4u) +#define PIN_WIRE_SCL (5u) +#define PERIPH_WIRE sercom1 +#define WIRE_IT_HANDLER SERCOM1_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (5ul) +#define PIN_USB_DM (6ul) +#define PIN_USB_DP (7ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/pybadge_airlift_m4/debug_scripts/variant.gdb b/variants/pybadge_airlift_m4/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/pybadge_airlift_m4/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/pybadge_airlift_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/pybadge_airlift_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..1bdea69ae --- /dev/null +++ b/variants/pybadge_airlift_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pybadge_airlift_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/pybadge_airlift_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..9c0c4e06d --- /dev/null +++ b/variants/pybadge_airlift_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/mkrwan1300/openocd_scripts/arduino_zero.cfg b/variants/pybadge_airlift_m4/openocd_scripts/arduino_zero.cfg similarity index 100% rename from variants/mkrwan1300/openocd_scripts/arduino_zero.cfg rename to variants/pybadge_airlift_m4/openocd_scripts/arduino_zero.cfg diff --git a/variants/pybadge_airlift_m4/pins_arduino.h b/variants/pybadge_airlift_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/pybadge_airlift_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/pybadge_airlift_m4/variant.cpp b/variants/pybadge_airlift_m4/variant.cpp new file mode 100644 index 000000000..ce2304ba1 --- /dev/null +++ b/variants/pybadge_airlift_m4/variant.cpp @@ -0,0 +1,154 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[] = + { + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + {PORTB, 17, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_1}, + {PORTB, 16, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_0}, + + // 2..12 + // Digital Low + {PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3}, + {PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2}, + {PORTA, 14, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14}, + {PORTA, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0}, + {PORTA, 18, PIO_SERCOM, PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2}, + {PORTB, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH0, TC5_CH0, EXTERNAL_INT_14}, + + // Digital High + {PORTA, 15, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15}, // D8 - NEOPIXEL + {PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH1, TC3_CH1, EXTERNAL_INT_3}, + {PORTA, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4}, + {PORTA, 21, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5}, + {PORTA, 22, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, TC4_CH0, EXTERNAL_INT_6}, + + // 13 (LED) + {PORTA, 23, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7}, + + // 14..23 - Analog pins + // -------------------- + {PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2}, + {PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5}, + {PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8}, + {PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9}, + {PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6}, + {PORTA, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10}, + + {PORTB, 1, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel13, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1}, // A6, D20 - vbatt + {PORTB, 4, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4}, // A7, D21 - Light + {PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2}, // A8 / D2 + {PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2}, // A9 / D3 + + // 24..25 I2C pins (SDA/SCL) + // ---------------------- + {PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12}, // SDA + {PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13}, // SCL + + // 26..28 - SPI pins (MISO,MOSI,SCK) + // ---------------------- + {PORTB, 22, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6}, // MISO: SERCOM1/PAD[2] + {PORTB, 23, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7}, // MOSI: SERCOM1/PAD[3] + {PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1}, // SCK: SERCOM1/PAD[1] + + // 29..31 - USB + // -------------------- + {NOT_A_PORT, PIN_NOT_A_PIN, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, // USB Host enable DOES NOT EXIST ON THIS BOARD + {PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, // USB/DM + {PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, // USB/DP + + // 32 (AREF) + {PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, // DAC/VREFP + + // ---------------------- + // 33..34 - Alternate use of A0 (DAC output) + {PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, // DAC/VOUT0 + {PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, // DAC/VOUT1 + + // ---------------------- + // 35..40 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + {PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, + {PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, + {PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, + {PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, + {PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, + {PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, + + // 41..46 - TFT SPI port + control pins + // -------------------- + {PORTB, 15, PIO_SERCOM, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH1, TC5_CH1, EXTERNAL_INT_15}, // SERCOM 4.3 MOSI + {PORTB, 13, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13}, // SERCOM 4.1 SCK + {PORTB, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12}, // SERCOM 4.0 'miso' (NC) + {PORTB, 6, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6}, // D44 TFT CS + {PORTB, 5, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5}, // D45 TFT DC + {PORTB, 7, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7}, // D46 TFT RST + + // 47 - backlight + {PORTA, 1, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_1}, // D47 TFT BACKLITE + + // 48 - button control + {PORTB, 31, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15}, // D48 button clock + {PORTB, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14}, // D49 button data + {PORTB, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0}, // D50 button latch + + // D51 Speaker enable + {PORTA, 27, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, + + // ESP GPIO0, BUSY, RESET (52-54) + {PORTA, 31, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE}, // D52 ESP32_GPIO0 + {PORTA, 0, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_0}, // D53 ESP32_BUSY + {PORTB, 12, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC3_CH0, TC4_CH0, EXTERNAL_INT_12}, // D54 ESP32_RESET + +}; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM5_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/pybadge_airlift_m4/variant.h b/variants/pybadge_airlift_m4/variant.h new file mode 100644 index 000000000..0887238d5 --- /dev/null +++ b/variants/pybadge_airlift_m4/variant.h @@ -0,0 +1,271 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_PYBADGE_AIRLIFT_M4_ +#define _VARIANT_PYBADGE_AIRLIFT_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (55u) +#define NUM_DIGITAL_PINS (25u) +#define NUM_ANALOG_INPUTS (10u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) + +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (31ul) +static const uint8_t ATN = PIN_ATN; + +/* WiFi interfaces */ +#define SerialESP32 Serial1 +#define SerialNina SerialESP32 +#define SPIWIFI SPI +#define SPIWIFI_SS 4 +#define SPIWIFI_ACK 53 +#define ESP32_GPIO0 52 +#define ESP32_RESETN 54 +#define SPIWIFI_RESET ESP32_RESETN +#define NINA_GPIO0 ESP32_GPIO0 +#define NINA_ACK SPIWIFI_ACK +#define NINA_RESETN ESP32_RESETN + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (26u) +#define PIN_SPI_MOSI (27u) +#define PIN_SPI_SCK (28u) +#define PERIPH_SPI sercom1 +#define PAD_SPI_TX SPI_PAD_3_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 9 ; // SERCOM1 last PAD is present on d9 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +// Internal SPI for TFT +#define PIN_SPI1_MOSI (41u) +#define PIN_SPI1_SCK (42u) +#define PIN_SPI1_MISO (43u) +#define PERIPH_SPI1 sercom4 +#define PAD_SPI1_TX SPI_PAD_3_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_0 + +static const uint8_t SS1 = 44 ; +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (24u) +#define PIN_WIRE_SCL (25u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler +#define WIRE_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (29ul) +#define PIN_USB_DM (30ul) +#define PIN_USB_DP (31ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (35u) +#define PIN_QSPI_CS (36u) +#define PIN_QSPI_IO0 (37u) +#define PIN_QSPI_IO1 (38u) +#define PIN_QSPI_IO2 (39u) +#define PIN_QSPI_IO3 (40u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_PYBADGE_AIRLIFT_M4_ */ + diff --git a/variants/pybadge_m4/debug_scripts/variant.gdb b/variants/pybadge_m4/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/pybadge_m4/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/pybadge_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/pybadge_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..1bdea69ae --- /dev/null +++ b/variants/pybadge_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pybadge_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/pybadge_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..9c0c4e06d --- /dev/null +++ b/variants/pybadge_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/mkrwifi1010/openocd_scripts/arduino_zero.cfg b/variants/pybadge_m4/openocd_scripts/arduino_zero.cfg similarity index 100% rename from variants/mkrwifi1010/openocd_scripts/arduino_zero.cfg rename to variants/pybadge_m4/openocd_scripts/arduino_zero.cfg diff --git a/variants/pybadge_m4/pins_arduino.h b/variants/pybadge_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/pybadge_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/pybadge_m4/variant.cpp b/variants/pybadge_m4/variant.cpp new file mode 100644 index 000000000..ebc2c7f48 --- /dev/null +++ b/variants/pybadge_m4/variant.cpp @@ -0,0 +1,152 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 17, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_1 }, + { PORTB, 16, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_0 }, + + // 2..12 + // Digital Low + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 14, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14 }, + { PORTA, 16, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, + { PORTA, 18, PIO_SERCOM_ALT, PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTB, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH0, TC5_CH0, EXTERNAL_INT_14 }, + + // Digital High + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D8 - NEOPIXEL + { PORTA, 19, PIO_SERCOM_ALT, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH1, TC3_CH1, EXTERNAL_INT_3 }, + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTA, 22, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, TC4_CH0, EXTERNAL_INT_6 }, + + // 13 (LED) + { PORTA, 23, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7 }, + + // 14..23 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, + + { PORTB, 1, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel13, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // A6, D20 - vbatt + { PORTB, 4, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // A7, D21 - Light + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // A8 / D2 + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A9 / D3 + + + // 24..25 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, // SDA + { PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, // SCL + + // 26..28 - SPI pins (MISO,MOSI,SCK) + // ---------------------- + { PORTB, 22, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // MISO: SERCOM1/PAD[2] + { PORTB, 23, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MOSI: SERCOM1/PAD[3] + { PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // SCK: SERCOM1/PAD[1] + + // 29..31 - USB + // -------------------- + { NOT_A_PORT, PIN_NOT_A_PIN, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable DOES NOT EXIST ON THIS BOARD + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 32 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 33..34 - Alternate use of A0 (DAC output) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT0 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT1 + + // ---------------------- + // 35..40 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 41..46 - TFT SPI port + control pins + // -------------------- + { PORTB, 15, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // SERCOM 4.3 MOSI + { PORTB, 13, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // SERCOM 4.1 SCK + { PORTB, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // SERCOM 4.0 'miso' (NC) + { PORTB, 7, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // D44 TFT CS + { PORTB, 5, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D45 TFT DC + { PORTA, 0, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_0 }, // D46 TFT RST + + // 47 - backlight + { PORTA, 1, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_1 }, // D47 TFT BACKLITE + + // 48 - button control + { PORTB, 31, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D48 button clock + { PORTB, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // D49 button data + { PORTB, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // D50 button latch + + // D51 Speaker enable + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // D52 Bandgap input + { NOT_A_PORT, PIN_NOT_A_PIN, PIO_NOT_A_PIN, PIN_ATTR_ANALOG, ADC_Channel_PTAT, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM5_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/pybadge_m4/variant.h b/variants/pybadge_m4/variant.h new file mode 100644 index 000000000..fbfb6824a --- /dev/null +++ b/variants/pybadge_m4/variant.h @@ -0,0 +1,272 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_PYBADGE_M4_ +#define _VARIANT_PYBADGE_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (51u) +#define NUM_DIGITAL_PINS (25u) +#define NUM_ANALOG_INPUTS (10u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_BANDGAP_ADC 52 + +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (31ul) +static const uint8_t ATN = PIN_ATN; + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 3 + +#define PIN_SPI_MISO (26u) +#define PIN_SPI_MOSI (27u) +#define PIN_SPI_SCK (28u) +#define PERIPH_SPI sercom1 +#define PAD_SPI_TX SPI_PAD_3_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 9 ; // SERCOM1 last PAD is present on d9 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +// Internal SPI for TFT +#define PIN_SPI1_MOSI (41u) +#define PIN_SPI1_SCK (42u) +#define PIN_SPI1_MISO (43u) +#define PERIPH_SPI1 sercom4 +#define PAD_SPI1_TX SPI_PAD_3_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_0 + +static const uint8_t SS1 = 44 ; +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + +// SPI for PDM mic +#define PIN_SPI2_MOSI (9u) +#define PIN_SPI2_SCK (5u) +#define PIN_SPI2_MISO (6u) +#define PERIPH_SPI2 sercom3 +#define PAD_SPI2_TX SPI_PAD_3_SCK_1 +#define PAD_SPI2_RX SERCOM_RX_PAD_2 + +static const uint8_t SS2 = 10 ; +static const uint8_t MOSI2 = PIN_SPI2_MOSI ; +static const uint8_t MISO2 = PIN_SPI2_MISO ; +static const uint8_t SCK2 = PIN_SPI2_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (24u) +#define PIN_WIRE_SCL (25u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler +#define WIRE_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (29ul) +#define PIN_USB_DM (30ul) +#define PIN_USB_DP (31ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (35u) +#define PIN_QSPI_CS (36u) +#define PIN_QSPI_IO0 (37u) +#define PIN_QSPI_IO1 (38u) +#define PIN_QSPI_IO2 (39u) +#define PIN_QSPI_IO3 (40u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_PYBADGE_M4_ */ + diff --git a/variants/pygamer_advance_m4/debug_scripts/variant.gdb b/variants/pygamer_advance_m4/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/pygamer_advance_m4/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/pygamer_advance_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/pygamer_advance_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..1bdea69ae --- /dev/null +++ b/variants/pygamer_advance_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pygamer_advance_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/pygamer_advance_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..9c0c4e06d --- /dev/null +++ b/variants/pygamer_advance_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pygamer_advance_m4/openocd_scripts/arduino_zero.cfg b/variants/pygamer_advance_m4/openocd_scripts/arduino_zero.cfg new file mode 100644 index 000000000..36c65c32d --- /dev/null +++ b/variants/pygamer_advance_m4/openocd_scripts/arduino_zero.cfg @@ -0,0 +1,30 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +source [find interface/cmsis-dap.cfg] + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/pygamer_advance_m4/pins_arduino.h b/variants/pygamer_advance_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/pygamer_advance_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/pygamer_advance_m4/variant.cpp b/variants/pygamer_advance_m4/variant.cpp new file mode 100644 index 000000000..34f7e9831 --- /dev/null +++ b/variants/pygamer_advance_m4/variant.cpp @@ -0,0 +1,151 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 17, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_1 }, + { PORTB, 16, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_0 }, + + // 2..12 + // Digital Low + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 14, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14 }, + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, + { PORTA, 18, PIO_SERCOM, PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTB, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH0, TC5_CH0, EXTERNAL_INT_14 }, + + // Digital High + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D8 - NEOPIXEL + { PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH1, TC3_CH1, EXTERNAL_INT_3 }, + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTA, 22, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, TC4_CH0, EXTERNAL_INT_6 }, + + // 13 (LED) + { PORTA, 23, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7 }, + + // 14..25 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, + + { PORTB, 1, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel13, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // A6, D20 - vbatt + { PORTB, 4, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // A7, D21 - Light + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // A8 / D2 + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A9 / D3 + { PORTB, 6, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel8, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // A10 / JOYY + { PORTB, 7, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel9, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // A11 / JOYX + + // 26..27 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, // SDA + { PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, // SCL + + // 28..30 - SPI pins (MISO,MOSI,SCK) + // ---------------------- + { PORTB, 22, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // MISO: SERCOM1/PAD[2] + { PORTB, 23, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MOSI: SERCOM1/PAD[3] + { PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // SCK: SERCOM1/PAD[1] + + // 31..33 - USB + // -------------------- + { NOT_A_PORT, PIN_NOT_A_PIN, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable DOES NOT EXIST ON THIS BOARD + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 34 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 35..40 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 41..46 - TFT SPI port + control pins + // -------------------- + { PORTB, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // SERCOM 4.0 MOSI + { PORTB, 13, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // SERCOM 4.1 SCK + { PORTB, 15, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // SERCOM 4.3 'miso' (NC) + { PORTB, 15, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D44 TFT CS + { PORTA, 0, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_0 }, // D45 TFT DC + { PORTB, 5, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D46 TFT RST + + // 47 - backlight + { PORTA, 1, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_1 }, // D47 TFT BACKLITE + + // 48 - button control + { PORTB, 31, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D48 button clock + { PORTB, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // D49 button data + { PORTB, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // D50 button latch + + // D51 Speaker enable + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // ---------------------- + // D52..D53 - Alternate use of A0 (DAC outputs) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT0 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT1 + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM5_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/pygamer_advance_m4/variant.h b/variants/pygamer_advance_m4/variant.h new file mode 100644 index 000000000..cd5e271dd --- /dev/null +++ b/variants/pygamer_advance_m4/variant.h @@ -0,0 +1,263 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_PYGAMER_ADVANCE_M4_ +#define _VARIANT_PYGAMER_ADVANCE_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (54u) +#define NUM_DIGITAL_PINS (25u) +#define NUM_ANALOG_INPUTS (12u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_A10 (PIN_A0 + 10) +#define PIN_A11 (PIN_A0 + 11) + +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; +static const uint8_t A10 = PIN_A10; +static const uint8_t A11 = PIN_A11; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (31ul) +static const uint8_t ATN = PIN_ATN; + + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (28u) +#define PIN_SPI_MOSI (29u) +#define PIN_SPI_SCK (30u) +#define PERIPH_SPI sercom1 +#define PAD_SPI_TX SPI_PAD_3_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 4 ; // SD card CS +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + // Internal SPI for TFT +#define PIN_SPI1_MOSI (41u) +#define PIN_SPI1_SCK (42u) +#define PIN_SPI1_MISO (0u) +#define PERIPH_SPI1 sercom4 +#define PAD_SPI1_TX SPI_PAD_0_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_3 + +static const uint8_t SS1 = 44 ; +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (26u) +#define PIN_WIRE_SCL (27u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler +#define WIRE_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (31ul) +#define PIN_USB_DM (32ul) +#define PIN_USB_DP (33ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (35u) +#define PIN_QSPI_CS (36u) +#define PIN_QSPI_IO0 (37u) +#define PIN_QSPI_IO1 (38u) +#define PIN_QSPI_IO2 (39u) +#define PIN_QSPI_IO3 (40u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_PYGAMER_ADVANCE_M4_ */ + diff --git a/variants/pygamer_m4/debug_scripts/variant.gdb b/variants/pygamer_m4/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/pygamer_m4/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/pygamer_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/pygamer_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..1bdea69ae --- /dev/null +++ b/variants/pygamer_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pygamer_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/pygamer_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..9c0c4e06d --- /dev/null +++ b/variants/pygamer_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pygamer_m4/openocd_scripts/arduino_zero.cfg b/variants/pygamer_m4/openocd_scripts/arduino_zero.cfg new file mode 100644 index 000000000..36c65c32d --- /dev/null +++ b/variants/pygamer_m4/openocd_scripts/arduino_zero.cfg @@ -0,0 +1,30 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +source [find interface/cmsis-dap.cfg] + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/pygamer_m4/pins_arduino.h b/variants/pygamer_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/pygamer_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/pygamer_m4/variant.cpp b/variants/pygamer_m4/variant.cpp new file mode 100644 index 000000000..ffbccefe8 --- /dev/null +++ b/variants/pygamer_m4/variant.cpp @@ -0,0 +1,151 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 17, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH5, NOT_ON_TIMER, EXTERNAL_INT_1 }, + { PORTB, 16, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH4, NOT_ON_TIMER, EXTERNAL_INT_0 }, + + // 2..12 + // Digital Low + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 14, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH0, TC3_CH0, EXTERNAL_INT_14 }, + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, + { PORTA, 18, PIO_SERCOM, PIO_SERCOM, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTB, 14, PIO_DIGITAL, PIN_ATTR_PWM_F, No_ADC_Channel, TCC4_CH0, TC5_CH0, EXTERNAL_INT_14 }, + + // Digital High + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D8 - NEOPIXEL + { PORTA, 19, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC3_CH1, TC3_CH1, EXTERNAL_INT_3 }, + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 21, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTA, 22, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH2, TC4_CH0, EXTERNAL_INT_6 }, + + // 13 (LED) + { PORTA, 23, PIO_SERCOM, PIN_ATTR_PWM_G, No_ADC_Channel, TCC0_CH3, TC4_CH1, EXTERNAL_INT_7 }, + + // 14..25 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + { PORTA, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, + + { PORTB, 1, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel13, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // A6, D20 - vbatt + { PORTB, 4, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // A7, D21 - Light + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // A8 / D2 + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A9 / D3 + { PORTB, 6, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel8, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // A10 / JOYY + { PORTB, 7, PIO_ANALOG, PIN_ATTR_ANALOG_ALT, ADC_Channel9, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // A11 / JOYX + + // 26..27 I2C pins (SDA/SCL) + // ---------------------- + { PORTA, 12, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_12 }, // SDA + { PORTA, 13, PIO_SERCOM, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_13 }, // SCL + + // 28..30 - SPI pins (MISO,MOSI,SCK) + // ---------------------- + { PORTB, 22, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // MISO: SERCOM1/PAD[2] + { PORTB, 23, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MOSI: SERCOM1/PAD[3] + { PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // SCK: SERCOM1/PAD[1] + + // 31..33 - USB + // -------------------- + { NOT_A_PORT, PIN_NOT_A_PIN, PIO_NOT_A_PIN, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable DOES NOT EXIST ON THIS BOARD + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 34 (AREF) + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VREFP + + // ---------------------- + // 35..40 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // 41..46 - TFT SPI port + control pins + // -------------------- + { PORTB, 15, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // SERCOM 4.3 MOSI + { PORTB, 13, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // SERCOM 4.1 SCK + { PORTB, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // SERCOM 4.0 'miso' (NC) + { PORTB, 12, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // D44 TFT CS + { PORTB, 5, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D45 TFT DC + { PORTA, 0, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH0, TC2_CH0, EXTERNAL_INT_0 }, // D46 TFT RST + + // 47 - backlight + { PORTA, 1, PIO_DIGITAL, PIN_ATTR_PWM_E, No_ADC_Channel, TC2_CH1, TC2_CH1, EXTERNAL_INT_1 }, // D47 TFT BACKLITE + + // 48 - button control + { PORTB, 31, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D48 button clock + { PORTB, 30, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // D49 button data + { PORTB, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // D50 button latch + + // D51 Speaker enable + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // ---------------------- + // D52..D53 - Alternate use of A0 (DAC outputs) + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT0 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, DAC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // DAC/VOUT1 + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM5_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM5_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/pygamer_m4/variant.h b/variants/pygamer_m4/variant.h new file mode 100644 index 000000000..12c5b4ffb --- /dev/null +++ b/variants/pygamer_m4/variant.h @@ -0,0 +1,264 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_PYGAMER_M4_ +#define _VARIANT_PYGAMER_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (54u) +#define NUM_DIGITAL_PINS (25u) +#define NUM_ANALOG_INPUTS (12u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_A10 (PIN_A0 + 10) +#define PIN_A11 (PIN_A0 + 11) + +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; +static const uint8_t A10 = PIN_A10; +static const uint8_t A11 = PIN_A11; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (31ul) +static const uint8_t ATN = PIN_ATN; + + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_MISO (28u) +#define PIN_SPI_MOSI (29u) +#define PIN_SPI_SCK (30u) +#define PERIPH_SPI sercom1 +#define PAD_SPI_TX SPI_PAD_3_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 4 ; // SD card CS +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + // Internal SPI for TFT +#define PIN_SPI1_MOSI (41u) +#define PIN_SPI1_SCK (42u) +#define PIN_SPI1_MISO (0u) +#define PERIPH_SPI1 sercom4 +#define PAD_SPI1_TX SPI_PAD_3_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_0 + +static const uint8_t SS1 = 44 ; +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (26u) +#define PIN_WIRE_SCL (27u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler +#define WIRE_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (31ul) +#define PIN_USB_DM (32ul) +#define PIN_USB_DP (33ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q64C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (35u) +#define PIN_QSPI_CS (36u) +#define PIN_QSPI_IO0 (37u) +#define PIN_QSPI_IO1 (38u) +#define PIN_QSPI_IO2 (39u) +#define PIN_QSPI_IO3 (40u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_PYGAMER_M4_ */ + diff --git a/variants/pyportal_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/pyportal_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..5fe575a0d --- /dev/null +++ b/variants/pyportal_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x80000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pyportal_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/pyportal_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0123a0a23 --- /dev/null +++ b/variants/pyportal_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,215 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + . = ALIGN(4); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pyportal_m4/pins_arduino.h b/variants/pyportal_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/pyportal_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/pyportal_m4/variant.cpp b/variants/pyportal_m4/variant.cpp new file mode 100644 index 000000000..a74da78f6 --- /dev/null +++ b/variants/pyportal_m4/variant.cpp @@ -0,0 +1,151 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +// PyPortal uses ATSAMD51J20 (64-pin), Metro & Feather M4 use J19, Trellis uses 51G +// NOT SURE ABOUT PIN_ATTR_PWM_n VALUES, defaulting all to "E" for now, update as required +// Also setting PWM and TIMER pins to same value to start, update as required +// Is LIGHT pin connected/routed anywhere? + +/* NEW PIN DEFS IN PROGRESS: + + { PORTA, 3, PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel1 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // AREF - NOT USED + { PORTA, 30, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC6_CH0 , TC6_CH0 , EXTERNAL_INT_14 }, // SWCLK - not used? + { PORTA, 31, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC6_CH1 , TC6_CH1 , EXTERNAL_INT_15 }, // SWDIO - not used? + +*/ + + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 13, PIO_SERCOM , PIN_ATTR_NONE , No_ADC_Channel, TC4_CH1 , TCC3_CH1 , EXTERNAL_INT_13 }, // RXD (pin 0, to ESP32), SERCOM4/PAD[1] + { PORTB, 12, PIO_SERCOM , PIN_ATTR_NONE , No_ADC_Channel, TC4_CH0 , TCC3_CH0 , EXTERNAL_INT_12 }, // TXD (pin 1, to ESP32), SERCOM4/PAD[0] + + // 2..4 + { PORTB, 22, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // NEOPIX + { PORTA, 4, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4 , TC0_CH0 , TC0_CH0 , EXTERNAL_INT_4 }, // D3 (SENSE JST) + { PORTA, 5, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel5 , TC0_CH1 , TC0_CH1 , EXTERNAL_INT_5 }, // D4 (NEOPIX JST) + + // 5..12 ESP32 and TFT control lines + { PORTB, 16, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // ESP_BUSY + { PORTB, 15, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC5_CH1 , TC5_CH1 , EXTERNAL_INT_15 }, // ESP_GPIO0 + { PORTB, 17, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // ESP RESET + { PORTB, 14, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC5_CH0 , TC5_CH0 , EXTERNAL_INT_14 }, // ESP_CS + { PORTB, 4, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // TFT_RD + { PORTB, 5, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // TFT_RS + { PORTB, 6, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // TFT_CS + { PORTB, 7, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // TFT_TE + + // 13 (LED) + { PORTB, 23, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // D13 (LED) + + // 14..23 Analog pins + { PORTA, 2, PIO_ANALOG , PIN_ATTR_ANALOG , DAC_Channel0 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // AUDIO_OUT (A0) + { PORTA, 4, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4 , TC0_CH0 , TC0_CH0 , EXTERNAL_INT_4 }, // D3 (SENSE JST) + { PORTA, 7, PIO_DIGITAL , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel7 , TC1_CH1 , TC1_CH1 , EXTERNAL_INT_7 }, // Light sensor (A2) + { PORTA, 5, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel5 , TC0_CH1 , TC0_CH1 , EXTERNAL_INT_5 }, // D4 (NEOPIX JST) + { PORTB, 0, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel12 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // TOUCH_YD + { PORTB, 1, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel13 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // TOUCH_XL + { PORTA, 6, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6 , TC1_CH0 , TC1_CH0 , EXTERNAL_INT_6 }, // TOUCH_YU + { PORTB, 8, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel2 , TC4_CH0 , TC4_CH0 , EXTERNAL_INT_8 }, // TOUCH_XR + { PORTB, 2, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel14 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // SDA (JST), SERCOM5/PAD[0] - analog copy + { PORTB, 3, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel15 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // SCL (JST), SERCOM5/PAD[1] - analog copy + + // 24..26 more TFT control lines + { PORTA, 0, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH0 , TC2_CH0 , EXTERNAL_INT_0 }, // TFT_RESET + { PORTB, 31, PIO_DIGITAL , PIN_ATTR_PWM_F , No_ADC_Channel, TCC4_CH1 , TCC4_CH1 , EXTERNAL_INT_15 }, // TFT_BACKLITE + { PORTB, 9, PIO_DIGITAL , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel3 , TC4_CH1 , TC4_CH1 , EXTERNAL_INT_9 }, // TFT_WR, CCL/OUT[2] + + // 27..28 I2C pins + { PORTB, 2, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel14 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // SDA (JST), SERCOM5/PAD[0] + { PORTB, 3, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel15 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // SCL (JST), SERCOM5/PAD[1] + + // 29..31 SPI pins + { PORTA, 12, PIO_SERCOM , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH0 , TC2_CH0 , EXTERNAL_INT_12 }, // MOSI, SERCOM2/PAD[0] + { PORTA, 13, PIO_SERCOM , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH1 , TC2_CH1 , EXTERNAL_INT_13 }, // SCK, SERCOM2/PAD[1] + { PORTA, 14, PIO_SERCOM , PIN_ATTR_PWM_E , No_ADC_Channel, TC3_CH0 , TC3_CH0 , EXTERNAL_INT_14 }, // MISO, SERCOM2/PAD[2] + + // 32..33 Some SD card control + { PORTB, 30, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC0_CH0 , TC0_CH0 , EXTERNAL_INT_14 }, // SD_CS + { PORTA, 1, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH1 , TC2_CH1 , EXTERNAL_INT_1 }, // CARDDET + + // 34..41 LCD data + { PORTA, 16, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH0 , TC2_CH0 , EXTERNAL_INT_0 }, // LCD_DATA0 + { PORTA, 17, PIO_DIGITAL , PIN_ATTR_PWM_F , No_ADC_Channel, TCC1_CH1 , TC2_CH1 , EXTERNAL_INT_1 }, // LCD_DATA1 + { PORTA, 18, PIO_DIGITAL , PIN_ATTR_PWM_F , No_ADC_Channel, TCC1_CH2 , TC3_CH0 , EXTERNAL_INT_2 }, // LCD_DATA2 + { PORTA, 19, PIO_DIGITAL , PIN_ATTR_PWM_F , No_ADC_Channel, TCC1_CH3 , TC3_CH1 , EXTERNAL_INT_3 }, // LCD_DATA3 + { PORTA, 20, PIO_DIGITAL , PIN_ATTR_PWM_G , No_ADC_Channel, TCC0_CH0 , TC0_CH0 , EXTERNAL_INT_4 }, // LCD_DATA4 + { PORTA, 21, PIO_DIGITAL , PIN_ATTR_PWM_G , No_ADC_Channel, TCC0_CH0 , TC0_CH1 , EXTERNAL_INT_5 }, // LCD_DATA5 + { PORTA, 22, PIO_DIGITAL , PIN_ATTR_PWM_G , No_ADC_Channel, TCC0_CH2 , TC4_CH0 , EXTERNAL_INT_6 }, // LCD_DATA6 + { PORTA, 23, PIO_DIGITAL , PIN_ATTR_PWM_G , No_ADC_Channel, TCC0_CH3 , TC4_CH1 , EXTERNAL_INT_7 }, // LCD_DATA7 + + // 42..47 QSPI + { PORTB, 10, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, TC5_CH0 , TC5_CH0 , EXTERNAL_INT_10 }, // QSPI_SCK + { PORTB, 11, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, TC5_CH1 , TC5_CH1 , EXTERNAL_INT_11 }, // QSPI_CS + { PORTA, 8, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI }, // QSPI_DATA0 + { PORTA, 9, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // QSPI_DATA1 + { PORTA, 10, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // QSPI_DATA2 + { PORTA, 11, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // QSPI_DATA3 + + // 48..49 USB + { PORTA, 24, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB D- + { PORTA, 25, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB D+ + + // 50..51 + { PORTA, 27, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // Speaker shutdown + { PORTA, 15, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC3_CH1 , TC3_CH1 , EXTERNAL_INT_15 }, // ESP_RTS + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom4, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM4_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/pyportal_m4/variant.h b/variants/pyportal_m4/variant.h new file mode 100644 index 000000000..75fcb354c --- /dev/null +++ b/variants/pyportal_m4/variant.h @@ -0,0 +1,258 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_PYPORTAL_M4_ +#define _VARIANT_PYPORTAL_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (52u) +#define NUM_DIGITAL_PINS (42u) +#define NUM_ANALOG_INPUTS (9u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 10u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +//#define PIN_LED_RXL (27u) +//#define PIN_LED_TXL (28u) +#define PIN_LED PIN_LED_13 +//#define PIN_LED2 PIN_LED_RXL +//#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; + +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (39ul) // ??? +static const uint8_t ATN = PIN_ATN; + +/* WiFi interfaces */ +#define SerialNina Serial1 +#define SPIWIFI SPI +#define ESP32_GPIO0 6 +#define ESP32_RESETN 7 +#define SPIWIFI_SS 8 +#define SPIWIFI_ACK 5 +#define SPIWIFI_RESET 7 +#define NINA_GPIO0 ESP32_GPIO0 +#define NINA_RESETN ESP32_RESETN +#define NINA_ACK SPIWIFI_ACK +#define SerialESP32 Serial1 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (31u) +#define PIN_SPI_MOSI (29u) +#define PIN_SPI_SCK (30u) +#define PERIPH_SPI sercom2 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 32; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (27u) +#define PIN_WIRE_SCL (28u) +#define PERIPH_WIRE sercom5 +#define WIRE_IT_HANDLER SERCOM5_Handler +#define WIRE_IT_HANDLER_0 SERCOM5_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM5_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM5_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM5_3_Handler + + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (29ul) // ??? +#define PIN_USB_DM (48ul) +#define PIN_USB_DP (49ul) + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q64C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (42u) +#define PIN_QSPI_CS (43u) +#define PIN_QSPI_IO0 (44u) +#define PIN_QSPI_IO1 (45u) +#define PIN_QSPI_IO2 (46u) +#define PIN_QSPI_IO3 (47u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_PYPORTAL_M4_ */ + diff --git a/variants/pyportal_m4_titano/linker_scripts/gcc/flash_with_bootloader.ld b/variants/pyportal_m4_titano/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..5fe575a0d --- /dev/null +++ b/variants/pyportal_m4_titano/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x80000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pyportal_m4_titano/linker_scripts/gcc/flash_without_bootloader.ld b/variants/pyportal_m4_titano/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0123a0a23 --- /dev/null +++ b/variants/pyportal_m4_titano/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,215 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + . = ALIGN(4); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/pyportal_m4_titano/pins_arduino.h b/variants/pyportal_m4_titano/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/pyportal_m4_titano/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/pyportal_m4_titano/variant.cpp b/variants/pyportal_m4_titano/variant.cpp new file mode 100644 index 000000000..53cfdaca5 --- /dev/null +++ b/variants/pyportal_m4_titano/variant.cpp @@ -0,0 +1,151 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +// PyPortal uses ATSAMD51J20 (64-pin), Metro & Feather M4 use J19, Trellis uses 51G +// NOT SURE ABOUT PIN_ATTR_PWM_n VALUES, defaulting all to "E" for now, update as required +// Also setting PWM and TIMER pins to same value to start, update as required +// Is LIGHT pin connected/routed anywhere? + +/* NEW PIN DEFS IN PROGRESS: + + { PORTA, 3, PIO_ANALOG , PIN_ATTR_ANALOG , ADC_Channel1 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // AREF - NOT USED + { PORTA, 30, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC6_CH0 , TC6_CH0 , EXTERNAL_INT_14 }, // SWCLK - not used? + { PORTA, 31, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC6_CH1 , TC6_CH1 , EXTERNAL_INT_15 }, // SWDIO - not used? + +*/ + + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTB, 13, PIO_SERCOM , PIN_ATTR_NONE , No_ADC_Channel, TC4_CH1 , TCC3_CH1 , EXTERNAL_INT_13 }, // RXD (pin 0, to ESP32), SERCOM4/PAD[1] + { PORTB, 12, PIO_SERCOM , PIN_ATTR_NONE , No_ADC_Channel, TC4_CH0 , TCC3_CH0 , EXTERNAL_INT_12 }, // TXD (pin 1, to ESP32), SERCOM4/PAD[0] + + // 2..4 + { PORTB, 22, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // NEOPIX + { PORTA, 4, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4 , TC0_CH0 , TC0_CH0 , EXTERNAL_INT_4 }, // D3 (SENSE JST) + { PORTA, 5, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel5 , TC0_CH1 , TC0_CH1 , EXTERNAL_INT_5 }, // D4 (NEOPIX JST) + + // 5..12 ESP32 and TFT control lines + { PORTB, 16, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // ESP_BUSY + { PORTB, 15, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC5_CH1 , TC5_CH1 , EXTERNAL_INT_15 }, // ESP_GPIO0 + { PORTB, 17, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // ESP RESET + { PORTB, 14, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC5_CH0 , TC5_CH0 , EXTERNAL_INT_14 }, // ESP_CS + { PORTB, 4, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // TFT_RD + { PORTB, 5, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // TFT_RS + { PORTB, 6, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // TFT_CS + { PORTB, 7, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // TFT_TE + + // 13 (LED) + { PORTB, 23, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // D13 (LED) + + // 14..23 Analog pins + { PORTA, 2, PIO_ANALOG , PIN_ATTR_ANALOG , DAC_Channel0 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // AUDIO_OUT (A0) + { PORTA, 4, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel4 , TC0_CH0 , TC0_CH0 , EXTERNAL_INT_4 }, // D3 (SENSE JST) + { PORTA, 7, PIO_DIGITAL , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel7 , TC1_CH1 , TC1_CH1 , EXTERNAL_INT_7 }, // Light sensor (A2) + { PORTA, 5, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel5 , TC0_CH1 , TC0_CH1 , EXTERNAL_INT_5 }, // D4 (NEOPIX JST) + { PORTB, 0, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel12 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // TOUCH_YD + { PORTB, 1, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel13 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // TOUCH_XL + { PORTA, 6, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6 , TC1_CH0 , TC1_CH0 , EXTERNAL_INT_6 }, // TOUCH_YU + { PORTB, 8, PIO_ANALOG , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel2 , TC4_CH0 , TC4_CH0 , EXTERNAL_INT_8 }, // TOUCH_XR + { PORTB, 2, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel14 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // SDA (JST), SERCOM5/PAD[0] - analog copy + { PORTB, 3, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel15 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // SCL (JST), SERCOM5/PAD[1] - analog copy + + // 24..26 more TFT control lines + { PORTA, 0, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH0 , TC2_CH0 , EXTERNAL_INT_0 }, // TFT_RESET + { PORTB, 31, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC0_CH1 , TC0_CH1 , EXTERNAL_INT_15 }, // TFT_BACKLITE + { PORTB, 9, PIO_DIGITAL , (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel3 , TC4_CH1 , TC4_CH1 , EXTERNAL_INT_9 }, // TFT_WR, CCL/OUT[2] + + // 27..28 I2C pins + { PORTB, 2, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel14 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // SDA (JST), SERCOM5/PAD[0] + { PORTB, 3, PIO_SERCOM_ALT, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel15 , NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // SCL (JST), SERCOM5/PAD[1] + + // 29..31 SPI pins + { PORTA, 12, PIO_SERCOM , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH0 , TC2_CH0 , EXTERNAL_INT_12 }, // MOSI, SERCOM2/PAD[0] + { PORTA, 13, PIO_SERCOM , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH1 , TC2_CH1 , EXTERNAL_INT_13 }, // SCK, SERCOM2/PAD[1] + { PORTA, 14, PIO_SERCOM , PIN_ATTR_PWM_E , No_ADC_Channel, TC3_CH0 , TC3_CH0 , EXTERNAL_INT_14 }, // MISO, SERCOM2/PAD[2] + + // 32..33 Some SD card control + { PORTB, 30, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC0_CH0 , TC0_CH0 , EXTERNAL_INT_14 }, // SD_CS + { PORTA, 1, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH1 , TC2_CH1 , EXTERNAL_INT_1 }, // CARDDET + + // 34..41 LCD data + { PORTA, 16, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC2_CH0 , TC2_CH0 , EXTERNAL_INT_0 }, // LCD_DATA0 + { PORTA, 17, PIO_DIGITAL , PIN_ATTR_PWM_F , No_ADC_Channel, TCC1_CH1 , TC2_CH1 , EXTERNAL_INT_1 }, // LCD_DATA1 + { PORTA, 18, PIO_DIGITAL , PIN_ATTR_PWM_F , No_ADC_Channel, TCC1_CH2 , TC3_CH0 , EXTERNAL_INT_2 }, // LCD_DATA2 + { PORTA, 19, PIO_DIGITAL , PIN_ATTR_PWM_F , No_ADC_Channel, TCC1_CH3 , TC3_CH1 , EXTERNAL_INT_3 }, // LCD_DATA3 + { PORTA, 20, PIO_DIGITAL , PIN_ATTR_PWM_G , No_ADC_Channel, TCC0_CH0 , TC0_CH0 , EXTERNAL_INT_4 }, // LCD_DATA4 + { PORTA, 21, PIO_DIGITAL , PIN_ATTR_PWM_G , No_ADC_Channel, TCC0_CH0 , TC0_CH1 , EXTERNAL_INT_5 }, // LCD_DATA5 + { PORTA, 22, PIO_DIGITAL , PIN_ATTR_PWM_G , No_ADC_Channel, TCC0_CH2 , TC4_CH0 , EXTERNAL_INT_6 }, // LCD_DATA6 + { PORTA, 23, PIO_DIGITAL , PIN_ATTR_PWM_G , No_ADC_Channel, TCC0_CH3 , TC4_CH1 , EXTERNAL_INT_7 }, // LCD_DATA7 + + // 42..47 QSPI + { PORTB, 10, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, TC5_CH0 , TC5_CH0 , EXTERNAL_INT_10 }, // QSPI_SCK + { PORTB, 11, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, TC5_CH1 , TC5_CH1 , EXTERNAL_INT_11 }, // QSPI_CS + { PORTA, 8, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI }, // QSPI_DATA0 + { PORTA, 9, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // QSPI_DATA1 + { PORTA, 10, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // QSPI_DATA2 + { PORTA, 11, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // QSPI_DATA3 + + // 48..49 USB + { PORTA, 24, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB D- + { PORTA, 25, PIO_COM , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB D+ + + // 50..51 + { PORTA, 27, PIO_DIGITAL , PIN_ATTR_NONE , No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // Speaker shutdown + { PORTA, 15, PIO_DIGITAL , PIN_ATTR_PWM_E , No_ADC_Channel, TC3_CH1 , TC3_CH1 , EXTERNAL_INT_15 }, // ESP_RTS + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TCC3, TCC4, TC0, TC1, TC2, TC3, TC4, TC5 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TCC3_GCLK_ID, TCC4_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID } ; + + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom4, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM4_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/pyportal_m4_titano/variant.h b/variants/pyportal_m4_titano/variant.h new file mode 100644 index 000000000..0da7c158a --- /dev/null +++ b/variants/pyportal_m4_titano/variant.h @@ -0,0 +1,257 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_PYPORTAL_M4_TITANO_ +#define _VARIANT_PYPORTAL_M4_TITANO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (52u) +#define NUM_DIGITAL_PINS (42u) +#define NUM_ANALOG_INPUTS (9u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 10u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +//#define PIN_LED_RXL (27u) +//#define PIN_LED_TXL (28u) +#define PIN_LED PIN_LED_13 +//#define PIN_LED2 PIN_LED_RXL +//#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; +static const uint8_t A6 = PIN_A6; +static const uint8_t A7 = PIN_A7; +static const uint8_t A8 = PIN_A8; +static const uint8_t A9 = PIN_A9; + +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (39ul) // ??? +static const uint8_t ATN = PIN_ATN; + +/* WiFi interfaces */ +#define SerialNina Serial1 +#define SPIWIFI SPI +#define ESP32_GPIO0 6 +#define ESP32_RESETN 7 +#define SPIWIFI_SS 8 +#define SPIWIFI_ACK 5 +#define SPIWIFI_RESET 7 +#define NINA_GPIO0 ESP32_GPIO0 +#define NINA_RESETN ESP32_RESETN +#define NINA_ACK SPIWIFI_ACK +#define SerialESP32 Serial1 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (0ul) +#define PIN_SERIAL1_TX (1ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO (31u) +#define PIN_SPI_MOSI (29u) +#define PIN_SPI_SCK (30u) +#define PERIPH_SPI sercom2 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = 32; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (27u) +#define PIN_WIRE_SCL (28u) +#define PERIPH_WIRE sercom5 +#define WIRE_IT_HANDLER SERCOM5_Handler +#define WIRE_IT_HANDLER_0 SERCOM5_0_Handler +#define WIRE_IT_HANDLER_1 SERCOM5_1_Handler +#define WIRE_IT_HANDLER_2 SERCOM5_2_Handler +#define WIRE_IT_HANDLER_3 SERCOM5_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (29ul) // ??? +#define PIN_USB_DM (48ul) +#define PIN_USB_DP (49ul) + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q64C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (42u) +#define PIN_QSPI_CS (43u) +#define PIN_QSPI_IO0 (44u) +#define PIN_QSPI_IO1 (45u) +#define PIN_QSPI_IO2 (46u) +#define PIN_QSPI_IO3 (47u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_PYPORTAL_M4_TITANO_ */ + diff --git a/variants/qtpy_m0/debug_scripts/variant.gdb b/variants/qtpy_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/qtpy_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/qtpy_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/qtpy_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/qtpy_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/qtpy_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/qtpy_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/qtpy_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/qtpy_m0/openocd_scripts/qtpy_m0.cfg b/variants/qtpy_m0/openocd_scripts/qtpy_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/qtpy_m0/openocd_scripts/qtpy_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/qtpy_m0/pins_arduino.h b/variants/qtpy_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/qtpy_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/qtpy_m0/variant.cpp b/variants/qtpy_m0/variant.cpp new file mode 100644 index 000000000..4d5135036 --- /dev/null +++ b/variants/qtpy_m0/variant.cpp @@ -0,0 +1,86 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A0 / D0 / DAC + { PORTA, 3, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // A1 / D1 / AREF + { PORTA, 4, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // A2 / D2 / PWM + { PORTA, 5, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // A3 / D3 / PWM + + // I2C SDA & SCL + { PORTA, 16, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // D4 / SDA / PWM + { PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // D5 / SCL / PWM + + // UART TX & RX + { PORTA, 6, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // A6 / D6 / TX / PWM + { PORTA, 7, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // A7 / D7 / RX / PWM + + // SPI SCK, MISO, MOSI + { PORTA, 11, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), ADC_Channel19, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_11 }, // A8 / D8 / SCK / PWM + { PORTA, 9, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), ADC_Channel17, PWM1_CH3, TCC1_CH3, EXTERNAL_INT_9 }, // A9 / D9 / MISO / PWM + { PORTA, 10, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), ADC_Channel18, PWM0_CH2, TCC0_CH2, EXTERNAL_INT_10 }, // A10 / D10 / MOSI / PWM + + { PORTA, 18, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // D11 Neopix + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D12 Neopix power + + // D13 fake pin + { PORTA, 27, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as fake output only + + // SPI1 SCK, MISO, MOSI + { PORTA, 23, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH5, TCC0_CH5, EXTERNAL_INT_7 }, // D14 / SCK1 + { PORTA, 19, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_3 }, // D15 / MISO1 + { PORTA, 22, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH4, TCC0_CH4, EXTERNAL_INT_6 }, // D16 / MOSI1 + // SPI1 CS + { PORTA, 8, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), ADC_Channel16, PWM1_CH2, TCC1_CH2, EXTERNAL_INT_NMI }, // D17 / CS + + // USB pins + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); +} + +void initVariant(void) { + // special initialization code just for us + + // turn on neopixel + pinMode(12, OUTPUT); + digitalWrite(12, HIGH); +} diff --git a/variants/qtpy_m0/variant.h b/variants/qtpy_m0/variant.h new file mode 100644 index 000000000..1e4c4e0e1 --- /dev/null +++ b/variants/qtpy_m0/variant.h @@ -0,0 +1,234 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_QTPY_ZERO_ +#define _VARIANT_QTPY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (21u) +#define NUM_DIGITAL_PINS (21u) +#define NUM_ANALOG_INPUTS (9u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 +#define PIN_NEOPIXEL (11u) + +/* + * Analog pins + */ +#define PIN_A0 (0ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A6 (PIN_A0 + 6) +#define PIN_A7 (PIN_A0 + 7) +#define PIN_A8 (PIN_A0 + 8) +#define PIN_A9 (PIN_A0 + 9) +#define PIN_A10 (PIN_A0 + 10) +#define PIN_DAC0 (00ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; +static const uint8_t A8 = PIN_A8 ; +static const uint8_t A9 = PIN_A9 ; +static const uint8_t A10 = PIN_A10 ; +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +// On-board SPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q16C +#define EXTERNAL_FLASH_USE_SPI SPI1 +#define EXTERNAL_FLASH_USE_CS SS1 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_TX (6ul) +#define PIN_SERIAL1_RX (7ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_2) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + +#define PIN_SPI_SCK (8u) +#define PIN_SPI_MISO (9u) +#define PIN_SPI_MOSI (10u) +#define PERIPH_SPI sercom2 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_1 + +static const uint8_t SS = PIN_A0 ; // unused, just for reference +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +#define PIN_SPI1_SCK (14u) +#define PIN_SPI1_MISO (15u) +#define PIN_SPI1_MOSI (16u) +#define PERIPH_SPI1 sercom3 +#define PAD_SPI1_TX SPI_PAD_0_SCK_1 +#define PAD_SPI1_RX SERCOM_RX_PAD_3 + +static const uint8_t SS1 = 17; +static const uint8_t MOSI1 = PIN_SPI1_MOSI ; +static const uint8_t MISO1 = PIN_SPI1_MISO ; +static const uint8_t SCK1 = PIN_SPI1_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (4u) +#define PIN_WIRE_SCL (5u) +#define PERIPH_WIRE sercom1 +#define WIRE_IT_HANDLER SERCOM1_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (18ul) +#define PIN_USB_DM (19ul) +#define PIN_USB_DP (20ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 1 + +#define I2S_DEVICE 0 +#define I2S_CLOCK_GENERATOR 3 +#define PIN_I2S_SD (A7) +#define PIN_I2S_SCK (MOSI) +#define PIN_I2S_FS (SCK) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/rotarytrinkey_m0/debug_scripts/variant.gdb b/variants/rotarytrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/rotarytrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/rotarytrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/rotarytrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/rotarytrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/rotarytrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/rotarytrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/rotarytrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/rotarytrinkey_m0/openocd_scripts/rotarytrinkey_m0.cfg b/variants/rotarytrinkey_m0/openocd_scripts/rotarytrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/rotarytrinkey_m0/openocd_scripts/rotarytrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/rotarytrinkey_m0/pins_arduino.h b/variants/rotarytrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/rotarytrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/rotarytrinkey_m0/variant.cpp b/variants/rotarytrinkey_m0/variant.cpp new file mode 100644 index 000000000..e3c824ff5 --- /dev/null +++ b/variants/rotarytrinkey_m0/variant.cpp @@ -0,0 +1,68 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // NeoPixel + { PORTA, 1, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, + + // Encoder pin 1 + { PORTA, 0, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, + + // Encoder pin 2 + { PORTA, 4, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, + + // Encoder switch + { PORTA, 27, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, + + // Touch pad + { PORTA, 6, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, + + + // USB pins + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // Fake DAC pin just so we can compile stuff + { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; + +/* + * Serial interfaces + + +// Serial1 +#define PIN_SERIAL1_TX (6ul) +#define PIN_SERIAL1_RX (7ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_2) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) + */ diff --git a/variants/rotarytrinkey_m0/variant.h b/variants/rotarytrinkey_m0/variant.h new file mode 100644 index 000000000..a6442918e --- /dev/null +++ b/variants/rotarytrinkey_m0/variant.h @@ -0,0 +1,197 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ROTARYTRINKEY_ZERO_ +#define _VARIANT_ROTARYTRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (9u) +#define NUM_DIGITAL_PINS (5u) +#define NUM_ANALOG_INPUTS (2u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (0u) +#define NUM_NEOPIXEL (1u) + +// ENCODER +#define PIN_ENCODER_A 1 +#define PIN_ENCODER_B 2 +#define PIN_ENCODER_SWITCH 3 + +#define PIN_TOUCH 4 + +/* + * Analog pins + */ +#define PIN_A0 (8ul) +#define PIN_A1 (2) +#define PIN_A2 (4) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + * Fake SPI Interface just so we can compile + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO PIN_A0 +#define PIN_SPI_MOSI PIN_A0 +#define PIN_SPI_SCK PIN_A0 +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A0; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 0 + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (5ul) +#define PIN_USB_DM (6ul) +#define PIN_USB_DP (7ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_TX (2ul) // D2 / PA04 / SERCOM 0.0 +#define PIN_SERIAL1_RX (4ul) // D2 / PA06 / SERCOM 0.2 +#define PAD_SERIAL1_TX (UART_TX_PAD_0) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_2) + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/sht4xtrinkey_m0/debug_scripts/variant.gdb b/variants/sht4xtrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/sht4xtrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/sht4xtrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/sht4xtrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/sht4xtrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/sht4xtrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/sht4xtrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/sht4xtrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/sht4xtrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg b/variants/sht4xtrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/sht4xtrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/sht4xtrinkey_m0/pins_arduino.h b/variants/sht4xtrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/sht4xtrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/sht4xtrinkey_m0/variant.cpp b/variants/sht4xtrinkey_m0/variant.cpp new file mode 100644 index 000000000..7d25cd281 --- /dev/null +++ b/variants/sht4xtrinkey_m0/variant.cpp @@ -0,0 +1,52 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // Fake DAC A0 pin just so we can compile stuff + { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC + + // touch / A1 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + + // NeoPixel / D2 + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // I2C SDA D3 & SCL D4 + { PORTA, 4, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // D4 / SDA / PWM + { PORTA, 5, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D5 / SCL / PWM + + // USB pins D5, D6, D7 + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; diff --git a/variants/sht4xtrinkey_m0/variant.h b/variants/sht4xtrinkey_m0/variant.h new file mode 100644 index 000000000..2a3a0ee9b --- /dev/null +++ b/variants/sht4xtrinkey_m0/variant.h @@ -0,0 +1,188 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_SHT4XTRINKEY_ZERO_ +#define _VARIANT_SHT4XTRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (10u) +#define NUM_DIGITAL_PINS (6u) +#define NUM_ANALOG_INPUTS (2u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (2u) +#define NUM_NEOPIXEL (1u) + +// TOUCH PINS +#define PIN_TOUCH 1 + +/* + * Analog pins + */ +#define PIN_A0 (0ul) +#define PIN_A1 (1) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + * Fake SPI Interface just so we can compile + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO PIN_A0 +#define PIN_SPI_MOSI PIN_A0 +#define PIN_SPI_SCK PIN_A0 +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A0; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (3u) +#define PIN_WIRE_SCL (4u) +#define PERIPH_WIRE sercom0 +#define WIRE_IT_HANDLER SERCOM0_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (5ul) +#define PIN_USB_DM (6ul) +#define PIN_USB_DP (7ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/slidetrinkey_m0/debug_scripts/variant.gdb b/variants/slidetrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/slidetrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/slidetrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/slidetrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/slidetrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/slidetrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/slidetrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/slidetrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/slidetrinkey_m0/openocd_scripts/slidetrinkey_m0.cfg b/variants/slidetrinkey_m0/openocd_scripts/slidetrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/slidetrinkey_m0/openocd_scripts/slidetrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/slidetrinkey_m0/pins_arduino.h b/variants/slidetrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/slidetrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/slidetrinkey_m0/variant.cpp b/variants/slidetrinkey_m0/variant.cpp new file mode 100644 index 000000000..88a348db7 --- /dev/null +++ b/variants/slidetrinkey_m0/variant.cpp @@ -0,0 +1,48 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // Potentiometer + { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, + + // Touch pad + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, + + // NeoPixel + { PORTA, 4, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, + + // USB pins + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; diff --git a/variants/slidetrinkey_m0/variant.h b/variants/slidetrinkey_m0/variant.h new file mode 100644 index 000000000..65d2e75e8 --- /dev/null +++ b/variants/slidetrinkey_m0/variant.h @@ -0,0 +1,188 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_SLIDETRINKEY_ZERO_ +#define _VARIANT_SLIDETRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (6u) +#define NUM_DIGITAL_PINS (3u) +#define NUM_ANALOG_INPUTS (3u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (2u) +#define NUM_NEOPIXEL (2u) + +// POT +#define PIN_POTENTIOMETER (0u) +#define PIN_TOUCH (1u) + +/* + * Analog pins + */ +#define PIN_A0 (0ul) +#define PIN_A1 (1ul) +#define PIN_A2 (2ul) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + * Fake SPI Interface just so we can compile + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO PIN_A0 +#define PIN_SPI_MOSI PIN_A0 +#define PIN_SPI_SCK PIN_A0 +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_0 + +static const uint8_t SS = PIN_A0; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 0 + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (3ul) +#define PIN_USB_DM (4ul) +#define PIN_USB_DP (5ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +/* + * Serial interfaces + */ + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/thumbsticktrinkey_m0/debug_scripts/variant.gdb b/variants/thumbsticktrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/thumbsticktrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/thumbsticktrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/thumbsticktrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/thumbsticktrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/thumbsticktrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/thumbsticktrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/thumbsticktrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/thumbsticktrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg b/variants/thumbsticktrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/thumbsticktrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/thumbsticktrinkey_m0/pins_arduino.h b/variants/thumbsticktrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/thumbsticktrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/thumbsticktrinkey_m0/variant.cpp b/variants/thumbsticktrinkey_m0/variant.cpp new file mode 100644 index 000000000..91bfef826 --- /dev/null +++ b/variants/thumbsticktrinkey_m0/variant.cpp @@ -0,0 +1,52 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // X (D0) + { PORTA, 9, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel17, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + // Y (D1) + { PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel19, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + + // Button 1 (D2) + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, + // Button 2 (D3) + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, + + // NeoPixel (D4) + { PORTA, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // TCC1/WO[0] + + // USB pins D5, D6, D7 + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; diff --git a/variants/thumbsticktrinkey_m0/variant.h b/variants/thumbsticktrinkey_m0/variant.h new file mode 100644 index 000000000..e996a8886 --- /dev/null +++ b/variants/thumbsticktrinkey_m0/variant.h @@ -0,0 +1,171 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_THUMBSTICKTRINKEY_ZERO_ +#define _VARIANT_THUMBSTICKTRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (10u) +#define NUM_DIGITAL_PINS (7u) +#define NUM_ANALOG_INPUTS (6u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (4u) +#define NUM_NEOPIXEL (1u) + +#define PIN_JOY_X (0ul) +#define PIN_JOY_Y (1ul) +#define PIN_BUTTON1 (2ul) +#define PIN_BUTTON2 (3ul) + +/* + * Analog pins + */ +#define PIN_A0 (0ul) +#define PIN_A1 (1ul) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 0 + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 0 + + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (5ul) +#define PIN_USB_DM (6ul) +#define PIN_USB_DP (7ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/trellis_m4/linker_scripts/gcc/flash_with_bootloader.ld b/variants/trellis_m4/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..5fe575a0d --- /dev/null +++ b/variants/trellis_m4/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x80000-0x4000 /* First 16KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x4000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/trellis_m4/linker_scripts/gcc/flash_without_bootloader.ld b/variants/trellis_m4/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0123a0a23 --- /dev/null +++ b/variants/trellis_m4/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,215 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x80000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x30000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + . = ALIGN(4); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/trellis_m4/pins_arduino.h b/variants/trellis_m4/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/trellis_m4/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/trellis_m4/variant.cpp b/variants/trellis_m4/variant.cpp new file mode 100644 index 000000000..cbe7be633 --- /dev/null +++ b/variants/trellis_m4/variant.cpp @@ -0,0 +1,130 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - SERCOM/UART (Serial1) + { PORTA, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // SERCOM 2.0 + { PORTA, 13, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_13 }, // SERCOM 2.1 + + // 2..9 - columns + { PORTA, 14, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // D2 COL0 + { PORTA, 15, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, // D3 COL1 + { PORTA, 16, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // D4 COL2 + { PORTA, 17, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // D5 COL3 + { PORTA, 20, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // D6 COL4 + { PORTA, 21, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D7 COL5 + { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // D8 COL6 + { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // D9 COL7 + + // NeoPixel #10 + { PORTA, 27, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // D10 + + // 11 & 12 - dotstar clock + data + { PORTA, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // MOSI SERCOM 1.0 + { PORTA, 1, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // SCK SERCOM 1.1 + + // 13 (LED) + { PORTB, 02, PIO_DIGITAL, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // unconnected + + // 14..17 - rows + { PORTA, 18, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTA, 19, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, + { PORTB, 22, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, + { PORTB, 23, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // MISO SERCOM 1.3 + + // 18 - IRQ + { PORTA, 4, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + + // 19..20 - USB + // -------------------- + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // USB/DP + + // 21..22 I2C pins (SDA/SCL) or Serial1 Pins + // ---------------------- + { PORTB, 8, PIO_SERCOM_ALT, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // SERCOM 4.0 + { PORTB, 9, PIO_SERCOM_ALT, PIN_ATTR_ANALOG_ALT, ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // SERCOM 4.1 + + // ---------------------- + // 23 - 28 QSPI (SCK, CS, IO0, IO1, IO2, IO3) + { PORTB, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTB, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + { PORTA, 8, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NMI }, + { PORTA, 9, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, + { PORTA, 10, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, + { PORTA, 11, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, + + // 29..34 - Analog pins + // -------------------- + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A0 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // A1 + { PORTA, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // Amp'd Mic + { PORTA, 7, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel7, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // Raw Mic + { PORTB, 8, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel2, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8 }, // SDA + { PORTB, 9, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel3, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 }, // SCL + + // 35 - SWCLK + { PORTA, 30, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + // 36 - SWDIO + { PORTA, 31, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_15 }, + + // Unused + { PORTB, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel14, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + { PORTB, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel15, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, + + // AREF tied to 3.3V + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // DAC/VREFP +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC0, TC1, TC2, TC3 } ; +const uint32_t GCLK_CLKCTRL_IDs[TCC_INST_NUM+TC_INST_NUM] = { TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID, TC0_GCLK_ID, TC1_GCLK_ID, TC2_GCLK_ID, TC3_GCLK_ID } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +Uart Serial1( &sercom4, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM4_0_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_1_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_2_Handler() +{ + Serial1.IrqHandler(); +} +void SERCOM4_3_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/trellis_m4/variant.h b/variants/trellis_m4/variant.h new file mode 100644 index 000000000..46e66b754 --- /dev/null +++ b/variants/trellis_m4/variant.h @@ -0,0 +1,261 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_TRELLIS_M4_ +#define _VARIANT_TRELLIS_M4_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +#define VARIANT_GCLK0_FREQ (F_CPU) +#define VARIANT_GCLK1_FREQ (48000000UL) +#define VARIANT_GCLK2_FREQ (100000000UL) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (32u) +#define NUM_DIGITAL_PINS (30u) +#define NUM_ANALOG_INPUTS (3u) +#define NUM_ANALOG_OUTPUTS (2u) +#define analogInputToDigitalPin(p) ((p < NUM_ANALOG_INPUTS) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED PIN_LED_13 +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (29ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_A5 (PIN_A0 + 5) + +#define PIN_DAC0 PIN_A0 +#define PIN_DAC1 PIN_A1 +#define PIN_MIC PIN_A2 +#define PIN_MIC_RAW PIN_A3 +#define PIN_LINE_LEFT (21ul) +#define PIN_LINE_RIGHT (22ul) + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; + +static const uint8_t DAC0 = PIN_DAC0; +static const uint8_t DAC1 = PIN_DAC1; + +static const uint8_t MIC_RAW = PIN_MIC_RAW; +static const uint8_t MIC = PIN_MIC; +static const uint8_t LINE_LEFT = PIN_LINE_LEFT; +static const uint8_t LINE_RIGHT = PIN_LINE_RIGHT; + +#define ADC_RESOLUTION 12 + +/* + * Serial interfaces + */ + +// Serial1 +#define PIN_SERIAL1_RX (22ul) +#define PIN_SERIAL1_TX (21ul) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_1) +#define PAD_SERIAL1_TX (UART_TX_PAD_0) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_SCK (9u) // COL7 +#define PIN_SPI_MOSI (8u) // COL6 +#define PIN_SPI_MISO (7u) // COL5 +#define PERIPH_SPI sercom3 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_3 + +static const uint8_t SS = PIN_A2 ; +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 2 + +#define PIN_WIRE_SDA (21u) +#define PIN_WIRE_SCL (22u) +#define PERIPH_WIRE sercom4 +#define WIRE_IT_HANDLER SERCOM4_Handler + +// Sercom interrupt handlers for I2C slave not set; they are used by Serial1 +// #define WIRE_IT_HANDLER_0 SERCOM4_0_Handler +// #define WIRE_IT_HANDLER_1 SERCOM4_1_Handler +// #define WIRE_IT_HANDLER_2 SERCOM4_2_Handler +// #define WIRE_IT_HANDLER_3 SERCOM4_3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + + +#define PIN_WIRE1_SDA (0u) +#define PIN_WIRE1_SCL (1u) +#define PERIPH_WIRE1 sercom2 +#define WIRE1_IT_HANDLER SERCOM2_Handler +#define WIRE1_IT_HANDLER_0 SERCOM2_0_Handler +#define WIRE1_IT_HANDLER_1 SERCOM2_1_Handler +#define WIRE1_IT_HANDLER_2 SERCOM2_2_Handler +#define WIRE1_IT_HANDLER_3 SERCOM2_3_Handler + +static const uint8_t SDA1 = PIN_WIRE_SDA; +static const uint8_t SCL1 = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (13ul) +#define PIN_USB_DM (19ul) +#define PIN_USB_DP (20ul) + +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + +#define I2S_DEVICE 0 +// no I2S on G19! + +// On-board QSPI Flash +#define EXTERNAL_FLASH_DEVICES GD25Q64C +#define EXTERNAL_FLASH_USE_QSPI + +//QSPI Pins +#define PIN_QSPI_SCK (23u) +#define PIN_QSPI_CS (24u) +#define PIN_QSPI_IO0 (25u) +#define PIN_QSPI_IO1 (26u) +#define PIN_QSPI_IO2 (27u) +#define PIN_QSPI_IO3 (28u) + +#if !defined(VARIANT_QSPI_BAUD_DEFAULT) + // TODO: meaningful value for this + #define VARIANT_QSPI_BAUD_DEFAULT 5000000 +#endif + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + + +#endif /* _VARIANT_TRELLIS_M4_ */ + diff --git a/variants/trinket_m0/debug_scripts/variant.gdb b/variants/trinket_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/trinket_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/trinket_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/trinket_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..4475f9511 --- /dev/null +++ b/variants/trinket_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,211 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/trinket_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/trinket_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0162f0774 --- /dev/null +++ b/variants/trinket_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,212 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/trinket_m0/openocd_scripts/trinket_m0.cfg b/variants/trinket_m0/openocd_scripts/trinket_m0.cfg new file mode 100644 index 000000000..f26f25f37 --- /dev/null +++ b/variants/trinket_m0/openocd_scripts/trinket_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Trinket M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/trinket_m0/pins_arduino.h b/variants/trinket_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/trinket_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/trinket_m0/variant.cpp b/variants/trinket_m0/variant.cpp new file mode 100644 index 000000000..5363f8daf --- /dev/null +++ b/variants/trinket_m0/variant.cpp @@ -0,0 +1,103 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // GPIO 0-4 on external pads + // D0, ADC, PWM, IRQ, and I2C SDA on sercom2 - no captouch + { PORTA, 8, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + + // D1, ADC, DAC, IRQ, Captouch and general purpose pin - no timer + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + + // D2, ADC, PWM, IRQ, and I2C SCL on sercom2 - no captouch + { PORTA, 9, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + + // D3, ADC, PWM, IRQ, UART RX, Captouch and general purpose pin + { PORTA, 7, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + + // D4, ADC, PWM, IRQ, UART TX, Captouch and general purpose pin + { PORTA, 6, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + + // D5, same as D0 but on sercom2 (for SPI sercommin') + { PORTA, 8, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + // D6, same as D2 but on sercom2 (for SPI sercommin') + { PORTA, 9, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + + // GPIO 7 & 8 - DotStar internal data/clock + // ---------------------------------------- + { PORTA, 0, PIO_DIGITAL, 0, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // ADC/AIN[4] + { PORTA, 1, PIO_DIGITAL, 0, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, // ADC/AIN[5] + + // GPIO 9, 10, 11 USB Host enable + // ---------------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable - GPIO #5 + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM - GPIO #6 + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP - GPIO #7 + + // GPIO 12 is a placeholder, same as D13 + { PORTA, 10, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // TX: SERCOM0/PAD[2] + + // GPIO 13 (LED) + { PORTA, 10, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // TX: SERCOM0/PAD[2] + + + // Digital 14 - 18, Analog A0-A4 + // A0 same as D1 + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[0] + // A1, same as D2 + { PORTA, 9, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + // A2, same as D0 + { PORTA, 8, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + // A3, same as D3 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + // A4, same as D4 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + + + // GPIO 19 & 20 (SWCLK & SWDIO) + // -------------------------- + { PORTA, 30, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + { PORTA, 31, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + + // Placeholder #21 & 22 for 'txled' and 'rxled' + { PORTA, 14, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, + { PORTA, 15, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; + +Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; + +void SERCOM0_Handler() +{ + Serial1.IrqHandler(); +} + diff --git a/variants/trinket_m0/variant.h b/variants/trinket_m0/variant.h new file mode 100644 index 000000000..12e99e9dc --- /dev/null +++ b/variants/trinket_m0/variant.h @@ -0,0 +1,206 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ARDUINO_ZERO_ +#define _VARIANT_ARDUINO_ZERO_ + +// The definitions here needs a SAMD core >=1.6.6 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10606 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (22u) +#define NUM_DIGITAL_PINS (22u) +#define NUM_ANALOG_INPUTS (5u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) ((p < 5u) ? (p) + PIN_A0 : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (21u) +#define PIN_LED_TXL (22u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 +// DotStar LED +#define INTERNAL_DS_DATA (7u) +#define INTERNAL_DS_CLK (8u) +#define PIN_DOTSTAR_DATA (7u) +#define PIN_DOTSTAR_CLK (8u) +#define PIN_DOTSTAR_CLOCK PIN_DOTSTAR_CLK +#define DOTSTAR_NUM (1u) + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (PIN_A0 + 1) +#define PIN_A2 (PIN_A0 + 2) +#define PIN_A3 (PIN_A0 + 3) +#define PIN_A4 (PIN_A0 + 4) +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t DAC0 = PIN_DAC0; + +#define ADC_RESOLUTION 12 + +/* + * Serial interfaces + */ + +// Serial1 (sercom 0) +#define PIN_SERIAL1_RX (3ul) // PA07 +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) +#define PIN_SERIAL1_TX (4ul) // PA06 +#define PAD_SERIAL1_TX (UART_TX_PAD_2) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 // shared with I2C/UART (can't do both) + +#define PIN_SPI_MISO (6u) // PA09 same as D2 +#define PIN_SPI_MOSI (4u) +#define PIN_SPI_SCK (3u) +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_2_SCK_3 +#define PAD_SPI_RX SERCOM_RX_PAD_1 + +static const uint8_t SS = 5 ; // SERCOM0 last PAD is present on 5 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (0u) +#define PIN_WIRE_SCL (2u) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (9ul) +#define PIN_USB_DM (10ul) +#define PIN_USB_DP (11ul) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/trrstrinkey_m0/debug_scripts/variant.gdb b/variants/trrstrinkey_m0/debug_scripts/variant.gdb new file mode 100644 index 000000000..13ee2a173 --- /dev/null +++ b/variants/trrstrinkey_m0/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/trrstrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld b/variants/trrstrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..357946455 --- /dev/null +++ b/variants/trrstrinkey_m0/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,216 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.sketch_boot)) + + . = ALIGN(0x2000); + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/trrstrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld b/variants/trrstrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..ebeeee37f --- /dev/null +++ b/variants/trrstrinkey_m0/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,214 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + __text_start__ = .; + + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(16); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/trrstrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg b/variants/trrstrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg new file mode 100644 index 000000000..e4c3f81dc --- /dev/null +++ b/variants/trrstrinkey_m0/openocd_scripts/sht4xtrinkey_m0.cfg @@ -0,0 +1,28 @@ +# +# Adafruit ItsyBitsy M0 OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21e18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/trrstrinkey_m0/pins_arduino.h b/variants/trrstrinkey_m0/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/trrstrinkey_m0/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/trrstrinkey_m0/variant.cpp b/variants/trrstrinkey_m0/variant.cpp new file mode 100644 index 000000000..99184204b --- /dev/null +++ b/variants/trrstrinkey_m0/variant.cpp @@ -0,0 +1,64 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#include "variant.h" +#include "Arduino.h" +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // TRRS Tip, D0 / DAC / A0 + { PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, + // TRRS Tip Switch, D1, A1 + { PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, + + // TRRS Ring 1, D2, A2 + { PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, + // TRRS Ring 1 Switch, D3, A3 + { PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, + + // TRRS Ring2, D4, A4 + { PORTA, 4, PIO_ANALOG, PIN_ATTR_DIGITAL, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, + + // TRRS Sleeve, D5, A5 + { PORTA, 5, PIO_ANALOG, PIN_ATTR_DIGITAL, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, + + // Internal NeoPixel / D6 + { PORTA, 1, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, + + // QT SDA D7 + { PORTA, 8, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + + // QT SCL D8 + { PORTA, 9, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + + // USB pins D9, D10, D11 + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; diff --git a/variants/trrstrinkey_m0/variant.h b/variants/trrstrinkey_m0/variant.h new file mode 100644 index 000000000..998d00ddb --- /dev/null +++ b/variants/trrstrinkey_m0/variant.h @@ -0,0 +1,207 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_TRRSTRINKEY_ZERO_ +#define _VARIANT_TRRSTRINKEY_ZERO_ + +// The definitions here needs a SAMD core >=1.6.10 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (10u) +#define NUM_DIGITAL_PINS (7u) +#define NUM_ANALOG_INPUTS (6u) +#define NUM_ANALOG_OUTPUTS (1u) +#define analogInputToDigitalPin(p) (p) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_NEOPIXEL (6u) +#define NUM_NEOPIXEL (1u) + +#define PIN_TIP (0ul) +#define PIN_TIP_SWITCH (1ul) +#define PIN_RING1 (2ul) +#define PIN_RING1_SWITCH (3ul) +#define PIN_RING2 (4ul) +#define PIN_SLEEVE (5ul) + +/* + * Analog pins + */ +#define PIN_A0 (0ul) +#define PIN_A1 (1ul) +#define PIN_A2 (2ul) +#define PIN_A3 (3ul) +#define PIN_A4 (4ul) +#define PIN_A5 (5ul) + +#define PIN_DAC0 PIN_A0 + +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; +static const uint8_t A3 = PIN_A3; +static const uint8_t A4 = PIN_A4; +static const uint8_t A5 = PIN_A5; + +#define ADC_RESOLUTION 12 + + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 1 + +#define PIN_SPI_MISO PIN_RING1 +#define PIN_SPI_MOSI PIN_RING2 +#define PIN_SPI_SCK PIN_SLEEVE +#define PERIPH_SPI sercom0 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = PIN_TIP; +static const uint8_t MOSI = PIN_SPI_MOSI; +static const uint8_t MISO = PIN_SPI_MISO; +static const uint8_t SCK = PIN_SPI_SCK; + +/* + * Wire Interfaces, fake just for compilation + */ +#define WIRE_INTERFACES_COUNT 2 + +// QT Port +#define PIN_WIRE_SDA (7ul) +#define PIN_WIRE_SCL (8ul) +#define PERIPH_WIRE sercom2 +#define WIRE_IT_HANDLER SERCOM2_Handler + +// second, sekret I2C on the headphone jack +#define PIN_WIRE1_SDA PIN_RING2 +#define PIN_WIRE1_SCL PIN_SLEEVE +#define PERIPH_WIRE1 sercom0 +#define WIRE1_IT_HANDLER SERCOM0_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (9ul) +#define PIN_USB_DM (10ul) +#define PIN_USB_DP (11ul) +/* + * I2S Interfaces + */ +#define I2S_INTERFACES_COUNT 0 + + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + diff --git a/variants/zero_radio/debug_scripts/variant.gdb b/variants/zero_radio/debug_scripts/variant.gdb new file mode 100644 index 000000000..3c37ffde2 --- /dev/null +++ b/variants/zero_radio/debug_scripts/variant.gdb @@ -0,0 +1,31 @@ +# +# Arduino Zero OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# Define 'reset' command +define reset + +info reg + +break main + +# End of 'reset' command +end + +target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21g18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log" diff --git a/variants/zero_radio/linker_scripts/gcc/flash_with_bootloader.ld b/variants/zero_radio/linker_scripts/gcc/flash_with_bootloader.ld new file mode 100644 index 000000000..4475f9511 --- /dev/null +++ b/variants/zero_radio/linker_scripts/gcc/flash_with_bootloader.ld @@ -0,0 +1,211 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/zero_radio/linker_scripts/gcc/flash_without_bootloader.ld b/variants/zero_radio/linker_scripts/gcc/flash_without_bootloader.ld new file mode 100644 index 000000000..0162f0774 --- /dev/null +++ b/variants/zero_radio/linker_scripts/gcc/flash_without_bootloader.ld @@ -0,0 +1,212 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +/* Linker script to configure memory regions. + * Need modifying for a specific board. + * FLASH.ORIGIN: starting address of flash + * FLASH.LENGTH: length of flash + * RAM.ORIGIN: starting address of RAM bank 0 + * RAM.LENGTH: length of RAM bank 0 + */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __exidx_start + * __exidx_end + * __copy_table_start__ + * __copy_table_end__ + * __zero_table_start__ + * __zero_table_end__ + * __etext + * __data_start__ + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __data_end__ + * __bss_start__ + * __bss_end__ + * __end__ + * end + * __HeapLimit + * __StackLimit + * __StackTop + * __stack + * __ram_end__ + */ +ENTRY(Reset_Handler) + +SECTIONS +{ + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* To copy multiple ROM to RAM sections, + * uncomment .copy.table section and, + * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */ + /* + .copy.table : + { + . = ALIGN(4); + __copy_table_start__ = .; + LONG (__etext) + LONG (__data_start__) + LONG (__data_end__ - __data_start__) + LONG (__etext2) + LONG (__data2_start__) + LONG (__data2_end__ - __data2_start__) + __copy_table_end__ = .; + } > FLASH + */ + + /* To clear multiple BSS sections, + * uncomment .zero.table section and, + * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */ + /* + .zero.table : + { + . = ALIGN(4); + __zero_table_start__ = .; + LONG (__bss_start__) + LONG (__bss_end__ - __bss_start__) + LONG (__bss2_start__) + LONG (__bss2_end__ - __bss2_start__) + __zero_table_end__ = .; + } > FLASH + */ + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + PROVIDE(end = .); + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM) ; + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + __ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/variants/zero_radio/openocd_scripts/zero_radio.cfg b/variants/zero_radio/openocd_scripts/zero_radio.cfg new file mode 100644 index 000000000..6960702ab --- /dev/null +++ b/variants/zero_radio/openocd_scripts/zero_radio.cfg @@ -0,0 +1,28 @@ +# +# Adafruit Feather M0 Radio OpenOCD script. +# +# Copyright (c) 2014-2015 Arduino LLC. All right reserved. +# +# 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 +# + +# chip name +set CHIPNAME at91samd21g18 +set ENDIAN little + +# choose a port here +set telnet_port 0 + +source [find target/at91samdXX.cfg] diff --git a/variants/zero_radio/pins_arduino.h b/variants/zero_radio/pins_arduino.h new file mode 100644 index 000000000..db0e40c3d --- /dev/null +++ b/variants/zero_radio/pins_arduino.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +// API compatibility +#include "variant.h" + diff --git a/variants/zero_radio/variant.cpp b/variants/zero_radio/variant.cpp new file mode 100644 index 000000000..8e3150122 --- /dev/null +++ b/variants/zero_radio/variant.cpp @@ -0,0 +1,225 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ +/* + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * + Pin number + ZERO Board pin | PIN | Label/Name | Comments (* is for default peripheral in use) + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | Digital Low | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 0 | 0 | PA11 | AT86RF233_DIG4 | EIC/EXTINT[11] ADC/AIN[19] PTC/X[3] SERCOM0/PAD[3] SERCOM2/PAD[3] TCC0/WO[3] TCC1/WO[1] + * | 1 | 1 | PA10 | AT86RF233_DIG3 | EIC/EXTINT[10] ADC/AIN[18] PTC/X[2] SERCOM0/PAD[2] TCC0/WO[2] TCC1/WO[0] + * | 2 | 2 | PA14 | MISO | EIC/EXTINT[14] SERCOM2/PAD[2] SERCOM4/PAD[2] TC3/WO[0] TCC0/WO[4] + * | 3 | ~3 | PA09 | | EIC/EXTINT[9] ADC/AIN[17] PTC/X[1] SERCOM0/PAD[1] SERCOM2/PAD[1] *TCC0/WO[1] TCC1/WO[3] + * | 4 | ~4 | PA08 | | EIC/NMI ADC/AIN[16] PTC/X[0] SERCOM0/PAD[0] SERCOM2/PAD[0] *TCC0/WO[0] TCC1/WO[2] + * | 5 | ~5 | PA15 | | EIC/EXTINT[15] SERCOM2/PAD[3] SERCOM4/PAD[3] *TC3/WO[1] TCC0/WO[5] + * | 6 | ~6 | PA20 | | EIC/EXTINT[4] PTC/X[8] SERCOM5/PAD[2] SERCOM3/PAD[2] *TCC0/WO[6] + * | 7 | 7 | PA21 | | EIC/EXTINT[5] PTC/X[9] SERCOM5/PAD[3] SERCOM3/PAD[3] TCC0/WO[7] + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | Digital High | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 8 | ~8 | PA06 | | EIC/EXTINT[6] ADC/AIN[6] AC/AIN[2] PTC/Y[4] SERCOM0/PAD[2] *TCC1/WO[0] + * | 9 | ~9 | PA07 | | EIC/EXTINT[7] ADC/AIN[7] AC/AIN[3] PTC/Y[5] SERCOM0/PAD[3] *TCC1/WO[1] + * | 10 | ~10 | PA18 | | EIC/EXTINT[2] PTC/X[6] +SERCOM1/PAD[2] SERCOM3/PAD[2] *TC3/WO[0] TCC0/WO[2] + * | 11 | ~11 | PA16 | | EIC/EXTINT[0] PTC/X[4] +SERCOM1/PAD[0] SERCOM3/PAD[0] *TCC2/WO[0] TCC0/WO[6] + * | 12 | ~12 | PA19 | | EIC/EXTINT[3] PTC/X[7] +SERCOM1/PAD[3] SERCOM3/PAD[3] TC3/WO[1] *TCC0/WO[3] + * | 13 | ~13 | PA17 | LED | EIC/EXTINT[1] PTC/X[5] +SERCOM1/PAD[1] SERCOM3/PAD[1] *TCC2/WO[1] TCC0/WO[7] + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | Analog Connector | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 14 | A0 | PA02 | A0 | EIC/EXTINT[2] *ADC/AIN[0] DAC/VOUT PTC/Y[0] + * | 15 | A1 | PB08 | A1 | EIC/EXTINT[8] *ADC/AIN[2] PTC/Y[14] SERCOM4/PAD[0] TC4/WO[0] + * | 16 | A2 | PB09 | A2 | EIC/EXTINT[9] *ADC/AIN[3] PTC/Y[15] SERCOM4/PAD[1] TC4/WO[1] + * | 17 | A3 | PA04 | A3 | EIC/EXTINT[4] *ADC/AIN[4] AC/AIN[0] PTC/Y[2] SERCOM0/PAD[0] TCC0/WO[0] + * | 18 | A4 | PA05 | A4 | EIC/EXTINT[5] *ADC/AIN[5] AC/AIN[1] PTC/Y[5] SERCOM0/PAD[1] TCC0/WO[1] + * | 19 | A5 | PB02 | A5 | EIC/EXTINT[2] *ADC/AIN[10] PTC/Y[8] SERCOM5/PAD[0] + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | Wire | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 20 | SDA | PA22 | SDA | EIC/EXTINT[6] PTC/X[10] *SERCOM3/PAD[0] SERCOM5/PAD[0] TC4/WO[0] TCC0/WO[4] + * | 21 | SCL | PA23 | SCL | EIC/EXTINT[7] PTC/X[11] *SERCOM3/PAD[1] SERCOM5/PAD[1] TC4/WO[1] TCC0/WO[5] + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | |SPI (Legacy ICSP) | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 22 | 1 | PA12 | MISO | EIC/EXTINT[12] SERCOM2/PAD[0] *SERCOM4/PAD[0] TCC2/WO[0] TCC0/WO[6] + * | | 2 | | 5V0 | + * | 23 | 4 | PB10 | MOSI | EIC/EXTINT[10] *SERCOM4/PAD[2] TC5/WO[0] TCC0/WO[4] + * | 24 | 3 | PB11 | SCK | EIC/EXTINT[11] *SERCOM4/PAD[3] TC5/WO[1] TCC0/WO[5] + * | | 5 | | RESET | + * | | 6 | | GND | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | LEDs | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 25 | | PB03 | RX | + * | 26 | | PA27 | TX | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | USB | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 27 | | PA28 | USB_HOST_ENABLE | EIC/EXTINT[8] + * | 28 | | PA24 | USB_NEGATIVE | *USB/DM + * | 29 | | PA25 | USB_POSITIVE | *USB/DP + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | EDBG | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 30 | | PB22 | EDBG_UART TX | *SERCOM5/PAD[2] + * | 31 | | PB23 | EDBG_UART RX | *SERCOM5/PAD[3] + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 32 | | PA22 | EDBG_SDA | Pin 20 (SDA) + * | 33 | | PA23 | EDBG_SCL | Pin 21 (SCL) + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 34 | | PA19 | EDBG_MISO | EIC/EXTINT[3] *SERCOM1/PAD[3] SERCOM3/PAD[3] TC3/WO[1] TCC0/WO[3] + * | 35 | | PA16 | EDBG_MOSI | EIC/EXTINT[0] *SERCOM1/PAD[0] SERCOM3/PAD[0] TCC2/WO[0] TCC0/WO[6] + * | 36 | | PA18 | EDBG_SS | EIC/EXTINT[2] *SERCOM1/PAD[2] SERCOM3/PAD[2] TC3/WO[0] TCC0/WO[2] + * | 37 | | PA17 | EDBG_SCK | EIC/EXTINT[1] *SERCOM1/PAD[1] SERCOM3/PAD[1] TCC2/WO[1] TCC0/WO[7] + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | 38 | ATN | PA13 | EDBG_GPIO0 | EIC/EXTINT[13] SERCOM2/PAD[1] SERCOM4/PAD[1] *TCC2/WO[1] TCC0/WO[7] + * | 39 | | PA21 | EDBG_GPIO1 | Pin 7 + * | 40 | | PA06 | EDBG_GPIO2 | Pin 8 + * | 41 | | PA07 | EDBG_GPIO3 | Pin 9 + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | GND | | | + * | 42 | AREF | PA03 | | EIC/EXTINT[3] *[ADC|DAC]/VREFA ADC/AIN[1] PTC/Y[1] + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | |32.768KHz Crystal | | | + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + * | | | PA00 | XIN32 | EIC/EXTINT[0] SERCOM1/PAD[0] TCC2/WO[0] + * | | | PA01 | XOUT32 | EIC/EXTINT[1] SERCOM1/PAD[1] TCC2/WO[1] + * +------------+------------------+--------+-----------------+-------------------------------------------------------------------------------------------------------- + */ + + +#include "variant.h" + +/* + * Pins descriptions + */ +const PinDescription g_APinDescription[]= +{ + // 0..13 - Digital pins + // ---------------------- + // 0/1 - AT86RF233 internal pins + { PORTA, 11, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // AT86RF233 DIG4 + { PORTA, 10, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // AT86RF233 DIG3 + + // 2..12 + // Digital Low + { PORTA, 14, PIO_SERCOM, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_14 }, // SPI MISO SERCOM 2.2 + { PORTA, 9, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1] + { PORTA, 8, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0] + { PORTA, 15, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH1, TC3_CH1, EXTERNAL_INT_15 }, // TC3/WO[1] + { PORTA, 20, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_4 }, // used for AT86RF SLP_TR + { }, // PA21 not available on SAMR + + // Digital High + { PORTA, 6, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // TCC1/WO[0] + { PORTA, 7, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1] + { PORTA, 18, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM3_CH0, TC3_CH0, EXTERNAL_INT_2 }, // TC3/WO[0] + { PORTA, 16, PIO_TIMER, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // TCC2/WO[0] + { PORTA, 19, PIO_TIMER_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH3, TCC0_CH3, EXTERNAL_INT_3 }, // TCC0/WO[3] + + // 13 (LED) + { PORTA, 17, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM2_CH1, NOT_ON_TIMER, EXTERNAL_INT_1 }, // TCC2/WO[1] + + // 14..19 - Analog pins + // -------------------- + { }, // PA02 not available on SAMR + { }, // PB08 not available on SAMR + { }, // PB09 not available on SAMR + { PORTA, 4, PIO_ANALOG, 0, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // ADC/AIN[4] + { PORTA, 5, PIO_ANALOG, 0, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // ADC/AIN[5] + { PORTB, 2, PIO_ANALOG, 0, ADC_Channel10, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // ADC/AIN[10] + + // 20..21 I2C pins (SDA/SCL and also EDBG:SDA/SCL) + // ---------------------- + { PORTA, 22, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_7 }, // SCL: SERCOM3/PAD[1] + + // 22..24 - SPI pins (ICSP:MISO,SCK,MOSI) + // ---------------------- + { PORTA, 12, PIO_SERCOM, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MOSI: SERCOM2/PAD[0] + { }, // PB10 Not available + { }, // PB11 Not available + + // 25..26 - IO & TX LED (PB03/PA27) + // -------------------- + { PORTB, 3, PIO_ANALOG, 0, ADC_Channel11, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as analog11 + { PORTA, 27, PIO_OUTPUT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // used as output only + + // 27..29 - USB + // -------------------- + { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable + { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM + { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP + + // 30..41 - Serial1 UART + // ---------------------- + // 30/31 - Serial1 UART + { PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // TX: SERCOM5/PAD[2] + { PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // RX: SERCOM5/PAD[3] + + // 32/33 I2C (SDA/SCL and also EDBG:SDA/SCL) + { PORTA, 22, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SDA: SERCOM3/PAD[0] + { PORTA, 23, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCL: SERCOM3/PAD[1] + + // 34..37 - EDBG/SPI + { PORTA, 19, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MISO: SERCOM1/PAD[3] + { PORTA, 16, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // MOSI: SERCOM1/PAD[0] + { PORTA, 18, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SS: SERCOM1/PAD[2] + { PORTA, 17, PIO_SERCOM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // SCK: SERCOM1/PAD[1] + + // 38..41 - EDBG/Digital + { PORTA, 13, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM0_CH5, NOT_ON_TIMER, EXTERNAL_INT_13 }, // SCK: SERCOM2.1 + { }, // PA21 Not available + { PORTA, 6, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH0, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 8 + { PORTA, 7, PIO_PWM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), No_ADC_Channel, PWM1_CH1, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // Pin 9 + + // 42 (AREF) + { }, // DAC/VREFP + + // ---------------------- + // 43 - Alternate use of A0 (DAC output) + { }, // DAC/VOUT + + + // ----- Special SAMR pins! ------ + { PORTB, 15, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #44 PB15 == AT86_RESETN + { PORTC, 16, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #45 PC16 == AT86_CLKM + { PORTC, 18, PIO_TIMER_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #46 PC18 == AT86_SCLK sercom4.3 + { PORTC, 19, PIO_TIMER_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #47 PC19 == AT86_MISO sercom4.0 + { PORTB, 30, PIO_TIMER_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #48 PB30 == AT86_MOSI sercom4.2 + { PORTB, 31, PIO_TIMER_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // #49 PB31 == AT86_SEL sercom4.1 + { PORTB, 00, PIO_TIMER, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 }, // #50 PB00 = AT86_IRQ +} ; + +const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ; + +// Multi-serial objects instantiation +SERCOM sercom0( SERCOM0 ) ; +SERCOM sercom1( SERCOM1 ) ; +SERCOM sercom2( SERCOM2 ) ; +SERCOM sercom3( SERCOM3 ) ; +SERCOM sercom4( SERCOM4 ) ; +SERCOM sercom5( SERCOM5 ) ; + +// We'll use sercom5 for Serial1 hardware serial since pins 0 and 1 are not external +Uart Serial1( &sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ; +void SERCOM5_Handler() +{ + Serial1.IrqHandler(); +} diff --git a/variants/zero_radio/variant.h b/variants/zero_radio/variant.h new file mode 100644 index 000000000..dfc5b93d7 --- /dev/null +++ b/variants/zero_radio/variant.h @@ -0,0 +1,242 @@ +/* + Copyright (c) 2014-2015 Arduino LLC. All right reserved. + + 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 +*/ + +#ifndef _VARIANT_ARDUINO_ZERO_ +#define _VARIANT_ARDUINO_ZERO_ + +// The definitions here needs a SAMD core >=1.6.6 +#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10606 + +/*---------------------------------------------------------------------------- + * Definitions + *----------------------------------------------------------------------------*/ + +/** Frequency of the board main oscillator */ +#define VARIANT_MAINOSC (32768ul) + +/** Master clock frequency */ +#define VARIANT_MCK (F_CPU) + +/*---------------------------------------------------------------------------- + * Headers + *----------------------------------------------------------------------------*/ + +#include "WVariant.h" + +#ifdef __cplusplus +#include "SERCOM.h" +#include "Uart.h" +#endif // __cplusplus + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + +/*---------------------------------------------------------------------------- + * Pins + *----------------------------------------------------------------------------*/ + +// Number of pins defined in PinDescription array +#define PINS_COUNT (51u) +#define NUM_DIGITAL_PINS (51u) + +#define NUM_ANALOG_INPUTS (8u) +#define NUM_ANALOG_OUTPUTS (0u) +#define analogInputToDigitalPin(p) ((p < 6u) ? (p) + 14u : -1) + +#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) ) +#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin ) +//#define analogInPinToBit(P) ( ) +#define portOutputRegister(port) ( &(port->OUT.reg) ) +#define portInputRegister(port) ( &(port->IN.reg) ) +#define portModeRegister(port) ( &(port->DIR.reg) ) +#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER ) + +/* + * digitalPinToTimer(..) is AVR-specific and is not defined for SAMD + * architecture. If you need to check if a pin supports PWM you must + * use digitalPinHasPWM(..). + * + * https://github.com/arduino/Arduino/issues/1833 + */ +// #define digitalPinToTimer(P) + +// LEDs +#define PIN_LED_13 (13u) +#define PIN_LED_RXL (25u) +#define PIN_LED_TXL (26u) +#define PIN_LED PIN_LED_13 +#define PIN_LED2 PIN_LED_RXL +#define PIN_LED3 PIN_LED_TXL +#define LED_BUILTIN PIN_LED_13 + +/* + * Analog pins + */ +#define PIN_A0 (14ul) +#define PIN_A1 (15ul) +#define PIN_A2 (16ul) +#define PIN_A3 (17ul) +#define PIN_A4 (18ul) +#define PIN_A5 (19ul) +#define PIN_A6 (8ul) +#define PIN_A7 (9ul) +#define PIN_A11 (25ul) +#define PIN_A16 (4ul) +#define PIN_A17 (3ul) + +static const uint8_t A0 = PIN_A0 ; +static const uint8_t A1 = PIN_A1 ; +static const uint8_t A2 = PIN_A2 ; +static const uint8_t A3 = PIN_A3 ; +static const uint8_t A4 = PIN_A4 ; +static const uint8_t A5 = PIN_A5 ; +static const uint8_t A6 = PIN_A6 ; +static const uint8_t A7 = PIN_A7 ; +static const uint8_t A11 = PIN_A11 ; +static const uint8_t A16 = PIN_A16 ; +static const uint8_t A17 = PIN_A17 ; + +#define ADC_RESOLUTION 12 + +// Other pins +#define PIN_ATN (38ul) +static const uint8_t ATN = PIN_ATN; + + +// Other pins +#define PIN_ATRF_RESETN 44 +#define PIN_ATRF_CLKM 45 +#define PIN_ATRF_SLPTR 6 +#define PIN_ATRF_SCLK (46u) +#define PIN_ATRF_MISO (47u) +#define PIN_ATRF_MOSI (48u) +#define PIN_ATRF_SEL (49u) +#define PIN_ATRF_IRQ (50u) + +/* + * Serial interfaces + */ + +// Serial1 on SERCOM5 +#define PIN_SERIAL1_RX (31ul) +#define PIN_SERIAL1_TX (30ul) +#define PAD_SERIAL1_TX (UART_TX_PAD_2) +#define PAD_SERIAL1_RX (SERCOM_RX_PAD_3) + +/* + * SPI Interfaces + */ +#define SPI_INTERFACES_COUNT 2 + + // "external" SPI, used for sensors, displays, available to user +#define PIN_SPI_MISO (2u) +#define PIN_SPI_MOSI (22u) +#define PIN_SPI_SCK (38u) +#define PERIPH_SPI sercom2 +#define PAD_SPI_TX SPI_PAD_0_SCK_1 +#define PAD_SPI_RX SERCOM_RX_PAD_2 + +static const uint8_t SS = PIN_A2 ; // SERCOM4 last PAD is present on A2 but HW SS isn't used. Set here only for reference. +static const uint8_t MOSI = PIN_SPI_MOSI ; +static const uint8_t MISO = PIN_SPI_MISO ; +static const uint8_t SCK = PIN_SPI_SCK ; + + // "internal" SPI, used for AT86RF233 only! +#define PIN_SPI1_MISO (47u) +#define PIN_SPI1_MOSI (48u) +#define PIN_SPI1_SCK (46u) +#define PIN_SPI1_SEL (49u) +#define PERIPH_SPI1 sercom4 +#define PAD_SPI1_TX SPI_PAD_2_SCK_3 +#define PAD_SPI1_RX SERCOM_RX_PAD_0 + +static const uint8_t SS1 = PIN_SPI1_SEL ; +static const uint8_t MOSI1 = PIN_SPI_MOSI ; +static const uint8_t MISO1 = PIN_SPI_MISO ; +static const uint8_t SCK1 = PIN_SPI_SCK ; + +/* + * Wire Interfaces + */ +#define WIRE_INTERFACES_COUNT 1 + +#define PIN_WIRE_SDA (20u) +#define PIN_WIRE_SCL (21u) +#define PERIPH_WIRE sercom3 +#define WIRE_IT_HANDLER SERCOM3_Handler + +static const uint8_t SDA = PIN_WIRE_SDA; +static const uint8_t SCL = PIN_WIRE_SCL; + +/* + * USB + */ +#define PIN_USB_HOST_ENABLE (27ul) +#define PIN_USB_DM (28ul) +#define PIN_USB_DP (29ul) + +#ifdef __cplusplus +} +#endif + +/*---------------------------------------------------------------------------- + * Arduino objects - C++ only + *----------------------------------------------------------------------------*/ + +#ifdef __cplusplus + +/* ========================= + * ===== SERCOM DEFINITION + * ========================= +*/ +extern SERCOM sercom0; +extern SERCOM sercom1; +extern SERCOM sercom2; +extern SERCOM sercom3; +extern SERCOM sercom4; +extern SERCOM sercom5; + +extern Uart Serial1; + +#endif + +// These serial port names are intended to allow libraries and architecture-neutral +// sketches to automatically default to the correct port name for a particular type +// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN, +// the first hardware serial port whose RX/TX pins are not dedicated to another use. +// +// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor +// +// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial +// +// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library +// +// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins. +// +// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX +// pins are NOT connected to anything by default. +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +// Serial has no physical pins broken out, so it's not listed as HARDWARE port +#define SERIAL_PORT_HARDWARE Serial1 +#define SERIAL_PORT_HARDWARE_OPEN Serial1 + +#endif /* _VARIANT_ARDUINO_ZERO_ */ + pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy