├── .github └── workflows │ ├── compile-examples.yml │ ├── compile-muxto.yml │ ├── release.yaml │ └── report-size-deltas.yml ├── .gitignore ├── .gitmodules ├── README.md ├── boards.txt ├── bootloaders ├── atmega4809_uart_bl.hex ├── boot.c └── build.sh ├── cores ├── arduino │ ├── Arduino.h │ ├── CDC.cpp │ ├── CDC.h │ ├── MSC.h │ ├── NANO_compat.cpp │ ├── NANO_compat.h │ ├── Tone.cpp │ ├── UART.cpp │ ├── UART.h │ ├── UART0.cpp │ ├── UART1.cpp │ ├── UART2.cpp │ ├── UART3.cpp │ ├── UART_private.h │ ├── UNO_compat.cpp │ ├── UNO_compat.h │ ├── USBCore.cpp │ ├── USBCore.h │ ├── WInterrupts.cpp │ ├── WMath.cpp │ ├── abi.cpp │ ├── hooks.c │ ├── main.cpp │ ├── new.cpp │ ├── new.h │ ├── wiring.c │ ├── wiring_analog.c │ ├── wiring_digital.c │ ├── wiring_private.h │ ├── wiring_pulse.S │ ├── wiring_pulse.c │ └── wiring_shift.c └── test │ ├── CMakeLists.txt │ ├── README.md │ ├── external │ └── catch │ │ └── v.2.7.0 │ │ └── include │ │ └── catch2 │ │ └── catch.hpp │ ├── include │ └── Arduino.h │ └── src │ └── test_main.cpp ├── drivers ├── atmelinf.cat ├── dpinst-amd64.exe ├── dpinst-x86.exe └── mEDBG_Virtual_Com_Port.inf ├── extras ├── pack.hourlybuild.bash ├── pack.pullrequest.bash ├── pack.release.bash ├── package_index.json.Hourly.template ├── package_index.json.NewTag.template └── package_index.json.PR.template ├── firmwares └── MuxTO │ ├── JICE_io.cpp │ ├── JICE_io.h │ ├── JTAG2.cpp │ ├── JTAG2.h │ ├── MuxTO.bin │ ├── MuxTO.hex │ ├── MuxTO.ino │ ├── NVM.h │ ├── UPDI_hi_lvl.cpp │ ├── UPDI_hi_lvl.h │ ├── UPDI_lo_lvl.cpp │ ├── UPDI_lo_lvl.h │ ├── crc16.cpp │ ├── crc16.h │ ├── lock.h │ ├── sys.cpp │ ├── sys.h │ ├── updi_io.cpp │ ├── updi_io.h │ └── updi_io_soft.cpp ├── fuses └── fuses_4809.bin ├── libraries ├── EEPROM │ ├── README.md │ ├── examples │ │ ├── eeprom_clear │ │ │ └── eeprom_clear.ino │ │ ├── eeprom_crc │ │ │ └── eeprom_crc.ino │ │ ├── eeprom_get │ │ │ └── eeprom_get.ino │ │ ├── eeprom_iteration │ │ │ └── eeprom_iteration.ino │ │ ├── eeprom_put │ │ │ └── eeprom_put.ino │ │ ├── eeprom_read │ │ │ └── eeprom_read.ino │ │ ├── eeprom_update │ │ │ └── eeprom_update.ino │ │ └── eeprom_write │ │ │ └── eeprom_write.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ │ └── EEPROM.h ├── SPI │ ├── examples │ │ ├── BarometricPressureSensor │ │ │ └── BarometricPressureSensor.ino │ │ └── DigitalPotControl │ │ │ └── DigitalPotControl.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ │ ├── SPI.cpp │ │ └── SPI.h ├── SoftwareSerial │ ├── examples │ │ ├── SoftwareSerialExample │ │ │ └── SoftwareSerialExample.ino │ │ └── TwoPortReceive │ │ │ └── TwoPortReceive.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ │ ├── SoftwareSerial.cpp │ │ └── SoftwareSerial.h └── Wire │ ├── examples │ ├── SFRRanger_reader │ │ └── SFRRanger_reader.ino │ ├── digital_potentiometer │ │ └── digital_potentiometer.ino │ ├── master_reader │ │ └── master_reader.ino │ ├── master_writer │ │ └── master_writer.ino │ ├── slave_receiver │ │ └── slave_receiver.ino │ └── slave_sender │ │ └── slave_sender.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ ├── Wire.cpp │ ├── Wire.h │ └── utility │ ├── twi.c │ └── twi.h ├── platform.txt ├── post_install.bat ├── post_install.sh ├── programmers.txt └── variants ├── nona4809 ├── pins_arduino.h ├── timers.h └── variant.c └── uno2018 ├── pins_arduino.h ├── timers.h └── variant.c /.github/workflows/compile-examples.yml: -------------------------------------------------------------------------------- 1 | name: Compile Examples 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - ".github/workflows/compile-examples.yml" 7 | - "cores/**" 8 | - "libraries/**" 9 | - "variants/**" 10 | - "boards.txt" 11 | - "platform.txt" 12 | push: 13 | paths: 14 | - ".github/workflows/compile-examples.yml" 15 | - "cores/**" 16 | - "libraries/**" 17 | - "variants/**" 18 | - "boards.txt" 19 | - "platform.txt" 20 | 21 | jobs: 22 | compile-test: 23 | runs-on: ubuntu-latest 24 | 25 | env: 26 | # sketch paths to compile (recursive) for all boards 27 | UNIVERSAL_SKETCH_PATHS: | 28 | - extras/examples 29 | - libraries/Wire 30 | - libraries/SPI 31 | - libraries/SoftwareSerial 32 | - libraries/EEPROM 33 | - ~/Arduino/libraries/Servo/examples 34 | - ~/Arduino/libraries/LiquidCrystal/examples 35 | - ~/Arduino/libraries/MFRC522/examples 36 | - ~/Arduino/libraries/Ethernet/examples 37 | - ~/Arduino/libraries/Adafruit_MQTT_Library/examples/mqtt_ethernet 38 | - ~/Arduino/libraries/ArduinoBearSSL/examples/SHA1 39 | - ~/Arduino/libraries/ArduinoBearSSL/examples/SHA256 40 | - ~/Arduino/libraries/Arduino_LSM9DS1/examples 41 | - ~/Arduino/libraries/SD/examples 42 | - ~/Arduino/libraries/Arduino_JSON/examples 43 | - ~/Arduino/libraries/TFT/examples/Arduino/TFTBitmapLogo 44 | - ~/Arduino/libraries/TFT/examples/Arduino/TFTColorPicker 45 | - ~/Arduino/libraries/TFT/examples/Arduino/TFTDisplayText 46 | - ~/Arduino/libraries/TFT/examples/Arduino/TFTEtchASketch 47 | - ~/Arduino/libraries/TFT/examples/Arduino/TFTGraph 48 | - ~/Arduino/libraries/TFT/examples/Arduino/TFTPong 49 | - ~/Arduino/libraries/Arduino_CRC32/examples 50 | - ~/Arduino/libraries/Arduino_LSM6DS3/examples 51 | - ~/Arduino/libraries/Stepper/examples 52 | - ~/Arduino/libraries/Arduino_HTS221/examples 53 | - ~/Arduino/libraries/Arduino_DebugUtils/examples 54 | - ~/Arduino/libraries/Arduino_LPS22HB/examples 55 | - ~/Arduino/libraries/ArduinoDMX/examples 56 | - ~/Arduino/libraries/ArduinoRS485/examples 57 | SKETCHES_REPORTS_PATH: sketches-reports 58 | 59 | strategy: 60 | fail-fast: false 61 | 62 | matrix: 63 | board: [ 64 | {"fqbn": "arduino:megaavr:uno2018:mode=on", "type": "UnoWiFiRev2"}, 65 | {"fqbn": "arduino:megaavr:uno2018:mode=off", "type": "UnoWiFiRev2"}, 66 | {"fqbn": "arduino:megaavr:nona4809", "type": "NanoEvery"} 67 | ] 68 | 69 | # make board type-specific customizations to the matrix jobs 70 | include: 71 | # Uno WiFi Rev2 72 | - board: 73 | type: "UnoWiFiRev2" 74 | additional-sketch-paths: | 75 | - ~/Arduino/libraries/WiFiNINA/examples 76 | - ~/Arduino/libraries/ArduinoMqttClient/examples 77 | - ~/Arduino/libraries/Arduino_OAuth/examples/Tweeter 78 | # Nano Every 79 | - board: 80 | type: "NanoEvery" 81 | additional-sketch-paths: 82 | 83 | steps: 84 | - name: Checkout repository 85 | uses: actions/checkout@v2 86 | 87 | # The source files are in a subfolder of the ArduinoCore-API repository, so it's not possible to clone it directly to the final destination in the core 88 | - name: Checkout ArduinoCore-API 89 | uses: actions/checkout@v2 90 | with: 91 | repository: arduino/ArduinoCore-API 92 | path: extras/ArduinoCore-API 93 | 94 | - name: Install ArduinoCore-API 95 | run: mv "$GITHUB_WORKSPACE/extras/ArduinoCore-API/api" "$GITHUB_WORKSPACE/cores/arduino" 96 | 97 | - name: Checkout Basic examples 98 | uses: actions/checkout@v2 99 | with: 100 | repository: arduino/arduino-examples 101 | path: extras 102 | 103 | - name: Delete incompatible examples 104 | run: | 105 | # These boards do not support native USB 106 | rm -r "$GITHUB_WORKSPACE/extras/examples/09.USB" 107 | # The next command can be removed after the core integration with ArduinoCore-API 108 | rm -r "$GITHUB_WORKSPACE/extras/examples/10.StarterKit_BasicKit/p11_CrystalBall" 109 | # CapacitiveSensor library does not support megaAVR core yet 110 | rm -r "$GITHUB_WORKSPACE/extras/examples/10.StarterKit_BasicKit/p13_TouchSensorLamp" 111 | - name: Compile examples 112 | uses: arduino/compile-sketches@v1 113 | with: 114 | github-token: ${{ secrets.GITHUB_TOKEN }} 115 | fqbn: ${{ matrix.board.fqbn }} 116 | libraries: | 117 | - name: Adafruit MQTT Library 118 | - name: Servo 119 | - name: LiquidCrystal 120 | - name: MFRC522 121 | - name: Ethernet 122 | - name: ArduinoBearSSL 123 | - name: Arduino_LSM9DS1 124 | - name: TFT 125 | - name: ArduinoMqttClient 126 | - name: Arduino_CRC32 127 | - name: Arduino_LSM6DS3 128 | - name: Stepper 129 | - name: SD 130 | - name: Arduino_JSON 131 | - name: Arduino_HTS221 132 | - name: Arduino_DebugUtils 133 | - name: Arduino_LPS22HB 134 | - name: ArduinoDMX 135 | - name: ArduinoRS485 136 | - name: Arduino_OAuth 137 | - name: WiFiNINA 138 | platforms: | 139 | # Use Board Manager to install the latest release of Arduino megaAVR Boards to get the toolchain 140 | - name: "arduino:megaavr" 141 | # Overwrite the Board Manager installation with the local platform 142 | - source-path: "./" 143 | name: "arduino:megaavr" 144 | sketch-paths: | 145 | ${{ env.UNIVERSAL_SKETCH_PATHS }} 146 | ${{ matrix.additional-sketch-paths }} 147 | enable-deltas-report: 'true' 148 | sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} 149 | 150 | - name: Save memory usage change report as artifact 151 | uses: actions/upload-artifact@v2 152 | with: 153 | path: ${{ env.SKETCHES_REPORTS_PATH }} 154 | name: ${{ env.SKETCHES_REPORTS_PATH }} 155 | -------------------------------------------------------------------------------- /.github/workflows/compile-muxto.yml: -------------------------------------------------------------------------------- 1 | name: Compile MuxTO 2 | 3 | # See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows 4 | on: 5 | push: 6 | paths: 7 | - ".github/workflows/compile-muxto.yml" 8 | - "firmwares/MuxTO/**" 9 | pull_request: 10 | paths: 11 | - ".github/workflows/compile-muxto.yml" 12 | - "firmwares/MuxTO/**" 13 | schedule: 14 | # Run every Tuesday at 8 AM UTC to catch breakage caused by changes to external resources (libraries, platforms). 15 | - cron: "0 8 * * TUE" 16 | workflow_dispatch: 17 | repository_dispatch: 18 | 19 | env: 20 | BINARY_FILENAME: MuxTO.ino.bin 21 | BINARY_ARTIFACT_NAME: MuxTO 22 | 23 | jobs: 24 | build: 25 | name: Build firmware 26 | runs-on: ubuntu-latest 27 | 28 | strategy: 29 | fail-fast: false 30 | 31 | matrix: 32 | board: 33 | - fqbn: arduino:samd:muxto:float=default,config=enabled,clock=internal_usb,timer=timer_732Hz,bootloader=4kb,serial=two_uart,usb=cdc 34 | platforms: | 35 | # Install MattairTech_Arduino:samd via Boards Manager for the toolchain 36 | - name: MattairTech_Arduino:samd 37 | source-url: https://www.mattairtech.com/software/arduino/package_MattairTech_index.json 38 | # This needs to match with the version of MattairTech_Arduino:samd the Arduino fork is based on in order to get the right tool versions 39 | version: 1.6.17 40 | # Install officila samd version for compiler support 41 | - name: arduino:samd 42 | # Install the platform with MuxTO support 43 | - name: arduino:samd 44 | source-url: https://github.com/arduino/ArduinoCore-samd.git 45 | version: muxto 46 | 47 | steps: 48 | - name: Set environment variables 49 | run: | 50 | # See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable 51 | echo "BINARY_OUTPUT_PATH=${{ runner.temp }}/output" >> "$GITHUB_ENV" 52 | echo "SKETCHES_REPORTS_PATH=${{ runner.temp }}/sketches-reports" >> "$GITHUB_ENV" 53 | 54 | - name: Checkout repository 55 | uses: actions/checkout@v2 56 | 57 | - name: Compile firmware 58 | uses: arduino/compile-sketches@v1 59 | with: 60 | github-token: ${{ secrets.GITHUB_TOKEN }} 61 | fqbn: ${{ matrix.board.fqbn }} 62 | platforms: ${{ matrix.board.platforms }} 63 | libraries: | 64 | - 65 | sketch-paths: | 66 | - firmwares/MuxTO 67 | cli-compile-flags: | 68 | - --output-dir=${{ env.BINARY_OUTPUT_PATH }} 69 | enable-deltas-report: true 70 | sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} 71 | 72 | - name: Save firmware binary as workflow artifact 73 | uses: actions/upload-artifact@v2 74 | with: 75 | if-no-files-found: error 76 | path: ${{ env.BINARY_OUTPUT_PATH }}/${{ env.BINARY_FILENAME }} 77 | name: ${{ env.BINARY_ARTIFACT_NAME }} 78 | 79 | - name: Save sketches report as workflow artifact 80 | uses: actions/upload-artifact@v2 81 | with: 82 | if-no-files-found: error 83 | path: ${{ env.SKETCHES_REPORTS_PATH }} 84 | name: sketches-reports 85 | 86 | size: 87 | name: Check firmware size 88 | needs: build 89 | runs-on: ubuntu-latest 90 | steps: 91 | - name: Download binary artifact 92 | uses: actions/download-artifact@v2 93 | with: 94 | name: ${{ env.BINARY_ARTIFACT_NAME }} 95 | 96 | # The normal size check done by Arduino CLI is not working correctly, so it's necessary to check the size directly 97 | - name: Check firmware binary size 98 | run: | 99 | BINARY_SIZE="$(stat --printf="%s" "${{ github.workspace }}/${{ env.BINARY_FILENAME }}")" 100 | MAX_BINARY_SIZE=$((12 * 1024)) 101 | echo "File size: ${BINARY_SIZE}/${MAX_BINARY_SIZE} B" 102 | if [[ $BINARY_SIZE -gt $MAX_BINARY_SIZE ]]; then 103 | echo "::error::Binary size of $BINARY_SIZE B exceeds the available memory ($MAX_BINARY_SIZE B)" 104 | exit 1 105 | fi 106 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | push: 5 | tags: 6 | - "[0-9]+.[0-9]+.[0-9]+*" 7 | 8 | jobs: 9 | core-pre-release-from-tag: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v2 15 | 16 | - name: Checkout ArduinoCore-API 17 | uses: actions/checkout@v2 18 | with: 19 | repository: arduino/ArduinoCore-API 20 | path: extras/ArduinoCore-API 21 | 22 | - name: Check if API should be compiled in the core 23 | id: checkapi 24 | run: | 25 | if [[ $(grep -r api platform.txt) ]]; then echo "::set-output name=IS_API::true"; fi 26 | 27 | - name: Checkout latest tag of ArduinoCore-API and add it to the core 28 | run: | 29 | cd extras/ArduinoCore-API 30 | git fetch --tags 31 | git checkout $(git describe --tags $(git rev-list --tags --max-count=1)) 32 | cd ../.. 33 | mv "$GITHUB_WORKSPACE/extras/ArduinoCore-API/api" "$GITHUB_WORKSPACE/cores/arduino" 34 | if: steps.checkapi.outputs.IS_API == 'true' 35 | 36 | - name: Remove ArduinoCore-API 37 | run: rm -r "$GITHUB_WORKSPACE/extras/ArduinoCore-API" 38 | 39 | - name: Set env 40 | run: echo "TAG_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV 41 | 42 | - name: Get repo name 43 | run: echo "REPOSITORY_NAME=$(echo ${{ github.repository }} | cut -d "/" -f2-)" >> $GITHUB_ENV 44 | 45 | - name: Package the new core 46 | run: | 47 | extras/pack.release.bash $TAG_VERSION $REPOSITORY_NAME 48 | cd extras 49 | mkdir staging 50 | echo $PWD 51 | mv ../*.json staging/ 52 | mv ../*.tar.bz2 staging/ 53 | cd .. 54 | 55 | - name: Get architecture name 56 | run: | 57 | echo "ARCHITECTURE=$(cat extras/package_index.json.NewTag.template | jq ".packages[0].platforms[0].architecture" | sed 's/\"//g')" >> $GITHUB_ENV 58 | 59 | - name: Upload package_*_index.json and *.tar.bz2 file to Arduino downloads servers 60 | env: 61 | AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} 62 | AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} 63 | run: | 64 | aws s3 sync extras/staging/ s3://${{ secrets.ARDUINO_DOWNLOADS_BUCKET }}/packages/staging/ --exclude "*" --include *.json 65 | aws s3 sync extras/staging/ s3://${{ secrets.ARDUINO_DOWNLOADS_BUCKET }}/cores/staging/ --exclude "*" --include *.tar.bz2 66 | 67 | - name: Checkout Basic examples 68 | uses: actions/checkout@v2 69 | with: 70 | repository: arduino/arduino-examples 71 | path: extras/arduino-examples 72 | 73 | - name: Install Arduino CLI 74 | uses: arduino/setup-arduino-cli@v1.1.1 75 | with: 76 | version: "0.14.0" 77 | 78 | - name: Download and verify new core 79 | run: | 80 | export PATH=$PATH:$PWD 81 | arduino-cli version 82 | cp extras/staging/package_${REPOSITORY_NAME}_${TAG_VERSION}_index.json . 83 | export ARDUINO_DIRECTORIES_DATA=$PWD 84 | export ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS=file://$PWD/package_${REPOSITORY_NAME}_${TAG_VERSION}_index.json 85 | arduino-cli config init 86 | arduino-cli config dump -v 87 | arduino-cli core update-index -v 88 | arduino-cli core install arduino:${ARCHITECTURE}@${TAG_VERSION} 89 | INDEX=0 90 | arduino-cli board listall --format=json > boardlist.json 91 | N=$(jq '.boards | length' boardlist.json) 92 | let N=N-1 93 | echo $N 94 | for INDEX in $(seq 0 1 $N); do arduino-cli compile --fqbn $(cat boardlist.json | jq ".boards[$INDEX].FQBN" | sed 's/\"//g') $PWD/extras/arduino-examples/examples/01.Basics/Blink; done 95 | 96 | # See: https://github.com/rtCamp/action-slack-notify 97 | - name: Slack notification of core pre-release 98 | uses: rtCamp/action-slack-notify@v2.1.0 99 | env: 100 | SLACK_CHANNEL: core_releases 101 | SLACK_COLOR: good 102 | SLACK_USERNAME: ArduinoBot 103 | SLACK_ICON: https://github.com/arduino.png?size=48 104 | SLACK_TITLE: Arduino core pre-release 105 | SLACK_MESSAGE: 'Version ${{ env.TAG_VERSION }} of core ${{ env.REPOSITORY_NAME }} is now available' 106 | SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} 107 | MSG_MINIMAL: true -------------------------------------------------------------------------------- /.github/workflows/report-size-deltas.yml: -------------------------------------------------------------------------------- 1 | name: Report PR Size Deltas 2 | 3 | on: 4 | schedule: 5 | - cron: '*/5 * * * *' 6 | 7 | jobs: 8 | report: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Comment size deltas reports to PRs 13 | uses: arduino/report-size-deltas@v1 14 | with: 15 | # The name of the workflow artifact created by the sketch compilation workflow 16 | sketches-reports-source: sketches-reports 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Adding the folder "avr/cores/arduino/api" to ignore list 2 | # this folder point to the repo below, and note not "master" but "api-release-cpp" 3 | # https://github.com/arduino/ArduinoCore-api/tree/api-release-cpp 4 | api 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cores/test/external/libvireg"] 2 | path = cores/test/external/libvireg 3 | url = https://github.com/bcmi-labs/libvireg 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino Core for ATMEGA4809 CPU 2 | 3 | [![Compile MuxTO status](https://github.com/arduino/ArduinoCore-megaavr/actions/workflows/compile-muxto.yml/badge.svg)](https://github.com/arduino/ArduinoCore-megaavr/actions/workflows/compile-muxto.yml) 4 | 5 | This repository contains the source code and configuration files of the Arduino Core 6 | for Microchip's ATMEGA4809 processor (used on the Arduino Uno WiFi Rev2 boards). 7 | 8 | ## Installation on Arduino IDE 9 | 10 | This core is available as a package in the Arduino IDE cores manager. 11 | Just open the "Boards Manager" and install the package called: 12 | 13 | "Arduino megaAVR Boards" 14 | 15 | ## Support 16 | 17 | There is a dedicated section of the Arduino Forum for general discussion and project assistance: 18 | 19 | http://forum.arduino.cc/index.php?board=126.0 20 | 21 | ## Bugs or Issues 22 | 23 | If you find a bug you can submit an issue here on github: 24 | 25 | https://github.com/arduino/ArduinoCore-megaavr/issues 26 | 27 | Before posting a new issue, please check if the same problem has been already reported by someone else 28 | to avoid duplicates. 29 | 30 | ## Contributions 31 | 32 | Contributions are always welcome. The preferred way to receive code cotribution is by submitting a 33 | Pull Request on github. 34 | 35 | ## Developing 36 | 37 | 1. Create an `/hardware/arduino` folder. Where `` is the location of your 38 | Arduino sketchbook. 39 | 1. Change directories: `cd /hardware/arduino` 40 | 1. Clone this repo: `git clone https://github.com/arduino/ArduinoCore-megaavr.git megaavr` 41 | 1. Change directories: `cd megaavr/cores/arduino` 42 | 1. Copy or symlink the `api` folder from the [ArduinoCore-API](https://github.com/arduino/ArduinoCore-API) repo. 43 | 1. Restart the IDE 44 | 45 | ## License and credits 46 | 47 | This core has been developed by Arduino SA in collaboration with Microchip. 48 | 49 | ``` 50 | Copyright (c) 2018 Arduino SA. All right reserved. 51 | 52 | This library is free software; you can redistribute it and/or 53 | modify it under the terms of the GNU Lesser General Public 54 | License as published by the Free Software Foundation; either 55 | version 2.1 of the License, or (at your option) any later version. 56 | 57 | This library is distributed in the hope that it will be useful, 58 | but WITHOUT ANY WARRANTY; without even the implied warranty of 59 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 60 | See the GNU Lesser General Public License for more details. 61 | 62 | You should have received a copy of the GNU Lesser General Public 63 | License along with this library; if not, write to the Free Software 64 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 65 | ``` -------------------------------------------------------------------------------- /boards.txt: -------------------------------------------------------------------------------- 1 | # See: https://arduino.github.io/arduino-cli/latest/platform-specification/ 2 | 3 | ############################################################## 4 | 5 | uno2018.name=Arduino UNO WiFi Rev2 6 | 7 | uno2018.vid.0=0x03eb 8 | uno2018.pid.0=0x2145 9 | uno2018.upload_port.0.vid=0x03eb 10 | uno2018.upload_port.0.pid=0x2145 11 | uno2018.upload_port.1.board=uno2018 12 | 13 | uno2018.upload.tool=avrdude 14 | uno2018.upload.tool.default=avrdude 15 | uno2018.upload.tool.network=arduino_ota 16 | uno2018.upload.protocol=xplainedmini_updi 17 | uno2018.upload.maximum_size=48640 18 | uno2018.upload.maximum_data_size=6144 19 | uno2018.upload.speed=115200 20 | uno2018.upload.extra_params=-Pusb 21 | uno2018.upload.extra_files="-Uflash:w:{runtime.platform.path}/bootloaders/{bootloader.file}:i" 22 | 23 | uno2018.build.mcu=atmega4809 24 | uno2018.build.f_cpu=16000000L 25 | uno2018.build.board=AVR_UNO_WIFI_REV2 26 | uno2018.build.core=arduino 27 | uno2018.build.variant=uno2018 28 | uno2018.build.text_section_start=.text=0x200 29 | uno2018.build.extra_flags={build.328emulation} -DMILLIS_USE_TIMERB3 30 | #uno2018.build.extra_flags=-B{runtime.tools.atpack.path}/gcc/dev/{build.mcu} 31 | 32 | uno2018.bootloader.tool=avrdude 33 | uno2018.bootloader.tool.default=avrdude 34 | uno2018.bootloader.file=atmega4809_uart_bl.hex 35 | uno2018.bootloader.SYSCFG0=0xC9 36 | uno2018.bootloader.BOOTEND=0x02 37 | uno2018.bootloader.OSCCFG=0x01 38 | uno2018.fuses.file=fuses_4809.bin 39 | 40 | menu.mode=Registers emulation 41 | uno2018.menu.mode.on=ATMEGA328 42 | uno2018.menu.mode.on.build.328emulation=-DUNO_WIFI_REV2_328MODE 43 | uno2018.menu.mode.off=None (ATMEGA4809) 44 | uno2018.menu.mode.off.build.328emulation= 45 | 46 | ############################################################## 47 | 48 | nona4809.name=Arduino Nano Every 49 | 50 | nona4809.vid.0=0x2341 51 | nona4809.pid.0=0x0058 52 | nona4809.upload_port.0.vid=0x2341 53 | nona4809.upload_port.0.pid=0x0058 54 | nona4809.upload_port.1.board=nona4809 55 | 56 | nona4809.upload.tool=avrdude 57 | nona4809.upload.tool.default=avrdude 58 | nona4809.upload.tool.network=arduino_ota 59 | nona4809.upload.protocol=jtag2updi 60 | nona4809.upload.maximum_size=49152 61 | nona4809.upload.maximum_data_size=6144 62 | nona4809.upload.speed=115200 63 | nona4809.upload.use_1200bps_touch=true 64 | nona4809.upload.extra_params=-P{serial.port} 65 | 66 | nona4809.build.mcu=atmega4809 67 | nona4809.build.f_cpu=16000000L 68 | nona4809.build.board=AVR_NANO_EVERY 69 | nona4809.build.core=arduino 70 | nona4809.build.variant=nona4809 71 | nona4809.build.text_section_start=.text=0x0 72 | nona4809.build.extra_flags={build.328emulation} -DMILLIS_USE_TIMERB3 -DNO_EXTERNAL_I2C_PULLUP 73 | #nona4809.build.extra_flags=-B{runtime.tools.atpack.path}/gcc/dev/{build.mcu} 74 | 75 | nona4809.bootloader.tool=avrdude 76 | nona4809.bootloader.tool.default=avrdude 77 | nona4809.bootloader.file=atmega4809_uart_bl.hex 78 | nona4809.bootloader.SYSCFG0=0xC9 79 | nona4809.bootloader.BOOTEND=0x00 80 | nona4809.bootloader.OSCCFG=0x01 81 | nona4809.fuses.file=fuses_4809.bin 82 | 83 | menu.mode=Registers emulation 84 | nona4809.menu.mode.on=ATMEGA328 85 | nona4809.menu.mode.on.build.328emulation=-DAVR_NANO_4809_328MODE 86 | nona4809.menu.mode.off=None (ATMEGA4809) 87 | nona4809.menu.mode.off.build.328emulation= 88 | 89 | ############################################################## 90 | -------------------------------------------------------------------------------- /bootloaders/atmega4809_uart_bl.hex: -------------------------------------------------------------------------------- 1 | :100000001124669A26E030E408C000000197E9F761 2 | :100010008DB183278DB9215019F081E091E7F6CF9A 3 | :1000200080911F138B3E69F48FEF80931F138DE92E 4 | :1000300093E084BF909300108091021081FDFCCF6B 5 | :1000400006C082E080930110E0E0F1E0099580ECC9 6 | :1000500080930608A09123110A2E000CBB0BBC5FF5 7 | :100060002CE530E00E9476007E5F8F4F9F4F2AE0A4 8 | :1000700095958795779567952A95D1F760930808A8 9 | :10008000709309088091E20581608093E205049AEB 10 | :10009000E0E0F2E42DE933E040E41EC08091040882 11 | :1000A00087FFFCCF80910008E11552E4F50711F4B9 12 | :1000B000882391F0809302088193CF018F7799274D 13 | :1000C000892B51F424BF309300108091021080FDE1 14 | :1000D000FCCF8DB184278DB9CF0190548115904C00 15 | :1000E000E8F288ED91E084BF909341000E947D008A 16 | :1000F000B7FF0895821B930B0895A29FB001B39F91 17 | :10010000C001A39F700D811D1124911DB29F700D20 18 | :08011000811D1124911D0895C9 19 | :02000004008278 20 | :00000001FF 21 | -------------------------------------------------------------------------------- /bootloaders/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ x$AVR_GCC_PATH == x"" ]; then 4 | AVR_GCC_PATH=/bin/ 5 | fi 6 | 7 | echo Compiling 8 | ${AVR_GCC_PATH}/avr-gcc -c -g -Os -w -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -Wl,--gc-sections -w -mmcu=atmega4809 -DF_CPU=16000000L boot.c -o boot.o 9 | ${AVR_GCC_PATH}/avr-gcc -g -Os -w -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -nostartfiles -Wl,--gc-sections -w -mmcu=atmega4809 -DF_CPU=16000000L boot.o -o boot.elf 10 | 11 | echo Extracting bin 12 | ${AVR_GCC_PATH}/avr-objcopy -O ihex -R .fuses boot.elf boot.hex 13 | #${AVR_GCC_PATH}avr-objcopy -O binary -j .fuses --set-section-flags=.fuses=alloc,load --no-change-warnings --change-section-lma .fuses=0 boot.elf boot.fuses 14 | 15 | echo Moving hex 16 | mv boot.hex atmega4809_uart_bl.hex 17 | 18 | #${AVR_GCC_PATH}/../avrdude/6.3.0-arduino14/bin/avrdude -C${AVR_GCC_PATH}/../avrdude/6.3.0-arduino14/etc/avrdude.conf -v -patmega4809 -cxplainedmini_updi -Pusb -Ufuses:w:boot.fuses:r -Uflash:w:boot.bin:r 19 | -------------------------------------------------------------------------------- /cores/arduino/Arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino.h - Main include file for the Arduino SDK 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef Arduino_h 21 | #define Arduino_h 22 | 23 | #include "api/ArduinoAPI.h" 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C"{ 31 | #endif 32 | 33 | /* Analog reference options */ 34 | 35 | /* Change in mega4809: two places to define analog reference 36 | - VREF peripheral defines internal reference 37 | - analog peripherals define internal/Vdd/external 38 | */ 39 | 40 | // internal from VREF 41 | 42 | /* Values shifted to avoid clashing with ADC REFSEL defines 43 | Will shift back in analog_reference function 44 | */ 45 | #define INTERNAL0V55 (VREF_ADC0REFSEL_0V55_gc >> VREF_ADC0REFSEL_gp) 46 | #define INTERNAL1V1 (VREF_ADC0REFSEL_1V1_gc >> VREF_ADC0REFSEL_gp) 47 | #define INTERNAL2V5 (VREF_ADC0REFSEL_2V5_gc >> VREF_ADC0REFSEL_gp) 48 | #define INTERNAL4V3 (VREF_ADC0REFSEL_4V34_gc >> VREF_ADC0REFSEL_gp) 49 | #define INTERNAL1V5 (VREF_ADC0REFSEL_1V5_gc >> VREF_ADC0REFSEL_gp) 50 | 51 | #define DEFAULT INTERNAL0V55 52 | #define INTERNAL ADC_REFSEL_INTREF_gc 53 | #define VDD ADC_REFSEL_VDDREF_gc 54 | #define EXTERNAL ADC_REFSEL_VREFA_gc 55 | 56 | #define VCC_5V0 2 57 | #define VCC_3V3 1 58 | #define VCC_1V8 0 59 | 60 | #define interrupts() sei() 61 | #define noInterrupts() cli() 62 | 63 | // avr-libc defines _NOP() since 1.6.2 64 | #ifndef _NOP 65 | #define _NOP() do { __asm__ volatile ("nop"); } while (0) 66 | #endif 67 | 68 | /* Allows performing a correction on the CPU value using the signature row 69 | values indicating oscillator error provided from the device manufacturer */ 70 | #define PERFORM_SIGROW_CORRECTION_F_CPU 0 71 | 72 | /* Variable containing corrected F_CPU value, after checks for safe operating 73 | frequency vs supply voltage, oscillator fuse setting and MCLK divider. 74 | Also includes the correction from signature row values if above #define 75 | PERFORM_SIGROW_CORRECTION_F_CPU = 1 */ 76 | extern uint32_t F_CPU_CORRECTED; 77 | 78 | uint16_t clockCyclesPerMicrosecondComp(uint32_t clk); 79 | uint16_t clockCyclesPerMicrosecond(); 80 | unsigned long clockCyclesToMicroseconds(unsigned long cycles); 81 | unsigned long microsecondsToClockCycles(unsigned long microseconds); 82 | 83 | // Get the bit location within the hardware port of the given virtual pin. 84 | // This comes from the pins_*.c file for the active board configuration. 85 | 86 | extern const uint8_t digital_pin_to_port[]; 87 | extern const uint8_t digital_pin_to_bit_mask[]; 88 | extern const uint8_t digital_pin_to_bit_position[]; 89 | extern const uint8_t digital_pin_to_timer[]; 90 | extern const uint8_t analog_pin_to_channel[]; 91 | 92 | // Get the bit location within the hardware port of the given virtual pin. 93 | // This comes from the pins_*.c file for the active board configuration. 94 | // 95 | // These perform slightly better as macros compared to inline functions 96 | // 97 | #define NOT_A_PIN 255 98 | #define NOT_A_PORT 255 99 | #define NOT_AN_INTERRUPT 255 100 | 101 | #define PA 0 102 | #define PB 1 103 | #define PC 2 104 | #define PD 3 105 | #define PE 4 106 | #define PF 5 107 | #define NUM_TOTAL_PORTS 6 108 | 109 | #define NOT_ON_TIMER 0 110 | #define TIMERA0 1 111 | #define TIMERB0 2 112 | #define TIMERB1 3 113 | #define TIMERB2 4 114 | #define TIMERB3 5 115 | 116 | void setup_timers(); 117 | bool isDoubleBondedActive(uint8_t pin); 118 | 119 | #define digitalPinToPort(pin) ( (pin < NUM_TOTAL_PINS) ? digital_pin_to_port[pin] : NOT_A_PIN ) 120 | #define digitalPinToBitPosition(pin) ( (pin < NUM_TOTAL_PINS) ? digital_pin_to_bit_position[pin] : NOT_A_PIN ) 121 | #define digitalPinToBitMask(pin) ( (pin < NUM_TOTAL_PINS) ? digital_pin_to_bit_mask[pin] : NOT_A_PIN ) 122 | #define digitalPinToTimer(pin) ( (pin < NUM_TOTAL_PINS) ? digital_pin_to_timer[pin] : NOT_ON_TIMER ) 123 | #define analogPinToBitPosition(pin) ( (digitalPinToAnalogInput(pin) != NOT_A_PIN) ? digital_pin_to_bit_position[pin + ANALOG_INPUT_OFFSET] : NOT_A_PIN ) 124 | #define analogPinToBitMask(pin) ( (digitalPinToAnalogInput(pin) != NOT_A_PIN) ? digital_pin_to_bit_mask[pin + ANALOG_INPUT_OFFSET] : NOT_A_PIN ) 125 | 126 | #define portToPortStruct(port) ( (port < NUM_TOTAL_PORTS) ? ((PORT_t *)&PORTA + port) : NULL) 127 | #define digitalPinToPortStruct(pin) ( (pin < NUM_TOTAL_PINS) ? ((PORT_t *)&PORTA + digitalPinToPort(pin)) : NULL) 128 | #define getPINnCTRLregister(port, bit_pos) ( ((port != NULL) && (bit_pos < NOT_A_PIN)) ? ((volatile uint8_t *)&(port->PIN0CTRL) + bit_pos) : NULL ) 129 | #define digitalPinToInterrupt(P) (P) 130 | 131 | #define portOutputRegister(P) ( (volatile uint8_t *)( &portToPortStruct(P)->OUT ) ) 132 | #define portInputRegister(P) ( (volatile uint8_t *)( &portToPortStruct(P)->IN ) ) 133 | #define portModeRegister(P) ( (volatile uint8_t *)( &portToPortStruct(P)->DIR ) ) 134 | 135 | #ifdef __cplusplus 136 | } // extern "C" 137 | #endif 138 | 139 | #ifdef __cplusplus 140 | #include "UART.h" 141 | #include "USBCore.h" 142 | #include "CDC.h" 143 | #include "MSC.h" 144 | #ifdef UNO_WIFI_REV2_328MODE 145 | #include 146 | #endif 147 | #ifdef AVR_NANO_4809_328MODE 148 | #include 149 | #endif 150 | #if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL) 151 | #error "Targets with both UART0 and CDC serial not supported" 152 | #endif 153 | 154 | #endif 155 | 156 | #ifdef __cplusplus 157 | extern "C" { 158 | #endif 159 | #include "pins_arduino.h" 160 | #ifdef __cplusplus 161 | } // extern "C" 162 | #endif 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /cores/arduino/CDC.h: -------------------------------------------------------------------------------- 1 | #ifndef __CDC_H__ 2 | #define __CDC_H__ 3 | 4 | #include "api/Stream.h" 5 | #include "api/USBAPI.h" 6 | 7 | #if defined (USBCON) 8 | 9 | //================================================================================ 10 | //================================================================================ 11 | // Serial over CDC (Serial1 is the physical port) 12 | 13 | #define RINGBUFFER_FORCE_SMALL_SIZE 14 | #include "api/RingBuffer.h" 15 | 16 | #ifndef SERIAL_BUFFER_SIZE 17 | #if ((RAMEND - RAMSTART) < 1023) 18 | #define SERIAL_BUFFER_SIZE 16 19 | #else 20 | #define SERIAL_BUFFER_SIZE 64 21 | #endif 22 | #endif 23 | #if (SERIAL_BUFFER_SIZE > 256) 24 | #error Please lower the CDC Buffer size 25 | #endif 26 | 27 | class Serial_ : public Stream 28 | { 29 | private: 30 | int peek_buffer; 31 | public: 32 | Serial_() { peek_buffer = -1; }; 33 | void begin(unsigned long); 34 | void begin(unsigned long, uint8_t); 35 | void end(void); 36 | 37 | virtual int available(void); 38 | virtual int peek(void); 39 | virtual int read(void); 40 | virtual int availableForWrite(void); 41 | virtual void flush(void); 42 | virtual size_t write(uint8_t); 43 | virtual size_t write(const uint8_t*, size_t); 44 | using Print::write; // pull in write(str) and write(buf, size) from Print 45 | operator bool(); 46 | 47 | //RingBuffer _rx_buffer(SERIAL_BUFFER_SIZE); 48 | 49 | // This method allows processing "SEND_BREAK" requests sent by 50 | // the USB host. Those requests indicate that the host wants to 51 | // send a BREAK signal and are accompanied by a single uint16_t 52 | // value, specifying the duration of the break. The value 0 53 | // means to end any current break, while the value 0xffff means 54 | // to start an indefinite break. 55 | // readBreak() will return the value of the most recent break 56 | // request, but will return it at most once, returning -1 when 57 | // readBreak() is called again (until another break request is 58 | // received, which is again returned once). 59 | // This also mean that if two break requests are received 60 | // without readBreak() being called in between, the value of the 61 | // first request is lost. 62 | // Note that the value returned is a long, so it can return 63 | // 0-0xffff as well as -1. 64 | int32_t readBreak(); 65 | 66 | // These return the settings specified by the USB host for the 67 | // serial port. These aren't really used, but are offered here 68 | // in case a sketch wants to act on these settings. 69 | uint32_t baud(); 70 | uint8_t stopbits(); 71 | uint8_t paritytype(); 72 | uint8_t numbits(); 73 | bool dtr(); 74 | bool rts(); 75 | enum { 76 | ONE_STOP_BIT = 0, 77 | ONE_AND_HALF_STOP_BIT = 1, 78 | TWO_STOP_BITS = 2, 79 | }; 80 | enum { 81 | NO_PARITY = 0, 82 | ODD_PARITY = 1, 83 | EVEN_PARITY = 2, 84 | MARK_PARITY = 3, 85 | SPACE_PARITY = 4, 86 | }; 87 | 88 | }; 89 | extern Serial_ Serial; 90 | 91 | #define HAVE_CDCSERIAL 92 | 93 | //================================================================================ 94 | //================================================================================ 95 | // CSC 'Driver' 96 | 97 | int CDC_GetInterface(uint8_t* interfaceNum); 98 | int CDC_GetDescriptor(int i); 99 | bool CDC_Setup(USBSetup& setup); 100 | 101 | #endif 102 | 103 | #endif -------------------------------------------------------------------------------- /cores/arduino/MSC.h: -------------------------------------------------------------------------------- 1 | #if defined (USBCON) 2 | 3 | #ifndef __MSC_H__ 4 | #define __MSC_H__ 5 | 6 | #include "api/USBAPI.h" 7 | 8 | //================================================================================ 9 | //================================================================================ 10 | // MSC 'Driver' 11 | 12 | int MSC_GetInterface(uint8_t* interfaceNum); 13 | int MSC_GetDescriptor(int i); 14 | bool MSC_Setup(USBSetup& setup); 15 | bool MSC_Data(uint8_t rx,uint8_t tx); 16 | 17 | #endif 18 | 19 | #endif -------------------------------------------------------------------------------- /cores/arduino/NANO_compat.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #pragma once 20 | #include 21 | 22 | #ifdef AVR_NANO_4809_328MODE 23 | 24 | /* 25 | ARDUINO PIN ATMEGA 328 ATMEGA 4809 26 | D0 PD0 PC4 (TX1) 27 | D1 PD1 PC5 (RX1) 28 | D2 PD2 PA0 29 | D3 PD3 PF5 30 | D4 PD4 PC6 31 | D5 PD5 PB2 32 | D6 PD6 PF4 33 | D7 PD7 PA1 34 | D8 PB0 PE3 35 | D9 PB1 PB0 36 | D10 PB2 PB1 37 | D11 PB3 PE0 (MOSI) 38 | D12 PB4 PE1 (MISO) 39 | D13 PB5 PE2 (SCK) 40 | A0 PC0 PD3 41 | A1 PC1 PD2 42 | A2 PC2 PD1 43 | A3 PC3 PD0 44 | A4 PC4 PA2 (SDA) 45 | A5 PC5 PA3 (SCL) 46 | A6 ADC6 PD4 47 | A7 ADC7 PD5 48 | */ 49 | 50 | class DDRBClass { 51 | public: 52 | DDRBClass(PORT_t * portb, PORT_t * porte); 53 | 54 | DDRBClass & operator = (uint8_t const value); 55 | DDRBClass & operator &= (uint8_t const value); 56 | DDRBClass & operator |= (uint8_t const value); 57 | private: 58 | PORT_t * _portb , * _porte; 59 | }; 60 | 61 | class PORTBClass { 62 | public: 63 | PORTBClass(PORT_t * portb, PORT_t * porte); 64 | 65 | PORTBClass & operator = (uint8_t const value); 66 | PORTBClass & operator &= (uint8_t const value); 67 | PORTBClass & operator |= (uint8_t const value); 68 | private: 69 | PORT_t * _portb , * _porte; 70 | }; 71 | 72 | /*****************************************************************************/ 73 | 74 | class DDRCClass { 75 | public: 76 | DDRCClass(PORT_t * porta, PORT_t * portd); 77 | 78 | DDRCClass & operator = (uint8_t const value); 79 | DDRCClass & operator &= (uint8_t const value); 80 | DDRCClass & operator |= (uint8_t const value); 81 | private: 82 | PORT_t * _porta , * _portd; 83 | }; 84 | 85 | class PORTCClass { 86 | public: 87 | PORTCClass(PORT_t * porta, PORT_t * portd); 88 | 89 | PORTCClass & operator = (uint8_t const value); 90 | PORTCClass & operator &= (uint8_t const value); 91 | PORTCClass & operator |= (uint8_t const value); 92 | private: 93 | PORT_t * _porta , * _portd; 94 | }; 95 | 96 | /*****************************************************************************/ 97 | 98 | class DDRDClass { 99 | public: 100 | DDRDClass(PORT_t * porta, PORT_t * portb, PORT_t * portc, PORT_t * portf); 101 | 102 | DDRDClass & operator = (uint8_t const value); 103 | DDRDClass & operator &= (uint8_t const value); 104 | DDRDClass & operator |= (uint8_t const value); 105 | private: 106 | PORT_t * _porta, * _portb , * _portc, * _portf; 107 | }; 108 | 109 | class PORTDClass { 110 | public: 111 | PORTDClass(PORT_t * porta, PORT_t * portb, PORT_t * portc, PORT_t * portf); 112 | 113 | PORTDClass & operator = (uint8_t const value); 114 | PORTDClass & operator &= (uint8_t const value); 115 | PORTDClass & operator |= (uint8_t const value); 116 | private: 117 | PORT_t * _porta, * _portb , * _portc, * _portf; 118 | }; 119 | 120 | /*****************************************************************************/ 121 | 122 | #ifndef HOST_BUILD 123 | #undef DDRB 124 | #undef PORTB 125 | #undef DDRC 126 | #undef PORTC 127 | #undef DDRD 128 | #undef PORTD 129 | 130 | extern DDRBClass DDRB; 131 | extern PORTBClass PORTB; 132 | extern DDRCClass DDRC; 133 | extern PORTCClass PORTC; 134 | extern DDRDClass DDRD; 135 | extern PORTDClass PORTD; 136 | #endif /* #ifndef HOST_BUILD */ 137 | 138 | #endif /* #ifdef AVR_NANO_4809_328MODE */ -------------------------------------------------------------------------------- /cores/arduino/UART0.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | UART0.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "UART.h" 27 | #include "UART_private.h" 28 | 29 | // Each UartClass is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // UartClass instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL0) 38 | 39 | #if defined(HWSERIAL0_RXC_VECTOR) 40 | ISR(HWSERIAL0_RXC_VECTOR) 41 | { 42 | Serial._rx_complete_irq(); 43 | } 44 | #else 45 | #error "Don't know what the Data Received interrupt vector is called for Serial" 46 | #endif 47 | 48 | #if defined(HWSERIAL0_DRE_VECTOR) 49 | ISR(HWSERIAL0_DRE_VECTOR) 50 | { 51 | Serial._tx_data_empty_irq(); 52 | } 53 | #else 54 | #error "Don't know what the Data Register Empty interrupt vector is called for Serial" 55 | #endif 56 | 57 | #if defined(HWSERIAL0) 58 | UartClass Serial(HWSERIAL0, PIN_WIRE_HWSERIAL0_RX, PIN_WIRE_HWSERIAL0_TX, HWSERIAL0_DRE_VECTOR_NUM, HWSERIAL0_MUX); 59 | #endif 60 | 61 | // Function that can be weakly referenced by serialEventRun to prevent 62 | // pulling in this file if it's not otherwise used. 63 | bool Serial0_available() { 64 | return Serial.available(); 65 | } 66 | 67 | #endif // HAVE_HWSERIAL0 68 | -------------------------------------------------------------------------------- /cores/arduino/UART1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | UART1.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "UART.h" 27 | #include "UART_private.h" 28 | 29 | // Each UartClass is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // UartClass instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL1) 38 | 39 | #if defined(HWSERIAL1_RXC_VECTOR) 40 | ISR(HWSERIAL1_RXC_VECTOR) 41 | { 42 | Serial1._rx_complete_irq(); 43 | } 44 | #else 45 | #error "Don't know what the Data Received interrupt vector is called for Serial1" 46 | #endif 47 | 48 | #if defined(HWSERIAL1_DRE_VECTOR) 49 | ISR(HWSERIAL1_DRE_VECTOR) 50 | { 51 | Serial1._tx_data_empty_irq(); 52 | } 53 | #else 54 | #error "Don't know what the Data Register Empty interrupt vector is called for Serial1" 55 | #endif 56 | 57 | #if defined(HWSERIAL1) 58 | UartClass Serial1(HWSERIAL1, PIN_WIRE_HWSERIAL1_RX, PIN_WIRE_HWSERIAL1_TX, HWSERIAL1_DRE_VECTOR_NUM, HWSERIAL1_MUX); 59 | #endif 60 | 61 | // Function that can be weakly referenced by serialEventRun to prevent 62 | // pulling in this file if it's not otherwise used. 63 | bool Serial1_available() { 64 | return Serial1.available(); 65 | } 66 | 67 | #endif // HAVE_HWSERIAL1 68 | -------------------------------------------------------------------------------- /cores/arduino/UART2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | UART2.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "UART.h" 27 | #include "UART_private.h" 28 | 29 | // Each UartClass is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // UartClass instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL2) 38 | 39 | #if defined(HWSERIAL2_RXC_VECTOR) 40 | ISR(HWSERIAL2_RXC_VECTOR) 41 | { 42 | Serial2._rx_complete_irq(); 43 | } 44 | #else 45 | #error "Don't know what the Data Received interrupt vector is called for Serial2" 46 | #endif 47 | 48 | #if defined(HWSERIAL2_DRE_VECTOR) 49 | ISR(HWSERIAL2_DRE_VECTOR) 50 | { 51 | Serial2._tx_data_empty_irq(); 52 | } 53 | #else 54 | #error "Don't know what the Data Register Empty interrupt vector is called for Serial2" 55 | #endif 56 | 57 | #if defined(HWSERIAL2) 58 | UartClass Serial2(HWSERIAL2, PIN_WIRE_HWSERIAL2_RX, PIN_WIRE_HWSERIAL2_TX, HWSERIAL2_DRE_VECTOR_NUM, HWSERIAL2_MUX); 59 | #endif 60 | 61 | // Function that can be weakly referenced by serialEventRun to prevent 62 | // pulling in this file if it's not otherwise used. 63 | bool Serial2_available() { 64 | return Serial2.available(); 65 | } 66 | 67 | #endif // HAVE_HWSERIAL2 68 | -------------------------------------------------------------------------------- /cores/arduino/UART3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | UART3.cpp - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | Modified 3 December 2013 by Matthijs Kooijman 23 | */ 24 | 25 | #include "Arduino.h" 26 | #include "UART.h" 27 | #include "UART_private.h" 28 | 29 | // Each UartClass is defined in its own file, sine the linker pulls 30 | // in the entire file when any element inside is used. --gc-sections can 31 | // additionally cause unused symbols to be dropped, but ISRs have the 32 | // "used" attribute so are never dropped and they keep the 33 | // UartClass instance in as well. Putting each instance in its own 34 | // file prevents the linker from pulling in any unused instances in the 35 | // first place. 36 | 37 | #if defined(HAVE_HWSERIAL3) 38 | 39 | #if defined(HWSERIAL3_RXC_VECTOR) 40 | ISR(HWSERIAL3_RXC_VECTOR) 41 | { 42 | Serial3._rx_complete_irq(); 43 | } 44 | #else 45 | #error "Don't know what the Data Received interrupt vector is called for Serial3" 46 | #endif 47 | 48 | #if defined(HWSERIAL3_DRE_VECTOR) 49 | ISR(HWSERIAL3_DRE_VECTOR) 50 | { 51 | Serial3._tx_data_empty_irq(); 52 | } 53 | #else 54 | #error "Don't know what the Data Register Empty interrupt vector is called for Serial3" 55 | #endif 56 | 57 | #if defined(HWSERIAL3) 58 | UartClass Serial3(HWSERIAL3, PIN_WIRE_HWSERIAL3_RX, PIN_WIRE_HWSERIAL3_TX, HWSERIAL3_DRE_VECTOR_NUM, HWSERIAL3_MUX); 59 | #endif 60 | 61 | // Function that can be weakly referenced by serialEventRun to prevent 62 | // pulling in this file if it's not otherwise used. 63 | bool Serial3_available() { 64 | return Serial3.available(); 65 | } 66 | 67 | #endif // HAVE_HWSERIAL3 68 | -------------------------------------------------------------------------------- /cores/arduino/UART_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | UART_private.h - Hardware serial library for Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 23 November 2006 by David A. Mellis 20 | Modified 28 September 2010 by Mark Sproul 21 | Modified 14 August 2012 by Alarus 22 | */ 23 | 24 | #include "wiring_private.h" 25 | 26 | // this next line disables the entire UART.cpp, 27 | // this is so I can support Attiny series and any other chip without a uart 28 | #if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3) 29 | 30 | // Constructors //////////////////////////////////////////////////////////////// 31 | 32 | UartClass::UartClass( 33 | volatile USART_t *hwserial_module, 34 | volatile uint8_t hwserial_rx_pin, 35 | volatile uint8_t hwserial_tx_pin, 36 | volatile uint8_t hwserial_dre_interrupt_vect_num, 37 | volatile uint8_t uart_mux) : 38 | _hwserial_module(hwserial_module), 39 | _hwserial_rx_pin(hwserial_rx_pin), 40 | _hwserial_tx_pin(hwserial_tx_pin), 41 | _uart_mux(uart_mux), 42 | _rx_buffer_head(0), _rx_buffer_tail(0), 43 | _tx_buffer_head(0), _tx_buffer_tail(0), 44 | _hwserial_dre_interrupt_vect_num(hwserial_dre_interrupt_vect_num), 45 | _hwserial_dre_interrupt_elevated(0), 46 | _prev_lvl1_interrupt_vect(0) 47 | { 48 | } 49 | 50 | // Actual interrupt handlers ////////////////////////////////////////////////////////////// 51 | 52 | void UartClass::_rx_complete_irq(void) 53 | { 54 | //if (bit_is_clear(*_rxdatah, USART_PERR_bp)) { 55 | if (!(((*_hwserial_module).RXDATAH) & USART_PERR_bm)) { 56 | // No Parity error, read byte and store it in the buffer if there is 57 | // room 58 | unsigned char c = (*_hwserial_module).RXDATAL; 59 | rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE; 60 | 61 | // if we should be storing the received character into the location 62 | // just before the tail (meaning that the head would advance to the 63 | // current location of the tail), we're about to overflow the buffer 64 | // and so we don't write the character or advance the head. 65 | if (i != _rx_buffer_tail) { 66 | _rx_buffer[_rx_buffer_head] = c; 67 | _rx_buffer_head = i; 68 | } 69 | if (bound != NULL) { 70 | bound->write(c); 71 | } 72 | } else { 73 | // Parity error, read byte but discard it 74 | (*_hwserial_module).RXDATAL; 75 | } 76 | } 77 | 78 | #endif // whole file 79 | -------------------------------------------------------------------------------- /cores/arduino/UNO_compat.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Arduino Team. All right reserved. 3 | This library is free software; you can redistribute it and/or 4 | modify it under the terms of the GNU Lesser General Public 5 | License as published by the Free Software Foundation; either 6 | version 2.1 of the License, or (at your option) any later version. 7 | This library is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | Lesser General Public License for more details. 11 | You should have received a copy of the GNU Lesser General Public 12 | License along with this library; if not, write to the Free Software 13 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 14 | */ 15 | 16 | #include "UNO_compat.h" 17 | 18 | #ifdef UNO_WIFI_REV2_328MODE 19 | 20 | #warning "ATMEGA328 registers emulation is enabled. You may encounter some speed issue. Please consider to disable it in the Tools menu" 21 | 22 | PORTBClass PORTB; 23 | PORTCClass PORTC; 24 | PORTDClass PORTD; 25 | 26 | DDRBClass DDRB; 27 | DDRCClass DDRC; 28 | DDRDClass DDRD; 29 | 30 | #endif /* #ifdef UNO_WIFI_REV2_328MODE */ -------------------------------------------------------------------------------- /cores/arduino/WInterrupts.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 | 3 | /* 4 | Part of the Wiring project - http://wiring.uniandes.edu.co 5 | 6 | Copyright (c) 2004-05 Hernando Barragan 7 | 8 | This library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General 19 | Public License along with this library; if not, write to the 20 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 21 | Boston, MA 02111-1307 USA 22 | 23 | Modified 24 November 2006 by David A. Mellis 24 | Modified 1 August 2010 by Mark Sproul 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "wiring_private.h" 34 | 35 | static volatile voidFuncPtrParam intFunc[EXTERNAL_NUM_INTERRUPTS]; 36 | static void* args[EXTERNAL_NUM_INTERRUPTS]; 37 | 38 | void attachInterruptParam(pin_size_t pin, void (*userFunc)(void*), PinStatus mode, void* params) { 39 | 40 | /* Get bit position and check pin validity */ 41 | uint8_t bit_pos = digitalPinToBitPosition(pin); 42 | if(bit_pos == NOT_A_PIN) return; 43 | 44 | /* Get interrupt number from pin */ 45 | uint8_t interruptNum = (digitalPinToPort(pin) * 8) + bit_pos; 46 | 47 | /* Check interrupt number and apply function pointer to correct array index */ 48 | if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { 49 | intFunc[interruptNum] = userFunc; 50 | args[interruptNum] = params; 51 | 52 | // Configure the interrupt mode (trigger on low input, any change, rising 53 | // edge, or falling edge). The mode constants were chosen to correspond 54 | // to the configuration bits in the hardware register, so we simply apply 55 | // the setting in the pin control register 56 | 57 | int isc_mode; 58 | 59 | switch (mode) { 60 | case CHANGE: 61 | isc_mode = PORT_ISC_BOTHEDGES_gc; 62 | break; 63 | case FALLING: 64 | isc_mode = PORT_ISC_FALLING_gc; 65 | break; 66 | case RISING: 67 | isc_mode = PORT_ISC_RISING_gc; 68 | break; 69 | case LOW: 70 | isc_mode = PORT_ISC_LEVEL_gc; 71 | break; 72 | default: 73 | // AVR doesn't support level triggered interrupts 74 | return; 75 | } 76 | 77 | // Enable the interrupt. 78 | 79 | /* Get pointer to correct pin control register */ 80 | PORT_t *port = digitalPinToPortStruct(pin); 81 | volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos); 82 | 83 | /* Clear any previous setting */ 84 | *pin_ctrl_reg &= ~(PORT_ISC_gm); 85 | 86 | /* Apply ISC setting */ 87 | *pin_ctrl_reg |= isc_mode; 88 | } 89 | } 90 | 91 | void attachInterrupt(uint8_t pin, void (*userFunc)(void), PinStatus mode) { 92 | attachInterruptParam(pin, (voidFuncPtrParam)userFunc, mode, NULL); 93 | } 94 | 95 | void detachInterrupt(uint8_t pin) { 96 | /* Get bit position and check pin validity */ 97 | uint8_t bit_pos = digitalPinToBitPosition(pin); 98 | if(bit_pos == NOT_A_PIN) return; 99 | 100 | /* Get interrupt number from pin */ 101 | uint8_t interruptNum = (digitalPinToPort(pin) * 8) + bit_pos; 102 | 103 | if(interruptNum < EXTERNAL_NUM_INTERRUPTS) { 104 | // Disable the interrupt. 105 | 106 | /* Get pointer to correct pin control register */ 107 | PORT_t *port = digitalPinToPortStruct(pin); 108 | volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos); 109 | 110 | /* Clear ISC setting */ 111 | *pin_ctrl_reg &= ~(PORT_ISC_gm); 112 | 113 | intFunc[interruptNum] = 0; 114 | } 115 | } 116 | 117 | static void port_interrupt_handler(uint8_t port) { 118 | 119 | PORT_t *portStruct = portToPortStruct(port); 120 | /* Copy flags */ 121 | uint8_t int_flags = portStruct->INTFLAGS; 122 | 123 | uint8_t bit_pos = PIN0_bp, bit_mask = PIN0_bm; 124 | 125 | /* Iterate through flags */ 126 | while(bit_pos <= PIN7_bp){ 127 | 128 | /* Check if flag raised */ 129 | if(int_flags & bit_mask){ 130 | 131 | /* Get interrupt */ 132 | uint8_t interrupt_num = port*8 + bit_pos; 133 | 134 | /* Check if function defined */ 135 | if(intFunc[interrupt_num] != 0){ 136 | 137 | /* Call function */ 138 | intFunc[interrupt_num](args[interrupt_num]); 139 | } 140 | } 141 | bit_pos++; 142 | bit_mask = (bit_mask << 1); 143 | } 144 | 145 | /* Clear flags that have been handled */ 146 | portStruct->INTFLAGS = int_flags; 147 | } 148 | 149 | #define IMPLEMENT_ISR(vect, port) \ 150 | ISR(vect) { \ 151 | port_interrupt_handler(port);\ 152 | } \ 153 | 154 | IMPLEMENT_ISR(PORTA_PORT_vect, PA) 155 | IMPLEMENT_ISR(PORTB_PORT_vect, PB) 156 | IMPLEMENT_ISR(PORTC_PORT_vect, PC) 157 | IMPLEMENT_ISR(PORTD_PORT_vect, PD) 158 | IMPLEMENT_ISR(PORTE_PORT_vect, PE) 159 | IMPLEMENT_ISR(PORTF_PORT_vect, PF) 160 | -------------------------------------------------------------------------------- /cores/arduino/WMath.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2 | 3 | /* 4 | Part of the Wiring project - http://wiring.org.co 5 | Copyright (c) 2004-06 Hernando Barragan 6 | Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/ 7 | 8 | This library is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU Lesser General Public 10 | License as published by the Free Software Foundation; either 11 | version 2.1 of the License, or (at your option) any later version. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General 19 | Public License along with this library; if not, write to the 20 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 21 | Boston, MA 02111-1307 USA 22 | */ 23 | 24 | extern "C" { 25 | #include "stdlib.h" 26 | } 27 | 28 | void randomSeed(unsigned long seed) 29 | { 30 | if (seed != 0) { 31 | srandom(seed); 32 | } 33 | } 34 | 35 | long random(long howbig) 36 | { 37 | if (howbig == 0) { 38 | return 0; 39 | } 40 | return random() % howbig; 41 | } 42 | 43 | long random(long howsmall, long howbig) 44 | { 45 | if (howsmall >= howbig) { 46 | return howsmall; 47 | } 48 | long diff = howbig - howsmall; 49 | return random(diff) + howsmall; 50 | } 51 | -------------------------------------------------------------------------------- /cores/arduino/abi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | 21 | extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__)); 22 | extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__)); 23 | 24 | void __cxa_pure_virtual(void) { 25 | // We might want to write some diagnostics to uart in this case 26 | //std::terminate(); 27 | abort(); 28 | } 29 | 30 | void __cxa_deleted_virtual(void) { 31 | // We might want to write some diagnostics to uart in this case 32 | //std::terminate(); 33 | abort(); 34 | } 35 | 36 | -------------------------------------------------------------------------------- /cores/arduino/hooks.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /** 20 | * Empty yield() hook. 21 | * 22 | * This function is intended to be used by library writers to build 23 | * libraries or sketches that supports cooperative threads. 24 | * 25 | * Its defined as a weak symbol and it can be redefined to implement a 26 | * real cooperative scheduler. 27 | */ 28 | static void __empty() { 29 | // Empty 30 | } 31 | void yield(void) __attribute__ ((weak, alias("__empty"))); 32 | -------------------------------------------------------------------------------- /cores/arduino/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | main.cpp - Main loop for Arduino sketches 3 | Copyright (c) 2005-2013 Arduino Team. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | 22 | // Declared weak in Arduino.h to allow user redefinitions. 23 | int atexit(void (* /*func*/ )()) { return 0; } 24 | 25 | // Weak empty variant initialization function. 26 | // May be redefined by variant files. 27 | void initVariant() __attribute__((weak)); 28 | void initVariant() { } 29 | 30 | void setupUSB() __attribute__((weak)); 31 | void setupUSB() { } 32 | 33 | int main(void) 34 | { 35 | init(); 36 | 37 | initVariant(); 38 | 39 | #if defined(USBCON) 40 | USBDevice.attach(); 41 | #endif 42 | 43 | setup(); 44 | 45 | for (;;) { 46 | loop(); 47 | if (serialEventRun) serialEventRun(); 48 | } 49 | 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /cores/arduino/new.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #include 20 | 21 | void *operator new(size_t size) { 22 | return malloc(size); 23 | } 24 | 25 | void *operator new[](size_t size) { 26 | return malloc(size); 27 | } 28 | 29 | void operator delete(void * ptr) { 30 | free(ptr); 31 | } 32 | 33 | void operator delete[](void * ptr) { 34 | free(ptr); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /cores/arduino/new.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2014 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef NEW_H 20 | #define NEW_H 21 | 22 | #include 23 | 24 | void * operator new(size_t size); 25 | void * operator new[](size_t size); 26 | void operator delete(void * ptr); 27 | void operator delete[](void * ptr); 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /cores/arduino/wiring_analog.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_analog.c - analog input and output 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | Modified 28 September 2010 by Mark Sproul 23 | */ 24 | 25 | #include "wiring_private.h" 26 | #include "Arduino.h" 27 | 28 | uint8_t analog_reference = DEFAULT; 29 | 30 | void analogReference(uint8_t mode) 31 | { 32 | /* Clear relevant settings */ 33 | ADC0.CTRLC &= ~(ADC_REFSEL_gm); 34 | VREF.CTRLA &= ~(VREF_ADC0REFSEL_gm); 35 | 36 | /* If reference NOT using internal reference from VREF */ 37 | if((mode == EXTERNAL) || (mode == VDD)) { 38 | 39 | /* Set reference in ADC peripheral */ 40 | ADC0.CTRLC |= mode; 41 | 42 | /* If reference using internal reference from VREF */ 43 | } else if ( 44 | (mode == INTERNAL0V55) 45 | || (mode == INTERNAL1V1) 46 | || (mode == INTERNAL2V5) 47 | || (mode == INTERNAL4V3) 48 | || (mode == INTERNAL1V5)) { 49 | 50 | /* Set ADC reference to INTERNAL */ 51 | ADC0.CTRLC |= INTERNAL; 52 | 53 | /* Configure VREF ADC0 reference */ 54 | VREF.CTRLA |= (mode << VREF_ADC0REFSEL_gp); 55 | 56 | /* Non-standard values / default */ 57 | } else { 58 | 59 | /* Non valid value will set default */ 60 | /* Set ADC reference to INTERNAL */ 61 | ADC0.CTRLC |= INTERNAL; 62 | 63 | /* Configure VREF ADC0 reference */ 64 | VREF.CTRLA |= (INTERNAL0V55 << VREF_ADC0REFSEL_gp); 65 | } 66 | } 67 | 68 | int analogRead(uint8_t pin) 69 | { 70 | pin = digitalPinToAnalogInput(pin); 71 | if(pin > NUM_ANALOG_INPUTS) return NOT_A_PIN; 72 | 73 | /* Check if TWI is operating on double bonded pin (Master Enable is high 74 | in both Master and Slave mode for bus error detection, so this can 75 | indicate an active state for Wire) */ 76 | if(isDoubleBondedActive(pin)) return 0; 77 | 78 | uint8_t low, high; 79 | 80 | #if defined(analogPinToChannel) 81 | /* If analog pin number != adc0 channel */ 82 | #endif 83 | 84 | #if defined(ADC0) 85 | /* Reference should be already set up */ 86 | /* Select channel */ 87 | ADC0.MUXPOS = (pin << ADC_MUXPOS_gp); 88 | 89 | /* Start conversion */ 90 | ADC0.COMMAND = ADC_STCONV_bm; 91 | 92 | /* Wait for result ready */ 93 | while(!(ADC0.INTFLAGS & ADC_RESRDY_bm)); 94 | 95 | /* Save state */ 96 | uint8_t status = SREG; 97 | cli(); 98 | 99 | /* Read result */ 100 | low = ADC0.RESL; 101 | high = ADC0.RESH; 102 | 103 | /* Restore state */ 104 | SREG = status; 105 | 106 | #else /* No ADC, return 0 */ 107 | low = 0; 108 | high = 0; 109 | #endif 110 | 111 | /* Combine two bytes */ 112 | return (high << 8) | low; 113 | } 114 | 115 | // Right now, PWM output only works on the pins with 116 | // hardware support. These are defined in the appropriate 117 | // pins_*.c file. For the rest of the pins, we default 118 | // to digital output. 119 | void analogWrite(uint8_t pin, int val) 120 | { 121 | 122 | uint8_t bit_pos = digitalPinToBitPosition(pin); 123 | if(bit_pos == NOT_A_PIN || isDoubleBondedActive(pin)) return; 124 | 125 | // We need to make sure the PWM output is enabled for those pins 126 | // that support it, as we turn it off when digitally reading or 127 | // writing with them. Also, make sure the pin is in output mode 128 | // for consistently with Wiring, which doesn't require a pinMode 129 | // call for the analog output pins. 130 | pinMode(pin, OUTPUT); 131 | 132 | if(val < 1){ /* if zero or negative drive digital low */ 133 | 134 | digitalWrite(pin, LOW); 135 | 136 | } else if(val > 255){ /* if max or greater drive digital high */ 137 | 138 | digitalWrite(pin, HIGH); 139 | 140 | } else { /* handle pwm to generate analog value */ 141 | 142 | /* Get timer */ 143 | uint8_t digital_pin_timer = digitalPinToTimer(pin); 144 | 145 | uint16_t* timer_cmp_out; 146 | TCB_t *timer_B; 147 | 148 | uint8_t savedSREG; 149 | 150 | /* Find out Port and Pin to correctly handle port mux, and timer. */ 151 | switch (digital_pin_timer) { 152 | 153 | case TIMERA0: 154 | /* Calculate correct compare buffer register */ 155 | timer_cmp_out = ((uint16_t*) (&TCA0.SINGLE.CMP0BUF)) + bit_pos; 156 | 157 | /* Configure duty cycle for correct compare channel */ 158 | savedSREG = SREG; 159 | cli(); 160 | (*timer_cmp_out) = (val); // non-atomic 16-bit write operation 161 | SREG = savedSREG; 162 | 163 | /* Enable output on pin */ 164 | TCA0.SINGLE.CTRLB |= (1 << (TCA_SINGLE_CMP0EN_bp + bit_pos)); 165 | 166 | break; 167 | 168 | case TIMERB0: 169 | case TIMERB1: 170 | case TIMERB2: 171 | case TIMERB3: 172 | 173 | /* Get pointer to timer, TIMERB0 order definition in Arduino.h*/ 174 | //assert (((TIMERB0 - TIMERB3) == 2)); 175 | timer_B = ((TCB_t *)&TCB0 + (digital_pin_timer - TIMERB0)); 176 | 177 | /* set duty cycle */ 178 | // (16-bit read/write operation are non-atomic and use a temporary register) 179 | savedSREG = SREG; 180 | cli(); 181 | timer_B->CCMPL = timer_B->CCMPL; // copy CCMPL into temporary register 182 | timer_B->CCMPH = val; // set CCMPH value + copy temporary register content into CCMPL 183 | SREG = savedSREG; 184 | 185 | /* Enable Timer Output */ 186 | timer_B->CTRLB |= (TCB_CCMPEN_bm); 187 | 188 | break; 189 | 190 | /* If non timer pin, or unknown timer definition. */ 191 | /* do a digital write */ 192 | 193 | case NOT_ON_TIMER: 194 | default: 195 | if (val < 128) { 196 | digitalWrite(pin, LOW); 197 | } else { 198 | digitalWrite(pin, HIGH); 199 | } 200 | break; 201 | } 202 | } 203 | } -------------------------------------------------------------------------------- /cores/arduino/wiring_digital.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_digital.c - digital input and output functions 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | 22 | Modified 28 September 2010 by Mark Sproul 23 | */ 24 | 25 | #define ARDUINO_MAIN 26 | #include "wiring_private.h" 27 | #include "pins_arduino.h" 28 | 29 | __attribute__((weak)) bool isDoubleBondedActive(uint8_t pin __attribute__((unused))) { 30 | return false; 31 | }; 32 | 33 | void pinMode(uint8_t pin, PinMode mode) 34 | { 35 | uint8_t bit_mask = digitalPinToBitMask(pin); 36 | 37 | if ((bit_mask == NOT_A_PIN) || (mode > INPUT_PULLUP) || isDoubleBondedActive(pin)) return; 38 | 39 | PORT_t* port = digitalPinToPortStruct(pin); 40 | if(port == NULL) return; 41 | 42 | if(mode == OUTPUT){ 43 | 44 | /* Configure direction as output */ 45 | port->DIRSET = bit_mask; 46 | 47 | } else { /* mode == INPUT or INPUT_PULLUP */ 48 | 49 | uint8_t bit_pos = digitalPinToBitPosition(pin); 50 | /* Calculate where pin control register is */ 51 | volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos); 52 | 53 | /* Save state */ 54 | uint8_t status = SREG; 55 | cli(); 56 | 57 | /* Configure direction as input */ 58 | port->DIRCLR = bit_mask; 59 | 60 | /* Configure pull-up resistor */ 61 | if(mode == INPUT_PULLUP){ 62 | 63 | /* Enable pull-up */ 64 | *pin_ctrl_reg |= PORT_PULLUPEN_bm; 65 | 66 | } else { /* mode == INPUT (no pullup) */ 67 | 68 | /* Disable pull-up */ 69 | *pin_ctrl_reg &= ~(PORT_PULLUPEN_bm); 70 | } 71 | 72 | /* Restore state */ 73 | SREG = status; 74 | } 75 | } 76 | 77 | // Forcing this inline keeps the callers from having to push their own stuff 78 | // on the stack. It is a good performance win and only takes 1 more byte per 79 | // user than calling. (It will take more bytes on the 168.) 80 | // 81 | // But shouldn't this be moved into pinMode? Seems silly to check and do on 82 | // each digitalread or write. 83 | // 84 | // Mark Sproul: 85 | // - Removed inline. Save 170 bytes on atmega1280 86 | // - changed to a switch statment; added 32 bytes but much easier to read and maintain. 87 | // - Added more #ifdefs, now compiles for atmega645 88 | // 89 | //static inline void turnOffPWM(uint8_t timer) __attribute__ ((always_inline)); 90 | //static inline void turnOffPWM(uint8_t timer) 91 | static void turnOffPWM(uint8_t pin) 92 | { 93 | /* Actually turn off compare channel, not the timer */ 94 | 95 | /* Get pin's timer */ 96 | uint8_t timer = digitalPinToTimer(pin); 97 | if(timer == NOT_ON_TIMER) return; 98 | 99 | uint8_t bit_pos; 100 | TCB_t *timerB; 101 | 102 | switch (timer) { 103 | 104 | /* TCA0 */ 105 | case TIMERA0: 106 | /* Bit position will give output channel */ 107 | bit_pos = digitalPinToBitPosition(pin); 108 | 109 | /* Disable corresponding channel */ 110 | TCA0.SINGLE.CTRLB &= ~(1 << (TCA_SINGLE_CMP0EN_bp + bit_pos)); 111 | 112 | break; 113 | 114 | /* TCB - only one output */ 115 | case TIMERB0: 116 | case TIMERB1: 117 | case TIMERB2: 118 | case TIMERB3: 119 | 120 | timerB = (TCB_t *)&TCB0 + (timer - TIMERB0); 121 | 122 | /* Disable TCB compare channel */ 123 | timerB->CTRLB &= ~(TCB_CCMPEN_bm); 124 | 125 | break; 126 | default: 127 | break; 128 | } 129 | } 130 | 131 | void digitalWrite(uint8_t pin, PinStatus val) 132 | { 133 | /* Get bit mask for pin */ 134 | uint8_t bit_mask = digitalPinToBitMask(pin); 135 | if(bit_mask == NOT_A_PIN || isDoubleBondedActive(pin)) return; 136 | 137 | /* Turn off PWM if applicable */ 138 | 139 | // If the pin that support PWM output, we need to turn it off 140 | // before doing a digital write. 141 | turnOffPWM(pin); 142 | 143 | /* Assuming the direction is already output !! */ 144 | 145 | /* Get port */ 146 | PORT_t *port = digitalPinToPortStruct(pin); 147 | 148 | /* Output direction */ 149 | if(port->DIR & bit_mask){ 150 | 151 | /* Set output to value */ 152 | if (val == LOW) { /* If LOW */ 153 | port->OUTCLR = bit_mask; 154 | 155 | } else if (val == CHANGE) { /* If TOGGLE */ 156 | port->OUTTGL = bit_mask; 157 | /* If HIGH OR > TOGGLE */ 158 | } else { 159 | port->OUTSET = bit_mask; 160 | } 161 | 162 | /* Input direction */ 163 | } else { 164 | /* Old implementation has side effect when pin set as input - 165 | pull up is enabled if this function is called. 166 | Should we purposely implement this side effect? 167 | */ 168 | 169 | /* Get bit position for getting pin ctrl reg */ 170 | uint8_t bit_pos = digitalPinToBitPosition(pin); 171 | 172 | /* Calculate where pin control register is */ 173 | volatile uint8_t* pin_ctrl_reg = getPINnCTRLregister(port, bit_pos); 174 | 175 | /* Save system status and disable interrupts */ 176 | uint8_t status = SREG; 177 | cli(); 178 | 179 | if(val == LOW){ 180 | /* Disable pullup */ 181 | *pin_ctrl_reg &= ~PORT_PULLUPEN_bm; 182 | 183 | } else { 184 | /* Enable pull-up */ 185 | *pin_ctrl_reg |= PORT_PULLUPEN_bm; 186 | } 187 | 188 | /* Restore system status */ 189 | SREG = status; 190 | } 191 | 192 | } 193 | 194 | PinStatus digitalRead(uint8_t pin) 195 | { 196 | /* Get bit mask and check valid pin */ 197 | uint8_t bit_mask = digitalPinToBitMask(pin); 198 | if(bit_mask == NOT_A_PIN || isDoubleBondedActive(pin)) return LOW; 199 | 200 | // If the pin that support PWM output, we need to turn it off 201 | // before getting a digital reading. 202 | turnOffPWM(pin); 203 | 204 | /* Get port and check valid port */ 205 | PORT_t *port = digitalPinToPortStruct(pin); 206 | 207 | /* Read pin value from PORTx.IN register */ 208 | if(port->IN & bit_mask){ 209 | return HIGH; 210 | } else { 211 | return LOW; 212 | } 213 | return LOW; 214 | } 215 | -------------------------------------------------------------------------------- /cores/arduino/wiring_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_private.h - Internal header file. 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #ifndef WiringPrivate_h 24 | #define WiringPrivate_h 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "Arduino.h" 32 | 33 | #ifdef __cplusplus 34 | extern "C"{ 35 | #endif 36 | 37 | uint32_t countPulseASM(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops); 38 | 39 | typedef void (*voidFuncPtr)(void); 40 | 41 | #ifdef __cplusplus 42 | } // extern "C" 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /cores/arduino/wiring_pulse.S: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_pulse.s - pulseInASM() function in different flavours 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2014 Martino Facchin 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | /* 24 | * The following routine was generated by avr-gcc 4.8.3 with the following parameters 25 | * -gstabs -Wa,-ahlmsd=output.lst -dp -fverbose-asm -O2 26 | * on the original C function 27 | * 28 | * unsigned long pulseInSimpl(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops) 29 | * { 30 | * unsigned long width = 0; 31 | * // wait for any previous pulse to end 32 | * while ((*port & bit) == stateMask) 33 | * if (--maxloops == 0) 34 | * return 0; 35 | * 36 | * // wait for the pulse to start 37 | * while ((*port & bit) != stateMask) 38 | * if (--maxloops == 0) 39 | * return 0; 40 | * 41 | * // wait for the pulse to stop 42 | * while ((*port & bit) == stateMask) { 43 | * if (++width == maxloops) 44 | * return 0; 45 | * } 46 | * return width; 47 | * } 48 | * 49 | * some compiler outputs were removed but the rest of the code is untouched 50 | */ 51 | 52 | #include 53 | 54 | .section .text 55 | 56 | .global countPulseASM 57 | 58 | countPulseASM: 59 | 60 | .LM0: 61 | .LFBB1: 62 | push r12 ; ; 130 pushqi1/1 [length = 1] 63 | push r13 ; ; 131 pushqi1/1 [length = 1] 64 | push r14 ; ; 132 pushqi1/1 [length = 1] 65 | push r15 ; ; 133 pushqi1/1 [length = 1] 66 | push r16 ; ; 134 pushqi1/1 [length = 1] 67 | push r17 ; ; 135 pushqi1/1 [length = 1] 68 | /* prologue: function */ 69 | /* frame size = 0 */ 70 | /* stack size = 6 */ 71 | .L__stack_usage = 6 72 | mov r30,r24 ; port, port ; 2 *movhi/1 [length = 2] 73 | mov r31,r25 ; port, port 74 | /* unsigned long width = 0; 75 | *** // wait for any previous pulse to end 76 | *** while ((*port & bit) == stateMask) 77 | */ 78 | .LM1: 79 | rjmp .L2 ; ; 181 jump [length = 1] 80 | .L4: 81 | /* if (--maxloops == 0) */ 82 | .LM2: 83 | subi r16,1 ; maxloops, ; 17 addsi3/2 [length = 4] 84 | sbc r17, r1 ; maxloops 85 | sbc r18, r1 ; maxloops 86 | sbc r19, r1 ; maxloops 87 | breq .L13 ; , ; 19 branch [length = 1] 88 | .L2: 89 | /* if (--maxloops == 0) */ 90 | .LM3: 91 | ld r25,Z ; D.1554, *port_7(D) ; 22 movqi_insn/4 [length = 1] 92 | and r25,r22 ; D.1554, bit ; 24 andqi3/1 [length = 1] 93 | cp r25,r20 ; D.1554, stateMask ; 25 *cmpqi/2 [length = 1] 94 | breq .L4 ; , ; 26 branch [length = 1] 95 | rjmp .L6 ; ; 184 jump [length = 1] 96 | .L7: 97 | /* return 0; 98 | *** 99 | *** // wait for the pulse to start 100 | *** while ((*port & bit) != stateMask) 101 | *** if (--maxloops == 0) 102 | */ 103 | .LM4: 104 | subi r16,1 ; maxloops, ; 31 addsi3/2 [length = 4] 105 | sbc r17, r1 ; maxloops 106 | sbc r18, r1 ; maxloops 107 | sbc r19, r1 ; maxloops 108 | breq .L13 ; , ; 33 branch [length = 1] 109 | .L6: 110 | /* if (--maxloops == 0) */ 111 | .LM5: 112 | ld r25,Z ; D.1554, *port_7(D) ; 41 movqi_insn/4 [length = 1] 113 | and r25,r22 ; D.1554, bit ; 43 andqi3/1 [length = 1] 114 | cpse r25,r20 ; D.1554, stateMask ; 44 enable_interrupt-3 [length = 1] 115 | rjmp .L7 ; 116 | mov r12, r1 ; width ; 7 *movsi/2 [length = 4] 117 | mov r13, r1 ; width 118 | mov r14, r1 ; width 119 | mov r15, r1 ; width 120 | rjmp .L9 ; ; 186 jump [length = 1] 121 | .L10: 122 | /* return 0; 123 | *** 124 | *** // wait for the pulse to stop 125 | *** while ((*port & bit) == stateMask) { 126 | *** if (++width == maxloops) 127 | */ 128 | .LM6: 129 | ldi r24,-1 ; , ; 50 addsi3/3 [length = 5] 130 | sub r12,r24 ; width, 131 | sbc r13,r24 ; width, 132 | sbc r14,r24 ; width, 133 | sbc r15,r24 ; width, 134 | cp r16,r12 ; maxloops, width ; 51 *cmpsi/2 [length = 4] 135 | cpc r17,r13 ; maxloops, width 136 | cpc r18,r14 ; maxloops, width 137 | cpc r19,r15 ; maxloops, width 138 | breq .L13 ; , ; 52 branch [length = 1] 139 | .L9: 140 | /* if (++width == maxloops) */ 141 | .LM7: 142 | ld r24,Z ; D.1554, *port_7(D) ; 60 movqi_insn/4 [length = 1] 143 | and r24,r22 ; D.1554, bit ; 62 andqi3/1 [length = 1] 144 | cp r24,r20 ; D.1554, stateMask ; 63 *cmpqi/2 [length = 1] 145 | breq .L10 ; , ; 64 branch [length = 1] 146 | /* return 0; 147 | *** } 148 | *** return width; 149 | */ 150 | .LM8: 151 | mov r22,r12 ; D.1553, width ; 108 movqi_insn/1 [length = 1] 152 | mov r23,r13 ; D.1553, width ; 109 movqi_insn/1 [length = 1] 153 | mov r24,r14 ; D.1553, width ; 110 movqi_insn/1 [length = 1] 154 | mov r25,r15 ; D.1553, width ; 111 movqi_insn/1 [length = 1] 155 | /* epilogue start */ 156 | .LM9: 157 | pop r17 ; ; 171 popqi [length = 1] 158 | pop r16 ; ; 172 popqi [length = 1] 159 | pop r15 ; ; 173 popqi [length = 1] 160 | pop r14 ; ; 174 popqi [length = 1] 161 | pop r13 ; ; 175 popqi [length = 1] 162 | pop r12 ; ; 176 popqi [length = 1] 163 | ret ; 177 return_from_epilogue [length = 1] 164 | .L13: 165 | .LM10: 166 | ldi r22,0 ; D.1553 ; 120 movqi_insn/1 [length = 1] 167 | ldi r23,0 ; D.1553 ; 121 movqi_insn/1 [length = 1] 168 | ldi r24,0 ; D.1553 ; 122 movqi_insn/1 [length = 1] 169 | ldi r25,0 ; D.1553 ; 123 movqi_insn/1 [length = 1] 170 | /* epilogue start */ 171 | .LM11: 172 | pop r17 ; ; 138 popqi [length = 1] 173 | pop r16 ; ; 139 popqi [length = 1] 174 | pop r15 ; ; 140 popqi [length = 1] 175 | pop r14 ; ; 141 popqi [length = 1] 176 | pop r13 ; ; 142 popqi [length = 1] 177 | pop r12 ; ; 143 popqi [length = 1] 178 | ret ; 144 return_from_epilogue [length = 1] 179 | -------------------------------------------------------------------------------- /cores/arduino/wiring_pulse.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_pulse.c - pulseIn() function 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #include "wiring_private.h" 24 | #include "pins_arduino.h" 25 | 26 | /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH 27 | * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds 28 | * to 3 minutes in length, but must be called at least a few dozen microseconds 29 | * before the start of the pulse. 30 | * 31 | * This function performs better with short pulses in noInterrupt() context 32 | */ 33 | unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) 34 | { 35 | // cache the port and bit of the pin in order to speed up the 36 | // pulse width measuring loop and achieve finer resolution. calling 37 | // digitalRead() instead yields much coarser resolution. 38 | uint8_t bit = digitalPinToBitMask(pin); 39 | uint8_t port = digitalPinToPort(pin); 40 | uint8_t stateMask = (state ? bit : 0); 41 | 42 | // convert the timeout from microseconds to a number of times through 43 | // the initial loop; it takes approximately 16 clock cycles per iteration 44 | unsigned long maxloops = microsecondsToClockCycles(timeout)/12; 45 | 46 | unsigned long width = countPulseASM(portInputRegister(port), bit, stateMask, maxloops); 47 | 48 | // prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out 49 | if (width) 50 | return clockCyclesToMicroseconds(width * 16 + 16); 51 | else 52 | return 0; 53 | } 54 | 55 | /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH 56 | * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds 57 | * to 3 minutes in length, but must be called at least a few dozen microseconds 58 | * before the start of the pulse. 59 | * 60 | * ATTENTION: 61 | * this function relies on micros() so cannot be used in noInterrupt() context 62 | */ 63 | unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) 64 | { 65 | // cache the port and bit of the pin in order to speed up the 66 | // pulse width measuring loop and achieve finer resolution. calling 67 | // digitalRead() instead yields much coarser resolution. 68 | uint8_t bit = digitalPinToBitMask(pin); 69 | uint8_t port = digitalPinToPort(pin); 70 | uint8_t stateMask = (state ? bit : 0); 71 | 72 | unsigned long startMicros = micros(); 73 | 74 | // wait for any previous pulse to end 75 | while ((*portInputRegister(port) & bit) == stateMask) { 76 | if (micros() - startMicros > timeout) 77 | return 0; 78 | } 79 | 80 | // wait for the pulse to start 81 | while ((*portInputRegister(port) & bit) != stateMask) { 82 | if (micros() - startMicros > timeout) 83 | return 0; 84 | } 85 | 86 | unsigned long start = micros(); 87 | // wait for the pulse to stop 88 | while ((*portInputRegister(port) & bit) == stateMask) { 89 | if (micros() - startMicros > timeout) 90 | return 0; 91 | } 92 | return micros() - start; 93 | } -------------------------------------------------------------------------------- /cores/arduino/wiring_shift.c: -------------------------------------------------------------------------------- 1 | /* 2 | wiring_shift.c - shiftOut() function 3 | Part of Arduino - http://www.arduino.cc/ 4 | 5 | Copyright (c) 2005-2006 David A. Mellis 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General 18 | Public License along with this library; if not, write to the 19 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, 20 | Boston, MA 02111-1307 USA 21 | */ 22 | 23 | #include 24 | 25 | uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, BitOrder bitOrder) { 26 | uint8_t value = 0; 27 | uint8_t i; 28 | 29 | for (i = 0; i < 8; ++i) { 30 | digitalWrite(clockPin, HIGH); 31 | if (bitOrder == LSBFIRST) 32 | value |= digitalRead(dataPin) << i; 33 | else 34 | value |= digitalRead(dataPin) << (7 - i); 35 | digitalWrite(clockPin, LOW); 36 | } 37 | return value; 38 | } 39 | 40 | void shiftOut(uint8_t dataPin, uint8_t clockPin, BitOrder bitOrder, uint8_t val) 41 | { 42 | uint8_t i; 43 | 44 | for (i = 0; i < 8; i++) { 45 | if (bitOrder == LSBFIRST) 46 | digitalWrite(dataPin, !!(val & (1 << i))); 47 | else 48 | digitalWrite(dataPin, !!(val & (1 << (7 - i)))); 49 | 50 | digitalWrite(clockPin, HIGH); 51 | digitalWrite(clockPin, LOW); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /cores/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ########################################################################## 2 | 3 | cmake_minimum_required(VERSION 3.0) 4 | 5 | ########################################################################## 6 | 7 | include_directories(include) 8 | include_directories(external/libvireg/include) 9 | include_directories(external/catch/v.2.7.0/include) 10 | 11 | ########################################################################## 12 | 13 | set(CMAKE_CXX_STANDARD 11) 14 | 15 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) 16 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) 17 | 18 | ########################################################################## 19 | 20 | add_subdirectory(external/libvireg) # For building libvireg 21 | 22 | ########################################################################## 23 | 24 | set(TEST_TARGET testArduinoCore-megaavr) 25 | 26 | set(TEST_SRCS 27 | src/test_main.cpp 28 | ../arduino/NANO_compat.cpp 29 | ) 30 | 31 | ########################################################################## 32 | 33 | add_definitions(-DHOST_BUILD) 34 | add_definitions(-DAVR_NANO_4809_328MODE) 35 | 36 | ########################################################################## 37 | 38 | add_executable(${TEST_TARGET} ${TEST_SRCS}) 39 | target_link_libraries(${TEST_TARGET} vireg) 40 | 41 | ########################################################################## 42 | 43 | add_custom_command( 44 | TARGET ${TEST_TARGET} POST_BUILD 45 | COMMENT "Executing unit tests" 46 | COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${TEST_TARGET}" 47 | ) 48 | 49 | ########################################################################## 50 | -------------------------------------------------------------------------------- /cores/test/README.md: -------------------------------------------------------------------------------- 1 | Compilation/Execution of unit tests 2 | =================================== 3 | Unit tests are automatically executed as a post-build step. 4 | ```bash 5 | mkdir build && cd build 6 | cmake .. 7 | make 8 | ``` 9 | -------------------------------------------------------------------------------- /cores/test/include/Arduino.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2019 Arduino. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | See the GNU Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #ifndef ARDUINO_H_ 20 | #define ARDUINO_H_ 21 | 22 | /* This is a Arduino.h mockup for test purposes only */ 23 | 24 | #include 25 | 26 | #endif /* ARDUINO_H_ */ 27 | -------------------------------------------------------------------------------- /drivers/atmelinf.cat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoCore-megaavr/5e639ee40afa693354d3d056ba7fb795a8948c11/drivers/atmelinf.cat -------------------------------------------------------------------------------- /drivers/dpinst-amd64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoCore-megaavr/5e639ee40afa693354d3d056ba7fb795a8948c11/drivers/dpinst-amd64.exe -------------------------------------------------------------------------------- /drivers/dpinst-x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoCore-megaavr/5e639ee40afa693354d3d056ba7fb795a8948c11/drivers/dpinst-x86.exe -------------------------------------------------------------------------------- /drivers/mEDBG_Virtual_Com_Port.inf: -------------------------------------------------------------------------------- 1 | ; Windows 2000, XP & Vista setup File for XPLAINED Boards. 2 | 3 | ; Copyright (c) 2000 Microsoft Corporation 4 | ; Copyright (C) 2007 ATMEL, Inc. 5 | 6 | [Version] 7 | Signature="$Windows NT$" 8 | Class=Ports 9 | ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} 10 | CatalogFile=atmelinf.cat 11 | Provider=%ATMEL% 12 | DriverVer=06/14/2013,6.0.0.1 13 | 14 | ;---------------------------------------------------------- 15 | ; Targets 16 | ;---------------------------------------------------------- 17 | [Manufacturer] 18 | %ATMEL%=ATMEL, NTamd64 19 | 20 | [ATMEL] 21 | %ATMEL_CDC%=Reader, USB\VID_03EB&PID_2145&MI_01 22 | %ARDUINO_NANO_EVERY_CDC%=Reader, USB\VID_2341&PID_0058 23 | 24 | [ATMEL.NTamd64] 25 | %ATMEL_CDC%=DriverInstall, USB\VID_03EB&PID_2145&MI_01 26 | %ARDUINO_NANO_EVERY_CDC%=Reader, USB\VID_2341&PID_0058 27 | 28 | 29 | ;---------------------------------------------------------- 30 | ; Windows 2K, XP, and Vista32 31 | ;---------------------------------------------------------- 32 | [DestinationDirs] 33 | DefaultDestDir=12 34 | FakeModemCopyFileSection=12 35 | 36 | [Reader.NT] 37 | include=mdmcpq.inf 38 | CopyFiles=FakeModemCopyFileSection 39 | AddReg=Reader.NT.AddReg 40 | 41 | [Reader.NT.AddReg] 42 | HKR,,DevLoader,,*ntkern 43 | HKR,,NTMPDriver,,usbser.sys 44 | HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" 45 | HKR,,Properties, 1, 80,01,00,00, ff,00,00,00, ff,00,00,00, 07,00,00,00, 0f,00,00,00, f7,03,00,00, 40,4b,4c,00, 40,4b,4c,00 46 | 47 | [Reader.NT.Services] 48 | AddService = usbser, 0x00000002, Service_Inst 49 | 50 | [Service_Inst] 51 | DisplayName = %Serial.SvcDesc% 52 | ServiceType = 1 ; SERVICE_KERNEL_DRIVER 53 | StartType = 3 ; SERVICE_DEMAND_START 54 | ErrorControl = 1 ; SERVICE_ERROR_NORMAL 55 | ServiceBinary = %12%\usbser.sys 56 | LoadOrderGroup = Base 57 | 58 | 59 | ;---------------------------------------------------------- 60 | ; Vista64 61 | ;---------------------------------------------------------- 62 | 63 | [DriverInstall.NTamd64] 64 | include=mdmcpq.inf 65 | CopyFiles=FakeModemCopyFileSection 66 | AddReg=DriverInstall.NTamd64.AddReg 67 | 68 | [DriverInstall.NTamd64.AddReg] 69 | HKR,,DevLoader,,*ntkern 70 | HKR,,NTMPDriver,,usbser.sys 71 | HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" 72 | HKR,,Properties, 1, 80,01,00,00, ff,00,00,00, ff,00,00,00, 07,00,00,00, 0f,00,00,00, f7,03,00,00, 40,4b,4c,00, 40,4b,4c,00 73 | 74 | [DriverInstall.NTamd64.Services] 75 | AddService=usbser, 0x00000002, DriverService.NTamd64 76 | 77 | [DriverService.NTamd64] 78 | DisplayName=%Serial.SvcDesc% 79 | ServiceType=1 80 | StartType=3 81 | ErrorControl=1 82 | ServiceBinary=%12%\usbser.sys 83 | 84 | ;---------------------------------------------------------- 85 | ; String 86 | ;---------------------------------------------------------- 87 | 88 | [Strings] 89 | ATMEL = "Atmel Corp." 90 | ATMEL_CDC = "mEDBG Virtual COM Port" 91 | ARDUINO_NANO_EVERY_CDC = "Arduino NANO Every" 92 | Serial.SvcDesc = "USB Serial emulation driver" 93 | 94 | -------------------------------------------------------------------------------- /extras/pack.hourlybuild.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | # pack.*.bash - Bash script to help packaging avr core releases. 4 | # Copyright (c) 2015 Arduino LLC. All right reserved. 5 | # 6 | # This library is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU Lesser General Public 8 | # License as published by the Free Software Foundation; either 9 | # version 2.1 of the License, or (at your option) any later version. 10 | # 11 | # This library is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | # Lesser General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this library; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | BUILD_NUMBER=$1 21 | CURR_TIME=`date "+%Y-%m-%d %H:%M"` 22 | CURR_TIME_SED=`date "+%Y\\-%m\\-%d %H:%M"` 23 | VERSION=9.9.9-Hourly 24 | 25 | PWD=`pwd` 26 | FOLDERNAME=`basename $PWD` 27 | THIS_SCRIPT_NAME=`basename $0` 28 | FILENAME=package_avr-hourly-b${BUILD_NUMBER}.tar.bz2 29 | 30 | rm -f $FILENAME 31 | 32 | # Change name in platform.txt 33 | sed -i "s/name=.*/name=SAMD Hourly Build ${BUILD_NUMBER} (${CURR_TIME})/" platform.txt 34 | 35 | cd .. 36 | tar --transform "s|$FOLDERNAME|avr-hourly_b${BUILD_NUMBER}|g" --exclude=extras/** --exclude=.git* --exclude=.idea -cjf $FILENAME $FOLDERNAME 37 | cd - 38 | 39 | mv ../$FILENAME . 40 | 41 | CHKSUM=`sha256sum $FILENAME | awk '{ print $1 }'` 42 | SIZE=`wc -c $FILENAME | awk '{ print $1 }'` 43 | 44 | cat extras/package_index.json.Hourly.template | 45 | sed "s/%%BUILD_NUMBER%%/${BUILD_NUMBER}/" | 46 | sed "s/%%CURR_TIME%%/${CURR_TIME_SED}/" | 47 | sed "s/%%VERSION%%/${VERSION}/" | 48 | sed "s/%%FILENAME%%/${FILENAME}/" | 49 | sed "s/%%CHECKSUM%%/${CHKSUM}/" | 50 | sed "s/%%SIZE%%/${SIZE}/" > package_avr-hourly-build_index.json 51 | 52 | -------------------------------------------------------------------------------- /extras/pack.pullrequest.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | # pack.*.bash - Bash script to help packaging avr core releases. 4 | # Copyright (c) 2015 Arduino LLC. All right reserved. 5 | # 6 | # This library is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU Lesser General Public 8 | # License as published by the Free Software Foundation; either 9 | # version 2.1 of the License, or (at your option) any later version. 10 | # 11 | # This library is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | # Lesser General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this library; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | PR_NUMBER=$1 21 | BUILD_NUMBER=$2 22 | VERSION=`grep version= platform.txt | sed 's/version=//g'` 23 | 24 | PWD=`pwd` 25 | FOLDERNAME=`basename $PWD` 26 | THIS_SCRIPT_NAME=`basename $0` 27 | FILENAME=package_avr-b${BUILD_NUMBER}.tar.bz2 28 | 29 | rm -f $FILENAME 30 | 31 | # Change name in platform.txt 32 | sed -i "s/name=.*/name=SAMD Pull request #${PR_NUMBER} (Build ${BUILD_NUMBER})/" platform.txt 33 | 34 | cd .. 35 | tar --transform "s|$FOLDERNAME|avr-PR${PR_NUMBER}_b${BUILD_NUMBER}|g" --exclude=extras/** --exclude=.git* --exclude=.idea -cjf $FILENAME $FOLDERNAME 36 | cd - 37 | 38 | mv ../$FILENAME . 39 | 40 | CHKSUM=`sha256sum $FILENAME | awk '{ print $1 }'` 41 | SIZE=`wc -c $FILENAME | awk '{ print $1 }'` 42 | 43 | cat extras/package_index.json.PR.template | 44 | sed s/%%PR_NUMBER%%/${PR_NUMBER}/ | 45 | sed s/%%BUILD_NUMBER%%/${BUILD_NUMBER}/ | 46 | sed s/%%VERSION%%/${VERSION}-build-${BUILD_NUMBER}/ | 47 | sed s/%%FILENAME%%/${FILENAME}/ | 48 | sed s/%%CHECKSUM%%/${CHKSUM}/ | 49 | sed s/%%SIZE%%/${SIZE}/ > package_avr-b${BUILD_NUMBER}_index.json 50 | 51 | -------------------------------------------------------------------------------- /extras/pack.release.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | # pack.*.bash - Bash script to help packaging samd core releases. 4 | # Copyright (c) 2015 Arduino LLC. All right reserved. 5 | # 6 | # This library is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU Lesser General Public 8 | # License as published by the Free Software Foundation; either 9 | # version 2.1 of the License, or (at your option) any later version. 10 | # 11 | # This library is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | # Lesser General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU Lesser General Public 17 | # License along with this library; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | 20 | # Version check removed because version string passed from jenkins was incorrect 21 | VERSION_FROM_TAG=$1 22 | CORE_NAME=$2 23 | echo $VERSION_FROM_TAG 24 | echo $CORE_NAME 25 | VERSION=`grep version= platform.txt | sed 's/version=//g'` 26 | echo $VERSION 27 | 28 | if [ $VERSION != $VERSION_FROM_TAG ]; then 29 | exit 0 30 | fi 31 | 32 | PWD=`pwd` 33 | FOLDERNAME=`basename $PWD` 34 | THIS_SCRIPT_NAME=`basename $0` 35 | FILENAME=core-$CORE_NAME-$VERSION.tar.bz2 36 | echo $FILENAME 37 | 38 | rm -f *.tar.bz2 39 | rm -f *.json 40 | 41 | cd .. 42 | tar --exclude=extras/** --exclude=.git* --exclude=.idea -cjhf $FILENAME $FOLDERNAME 43 | cd - 44 | 45 | mv ../$FILENAME . 46 | 47 | CHKSUM=`sha256sum $FILENAME | awk '{ print $1 }'` 48 | SIZE=`wc -c $FILENAME | awk '{ print $1 }'` 49 | 50 | cat extras/package_index.json.NewTag.template | 51 | # sed "s/%%BUILD_NUMBER%%/${BUILD_NUMBER}/" | 52 | # sed "s/%%CURR_TIME%%/${CURR_TIME_SED}/" | 53 | sed "s/%%VERSION%%/${VERSION}/" | 54 | sed "s/%%FILENAME%%/${FILENAME}/" | 55 | sed "s/%%CHECKSUM%%/${CHKSUM}/" | 56 | sed "s/%%SIZE%%/${SIZE}/" > package_${CORE_NAME}_${VERSION}_index.json -------------------------------------------------------------------------------- /extras/package_index.json.Hourly.template: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "arduino-beta", 5 | "maintainer": "Arduino Betatesting", 6 | "websiteURL": "http://www.arduino.cc/", 7 | "email": "packages@arduino.cc", 8 | "help": { 9 | "online": "http://www.arduino.cc/en/Reference/HomePage" 10 | }, 11 | "platforms": [ 12 | { 13 | "name": "Arduino AVR core - Hourly build", 14 | "architecture": "avr", 15 | "version": "%%VERSION%%", 16 | "category": "Arduino", 17 | "url": "http://downloads.arduino.cc/Hourly/avr/%%FILENAME%%", 18 | "archiveFileName": "%%FILENAME%%", 19 | "checksum": "SHA-256:%%CHECKSUM%%", 20 | "size": "%%SIZE%%", 21 | "boards": [ 22 | {"name": "Arduino Yún"}, 23 | {"name": "Arduino/Genuino Uno"}, 24 | {"name": "Arduino Uno WiFi"}, 25 | {"name": "Arduino Diecimila"}, 26 | {"name": "Arduino Nano"}, 27 | {"name": "Arduino/Genuino Mega"}, 28 | {"name": "Arduino MegaADK"}, 29 | {"name": "Arduino Leonardo"}, 30 | {"name": "Arduino Leonardo Ethernet"}, 31 | {"name": "Arduino/Genuino Micro"}, 32 | {"name": "Arduino Esplora"}, 33 | {"name": "Arduino Mini"}, 34 | {"name": "Arduino Ethernet"}, 35 | {"name": "Arduino Fio"}, 36 | {"name": "Arduino BT"}, 37 | {"name": "Arduino LilyPadUSB"}, 38 | {"name": "Arduino Lilypad"}, 39 | {"name": "Arduino Pro"}, 40 | {"name": "Arduino ATMegaNG"}, 41 | {"name": "Arduino Robot Control"}, 42 | {"name": "Arduino Robot Motor"}, 43 | {"name": "Arduino Gemma"}, 44 | {"name": "Adafruit Circuit Playground"}, 45 | {"name": "Arduino Yún Mini"}, 46 | {"name": "Arduino Industrial 101"}, 47 | {"name": "Linino One"} 48 | ], 49 | "toolsDependencies": [ 50 | { 51 | "packager": "arduino", 52 | "name": "avr-gcc", 53 | "version": "4.9.2-atmel3.5.4-arduino2" 54 | }, 55 | { 56 | "packager": "arduino", 57 | "name": "avrdude", 58 | "version": "6.3.0-arduino9" 59 | }, 60 | { 61 | "packager": "arduino", 62 | "name": "arduinoOTA", 63 | "version": "1.1.1" 64 | } 65 | ] 66 | } 67 | ], 68 | "tools": [ 69 | ] 70 | } 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /extras/package_index.json.NewTag.template: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "arduino", 5 | "maintainer": "Arduino Betatesting", 6 | "websiteURL": "http://www.arduino.cc/", 7 | "email": "packages@arduino.cc", 8 | "help": { 9 | "online": "http://www.arduino.cc/en/Reference/HomePage" 10 | }, 11 | "platforms": [ 12 | { 13 | "name": "Arduino megaAVR Boards - Pre-release", 14 | "architecture": "megaavr", 15 | "version": "%%VERSION%%", 16 | "category": "Arduino", 17 | "url": "http://downloads.arduino.cc/cores/staging/%%FILENAME%%", 18 | "archiveFileName": "%%FILENAME%%", 19 | "checksum": "SHA-256:%%CHECKSUM%%", 20 | "size": "%%SIZE%%", 21 | "help": { 22 | "online": "https://github.com/arduino/ArduinoCore-megaavr/issues" 23 | }, 24 | "boards": [ 25 | { 26 | "name": "Arduino UNO WiFi Rev2" 27 | }, 28 | { 29 | "name": "Arduino Nano Every" 30 | } 31 | ], 32 | "toolsDependencies": [ 33 | { 34 | "packager": "arduino", 35 | "name": "avr-gcc", 36 | "version": "7.3.0-atmel3.6.1-arduino5" 37 | }, 38 | { 39 | "packager": "arduino", 40 | "name": "avrdude", 41 | "version": "6.3.0-arduino17" 42 | }, 43 | { 44 | "packager": "arduino", 45 | "name": "arduinoOTA", 46 | "version": "1.3.0" 47 | } 48 | ] 49 | } 50 | ], 51 | "tools": [] 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /extras/package_index.json.PR.template: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | { 4 | "name": "arduino-beta", 5 | "maintainer": "Arduino Betatesting", 6 | "websiteURL": "http://www.arduino.cc/", 7 | "email": "packages@arduino.cc", 8 | "help": { 9 | "online": "http://www.arduino.cc/en/Reference/HomePage" 10 | }, 11 | "platforms": [ 12 | { 13 | "name": "Arduino AVR core - Pull request #%%PR_NUMBER%% (build %%BUILD_NUMBER%%)", 14 | "architecture": "avr", 15 | "version": "%%VERSION%%", 16 | "category": "Arduino", 17 | "url": "http://downloads.arduino.cc/PR/a/%%FILENAME%%", 18 | "archiveFileName": "%%FILENAME%%", 19 | "checksum": "SHA-256:%%CHECKSUM%%", 20 | "size": "%%SIZE%%", 21 | "boards": [ 22 | {"name": "Arduino Yún"}, 23 | {"name": "Arduino/Genuino Uno"}, 24 | {"name": "Arduino Uno WiFi"}, 25 | {"name": "Arduino Diecimila"}, 26 | {"name": "Arduino Nano"}, 27 | {"name": "Arduino/Genuino Mega"}, 28 | {"name": "Arduino MegaADK"}, 29 | {"name": "Arduino Leonardo"}, 30 | {"name": "Arduino Leonardo Ethernet"}, 31 | {"name": "Arduino/Genuino Micro"}, 32 | {"name": "Arduino Esplora"}, 33 | {"name": "Arduino Mini"}, 34 | {"name": "Arduino Ethernet"}, 35 | {"name": "Arduino Fio"}, 36 | {"name": "Arduino BT"}, 37 | {"name": "Arduino LilyPadUSB"}, 38 | {"name": "Arduino Lilypad"}, 39 | {"name": "Arduino Pro"}, 40 | {"name": "Arduino ATMegaNG"}, 41 | {"name": "Arduino Robot Control"}, 42 | {"name": "Arduino Robot Motor"}, 43 | {"name": "Arduino Gemma"}, 44 | {"name": "Adafruit Circuit Playground"}, 45 | {"name": "Arduino Yún Mini"}, 46 | {"name": "Arduino Industrial 101"}, 47 | {"name": "Linino One"} 48 | ], 49 | "toolsDependencies": [ 50 | { 51 | "packager": "arduino", 52 | "name": "avr-gcc", 53 | "version": "4.9.2-atmel3.5.4-arduino2" 54 | }, 55 | { 56 | "packager": "arduino", 57 | "name": "avrdude", 58 | "version": "6.3.0-arduino9" 59 | }, 60 | { 61 | "packager": "arduino", 62 | "name": "arduinoOTA", 63 | "version": "1.1.1" 64 | } 65 | ] 66 | } 67 | ], 68 | "tools": [ 69 | ] 70 | } 71 | ] 72 | } 73 | -------------------------------------------------------------------------------- /firmwares/MuxTO/JICE_io.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | stk_io.cpp 3 | 4 | Created: 18-11-2017 15:20:29 5 | Author: JMR_2 6 | */ 7 | 8 | // Includes 9 | #include 10 | #include "JICE_io.h" 11 | #include "sys.h" 12 | 13 | namespace { 14 | // *** Baud rate lookup table for UBRR0 register *** 15 | // Indexed by valid values for PARAM_BAUD_RATE_VAL (defined in JTAG2.h) 16 | uint16_t baud_tbl[8] = {baud(2400), baud(4800), baud(9600), baud(19200), baud(38400), baud(57600), baud(115200), baud(14400)}; 17 | } 18 | 19 | // Functions 20 | uint8_t JICE_io::put(char c) { 21 | SERIALCOM.write(c); 22 | return c; 23 | } 24 | 25 | uint8_t JICE_io::get(void) { 26 | //while (!SERIALCOM.available()); 27 | uint8_t c = SERIALCOM.read(); 28 | return c; 29 | } 30 | 31 | void JICE_io::init(void) { 32 | SERIALCOM.begin(115200); 33 | } 34 | 35 | void JICE_io::flush(void) { 36 | SERIALCOM.flush(); 37 | } 38 | 39 | void JICE_io::set_baud(JTAG2::baud_rate rate) { 40 | 41 | } 42 | -------------------------------------------------------------------------------- /firmwares/MuxTO/JICE_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | stk_io.h 3 | 4 | Created: 18-11-2017 14:55:53 5 | Author: JMR_2 6 | */ 7 | 8 | 9 | #ifndef JICE_IO_H_ 10 | #define JICE_IO_H_ 11 | 12 | #include 13 | #include "JTAG2.h" 14 | 15 | #warning "modify this to match your USB serial port name" 16 | #define SERIALCOM SerialUSB 17 | 18 | namespace JICE_io { 19 | // Function prototypes 20 | uint8_t put(char c); 21 | uint8_t get(void); 22 | void init(void); 23 | void flush(void); 24 | void set_baud(JTAG2::baud_rate rate); 25 | } 26 | 27 | #endif /* JICE_IO_H_ */ 28 | -------------------------------------------------------------------------------- /firmwares/MuxTO/JTAG2.h: -------------------------------------------------------------------------------- 1 | /* 2 | packet.h 3 | 4 | Created: 12-11-2017 11:10:31 5 | Author: JMR_2 6 | */ 7 | 8 | 9 | #ifndef JTAG2_H_ 10 | #define JTAG2_H_ 11 | 12 | #include 13 | #include "sys.h" 14 | 15 | namespace JTAG2 { 16 | 17 | // *** Parameter IDs *** 18 | enum parameter { 19 | PARAM_HW_VER = 0x01, 20 | PARAM_FW_VER = 0x02, 21 | PARAM_EMU_MODE = 0x03, 22 | PARAM_BAUD_RATE = 0x05, 23 | PARAM_VTARGET = 0x06 24 | }; 25 | 26 | // *** valid values for PARAM_BAUD_RATE_VAL 27 | enum baud_rate { 28 | baud_2400 = 0x01, 29 | baud_4800, 30 | baud_9600, 31 | baud_19200, // default 32 | baud_38400, 33 | baud_57600, 34 | baud_115200, 35 | baud_14400 36 | }; 37 | 38 | // *** Parameter Values *** 39 | constexpr uint8_t PARAM_HW_VER_M_VAL = 0x01; 40 | constexpr uint8_t PARAM_HW_VER_S_VAL = 0x01; 41 | constexpr uint8_t PARAM_FW_VER_M_MIN_VAL = 0x07; 42 | constexpr uint8_t PARAM_FW_VER_M_MAJ_VAL = 0x01; 43 | constexpr uint8_t PARAM_FW_VER_S_MIN_VAL = 0x07; 44 | constexpr uint8_t PARAM_FW_VER_S_MAJ_VAL = 0x06; 45 | extern uint8_t PARAM_EMU_MODE_VAL; 46 | extern baud_rate PARAM_BAUD_RATE_VAL; 47 | constexpr uint16_t PARAM_VTARGET_VAL = 5000; 48 | 49 | // *** General command constants *** 50 | enum cmnd { 51 | CMND_SIGN_OFF = 0x00, 52 | CMND_GET_SIGN_ON = 0x01, 53 | CMND_SET_PARAMETER = 0x02, 54 | CMND_GET_PARAMETER = 0x03, 55 | CMND_WRITE_MEMORY = 0x04, 56 | CMND_READ_MEMORY = 0x05, 57 | CMND_GO = 0x08, 58 | CMND_RESET = 0x0b, 59 | CMND_SET_DEVICE_DESCRIPTOR = 0x0c, 60 | CMND_GET_SYNC = 0x0f, 61 | CMND_ENTER_PROGMODE = 0x14, 62 | CMND_LEAVE_PROGMODE = 0x15, 63 | CMND_XMEGA_ERASE = 0x34 64 | }; 65 | // *** JTAG Mk2 Single byte status responses *** 66 | enum response { 67 | // Success 68 | RSP_OK = 0x80, 69 | RSP_PARAMETER = 0x81, 70 | RSP_MEMORY = 0x82, 71 | // Error 72 | RSP_FAILED = 0xA0, 73 | RSP_ILLEGAL_PARAMETER = 0xA1, 74 | RSP_ILLEGAL_MEMORY_TYPE = 0xA2, 75 | RSP_ILLEGAL_MEMORY_RANGE = 0xA3, 76 | RSP_ILLEGAL_MCU_STATE = 0xA5, 77 | RSP_ILLEGAL_VALUE = 0xA6, 78 | RSP_ILLEGAL_BREAKPOINT = 0xA8, 79 | RSP_ILLEGAL_JTAG_ID = 0xA9, 80 | RSP_ILLEGAL_COMMAND = 0xAA, 81 | RSP_NO_TARGET_POWER = 0xAB, 82 | RSP_DEBUGWIRE_SYNC_FAILED = 0xAC, 83 | RSP_ILLEGAL_POWER_STATE = 0xAD 84 | }; 85 | 86 | // *** memory types for CMND_{READ,WRITE}_MEMORY *** 87 | enum mem_type { 88 | MTYPE_IO_SHADOW = 0x30, // cached IO registers? 89 | MTYPE_SRAM = 0x20, // target's SRAM or [ext.] IO registers 90 | MTYPE_EEPROM = 0x22, // EEPROM, what way? 91 | MTYPE_EVENT = 0x60, // ICE event memory 92 | MTYPE_SPM = 0xA0, // flash through LPM/SPM 93 | MTYPE_FLASH_PAGE = 0xB0, // flash in programming mode 94 | MTYPE_EEPROM_PAGE = 0xB1, // EEPROM in programming mode 95 | MTYPE_FUSE_BITS = 0xB2, // fuse bits in programming mode 96 | MTYPE_LOCK_BITS = 0xB3, // lock bits in programming mode 97 | MTYPE_SIGN_JTAG = 0xB4, // signature in programming mode 98 | MTYPE_OSCCAL_BYTE = 0xB5, // osccal cells in programming mode 99 | MTYPE_CAN = 0xB6, // CAN mailbox 100 | MTYPE_FLASH = 0xc0, // xmega (app.) flash 101 | MTYPE_BOOT_FLASH = 0xc1, // xmega boot flash 102 | MTYPE_EEPROM_XMEGA = 0xc4, // xmega EEPROM in debug mode 103 | MTYPE_USERSIG = 0xc5, // xmega user signature 104 | MTYPE_PRODSIG = 0xc6 // xmega production signature 105 | }; 106 | 107 | // *** STK500 packet *** 108 | constexpr uint8_t MESSAGE_START = 0x1B; 109 | constexpr int MAX_BODY_SIZE = 450; // Note: should not be reduced to less than 300 bytes. 110 | union __attribute__((packed)) packet_t { 111 | uint8_t raw[6 + MAX_BODY_SIZE]; 112 | struct __attribute__((packed)) { 113 | union { 114 | uint16_t number; 115 | uint8_t number_byte[2]; 116 | }; 117 | union { 118 | uint32_t size; 119 | uint16_t size_word[2]; 120 | uint8_t size_byte[4]; 121 | }; 122 | uint8_t body[MAX_BODY_SIZE]; 123 | }; 124 | } extern packet; 125 | constexpr uint8_t TOKEN = 0x0E; 126 | 127 | // *** Signature response *** 128 | extern uint8_t sgn_resp[29]; 129 | // *** Parameter initialization *** 130 | void init(); 131 | 132 | // *** Packet functions *** 133 | bool receive(); 134 | void answer(); 135 | void delay_exec(); 136 | 137 | // *** Set status function *** 138 | void set_status(uint8_t) __attribute__ ((noinline)); 139 | 140 | // *** General command functions *** 141 | void sign_on(); 142 | void get_parameter(); 143 | void set_parameter(); 144 | void set_device_descriptor(); 145 | 146 | // *** ISP command functions *** 147 | void enter_progmode(); 148 | void leave_progmode(); 149 | void read_signature(); 150 | void read_mem(); 151 | void write_mem(); 152 | void erase(); 153 | } 154 | 155 | 156 | 157 | #endif /* STK_H_ */ 158 | -------------------------------------------------------------------------------- /firmwares/MuxTO/MuxTO.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoCore-megaavr/5e639ee40afa693354d3d056ba7fb795a8948c11/firmwares/MuxTO/MuxTO.bin -------------------------------------------------------------------------------- /firmwares/MuxTO/MuxTO.ino: -------------------------------------------------------------------------------- 1 | /* 2 | j2updi.cpp 3 | 4 | Created: 11-11-2017 22:29:58 5 | Author : JMR_2 6 | Ported to generic Arduino framework by the Arduino Team - 2019 7 | */ 8 | 9 | /* 10 | Compile with 11 | fqbn=arduino:samd:muxto:float=default,config=enabled,clock=internal_usb,timer=timer_732Hz,bootloader=4kb,serial=two_uart,usb=cdc 12 | to obtain the binary for Serial-to-USB converter + UPDI programmer on the Arduino Nano Every (MuxTO for brevity) 13 | 14 | Since the "sketch" is (almost) pure Arduino it can be ported easily to other architectures (on chips with two serial ports) 15 | The bitbanged UPDI layer is being reworked to make it compatible with chips with just one UART (eg. atmega 32u4) 16 | */ 17 | 18 | // Includes 19 | #include "sys.h" 20 | #include "lock.h" 21 | #include "updi_io.h" 22 | #include "JICE_io.h" 23 | #include "JTAG2.h" 24 | #include "UPDI_hi_lvl.h" 25 | 26 | volatile bool updi_mode = false; 27 | unsigned long baudrate = 115200; 28 | unsigned long updi_mode_start = 0; 29 | unsigned long updi_mode_end = 0; 30 | uint8_t stopbits = 1; 31 | uint8_t paritytype = 0; 32 | uint8_t numbits = 8; 33 | int8_t dtr = -1; 34 | int8_t rts = -1; 35 | uint16_t serial_mode = SERIAL_8N1; 36 | bool serialNeedReconfiguration = false; 37 | 38 | char support_buffer[64]; 39 | 40 | struct lock q; 41 | 42 | void setup() { 43 | /* Initialize MCU */ 44 | pinMode(LED_BUILTIN, OUTPUT); 45 | 46 | /* Initialize serial links */ 47 | JICE_io::init(); 48 | UPDI_io::init(); 49 | Serial1.begin(baudrate, serial_mode); 50 | lock_init(&q); 51 | JTAG2::sign_on(); 52 | } 53 | 54 | //#define DEBUG; 55 | 56 | //long blink_timer = 0; 57 | //long blink_delay = 1000; 58 | 59 | void loop() { 60 | 61 | #ifdef DEBUG 62 | if (millis() - blink_timer > blink_delay) { 63 | SYS::toggleLED(); 64 | blink_timer = millis(); 65 | } 66 | #endif 67 | 68 | if (updi_mode == false) { 69 | 70 | //blink_delay = 1000; 71 | 72 | if (int c = Serial1.available()) { 73 | lock(&q); 74 | if (c > Serial.availableForWrite()) { 75 | c = Serial.availableForWrite(); 76 | } 77 | unlock(&q); 78 | Serial1.readBytes(support_buffer, c); 79 | Serial.write(support_buffer, c); 80 | } 81 | 82 | if (int c = Serial.available()) { 83 | lock(&q); 84 | if (c > Serial1.availableForWrite()) { 85 | c = Serial1.availableForWrite(); 86 | } 87 | unlock(&q); 88 | Serial.readBytes(support_buffer, c); 89 | Serial1.write(support_buffer, c); 90 | } 91 | 92 | if (Serial.stopbits() != stopbits) { 93 | serial_mode &= ~HARDSER_STOP_BIT_MASK; 94 | stopbits = Serial.stopbits(); 95 | serialNeedReconfiguration = true; 96 | switch (stopbits) { 97 | case 1: 98 | serial_mode |= HARDSER_STOP_BIT_1; 99 | break; 100 | case 2: 101 | serial_mode |= HARDSER_STOP_BIT_2; 102 | break; 103 | } 104 | } 105 | if (Serial.paritytype() != paritytype) { 106 | serial_mode &= ~HARDSER_PARITY_MASK; 107 | paritytype = Serial.paritytype(); 108 | serialNeedReconfiguration = true; 109 | switch (paritytype) { 110 | case 0: 111 | serial_mode |= HARDSER_PARITY_NONE; 112 | break; 113 | case 1: 114 | serial_mode |= HARDSER_PARITY_EVEN; 115 | break; 116 | case 2: 117 | serial_mode |= HARDSER_PARITY_ODD; 118 | break; 119 | } 120 | } 121 | if (Serial.numbits() != numbits) { 122 | serial_mode &= ~HARDSER_DATA_MASK; 123 | numbits = Serial.numbits(); 124 | serialNeedReconfiguration = true; 125 | switch (numbits) { 126 | case 5: 127 | serial_mode |= HARDSER_DATA_5; 128 | break; 129 | case 6: 130 | serial_mode |= HARDSER_DATA_6; 131 | break; 132 | case 7: 133 | serial_mode |= HARDSER_DATA_7; 134 | break; 135 | case 8: 136 | serial_mode |= HARDSER_DATA_8; 137 | break; 138 | } 139 | } 140 | 141 | if (baudrate == 1200 && Serial.dtr() == 0 && (millis() - updi_mode_end > 200)) { 142 | // don't reenter here if you just finished flashing 143 | updi_mode = true; 144 | updi_mode_start = millis(); 145 | updi_mode_end = 0; 146 | } 147 | 148 | if (Serial.baud() != baudrate || serialNeedReconfiguration || Serial.dtr() != dtr) { 149 | dtr = Serial.dtr(); 150 | if (Serial.dtr() == 1) { 151 | baudrate = Serial.baud(); 152 | Serial1.end(); 153 | if (baudrate != 1200) { 154 | Serial1.begin(baudrate, serial_mode); 155 | serialNeedReconfiguration = false; 156 | // Request reset 157 | UPDI::stcs(UPDI::reg::ASI_Reset_Request, UPDI::RESET_ON); 158 | // Release reset (System remains in reset state until released) 159 | UPDI::stcs(UPDI::reg::ASI_Reset_Request, UPDI::RESET_OFF); 160 | } 161 | } 162 | } 163 | return; 164 | } 165 | 166 | if (updi_mode == true) { 167 | 168 | // updi_mode cannot last more than 1 minute; in that case, break forcibly 169 | if ((updi_mode_end != 0 && (millis() - updi_mode_end) > 500) || ((millis() - updi_mode_start) > 60000)) { 170 | updi_mode = false; 171 | baudrate = -1; 172 | return; 173 | } 174 | 175 | //blink_delay = 100; 176 | 177 | // Receive command 178 | if (!JTAG2::receive()) { 179 | return; 180 | } 181 | // Process command 182 | switch (JTAG2::packet.body[0]) { 183 | case JTAG2::CMND_GET_SIGN_ON: 184 | JTAG2::sign_on(); 185 | break; 186 | case JTAG2::CMND_GET_PARAMETER: 187 | JTAG2::get_parameter(); 188 | break; 189 | case JTAG2::CMND_SET_PARAMETER: 190 | JTAG2::set_parameter(); 191 | break; 192 | case JTAG2::CMND_RESET: 193 | case JTAG2::CMND_ENTER_PROGMODE: 194 | JTAG2::enter_progmode(); 195 | break; 196 | case JTAG2::CMND_SIGN_OFF: 197 | // Restore default baud rate before exiting 198 | JTAG2::PARAM_BAUD_RATE_VAL = JTAG2::baud_19200; 199 | case JTAG2::CMND_LEAVE_PROGMODE: 200 | JTAG2::leave_progmode(); 201 | updi_mode_end = millis(); 202 | break; 203 | case JTAG2::CMND_GET_SYNC: 204 | case JTAG2::CMND_GO: 205 | JTAG2::set_status(JTAG2::RSP_OK); 206 | break; 207 | case JTAG2::CMND_SET_DEVICE_DESCRIPTOR: 208 | JTAG2::set_device_descriptor(); 209 | break; 210 | case JTAG2::CMND_READ_MEMORY: 211 | JTAG2::read_mem(); 212 | break; 213 | case JTAG2::CMND_WRITE_MEMORY: 214 | JTAG2::write_mem(); 215 | break; 216 | case JTAG2::CMND_XMEGA_ERASE: 217 | JTAG2::erase(); 218 | break; 219 | default: 220 | JTAG2::set_status(JTAG2::RSP_FAILED); 221 | break; 222 | } 223 | // send response 224 | JTAG2::answer(); 225 | // some commands need to be executed after sending the answer 226 | JTAG2::delay_exec(); 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /firmwares/MuxTO/NVM.h: -------------------------------------------------------------------------------- 1 | /* 2 | NVM.h 3 | 4 | Created: 15-12-2017 10:59:53 5 | Author: JMR_2 6 | */ 7 | 8 | 9 | #ifndef NVM_H_ 10 | #define NVM_H_ 11 | 12 | #include 13 | #include "UPDI_lo_lvl.h" 14 | 15 | namespace NVM { 16 | // *** Base Addresses *** 17 | enum base { 18 | NVM_base = 0x1000, /* Base address of the NVM controller */ 19 | Sig_base = 0x1100, /* Base address of the signature */ 20 | Fuse_base = 0x1280, /* Base address of the fuses */ 21 | User_base = 0x1300, /* Base address of the User Row EEPROM */ 22 | EEPROM_base = 0x1400 /* Base address of the main EEPROM */ 23 | }; 24 | 25 | // *** NVM Registers (offsets from NVN_base are enum default values) *** 26 | enum reg { 27 | CTRLA, 28 | CTRLB, 29 | STATUS, 30 | INTCTRL, 31 | INTFLAGS, 32 | Reg_5, 33 | DATA_lo, 34 | DATA_hi, 35 | ADDR_lo, 36 | ADDR_hi 37 | }; 38 | 39 | // *** NVM Commands (write to CTRLA to execute) *** 40 | enum cmnd { 41 | NOP, /* Does nothing */ 42 | WP, /* Write page buffer to memory */ 43 | ER, /* Erase page */ 44 | ERWP, /* Erase and write page */ 45 | PBC, /* Page buffer clear */ 46 | CHER, /* Chip erase: erase Flash and EEPROM */ 47 | EEER, /* EEPROM Erase */ 48 | WFU /* Write fuse */ 49 | }; 50 | 51 | // *** NVM Functions *** 52 | template 53 | void command (uint8_t cmd) { 54 | uint16_t temp; 55 | /* preserve UPDI pointer if requested */ 56 | if (preserve_ptr) temp = UPDI::ldptr_w(); 57 | /* Execute NVM command */ 58 | UPDI::sts_b(NVM_base + CTRLA, cmd); 59 | /* restore UPDI pointer if requested */ 60 | if (preserve_ptr) UPDI::stptr_w(temp); 61 | } 62 | 63 | template 64 | void wait () { 65 | uint16_t temp; 66 | /* preserve UPDI pointer if requested */ 67 | if (preserve_ptr) temp = UPDI::ldptr_w(); 68 | /* Wait while NVM is busy from previous operations */ 69 | while (UPDI::lds_b(NVM::NVM_base + NVM::STATUS) & 0x03); 70 | /* restore UPDI pointer if requested */ 71 | if (preserve_ptr) UPDI::stptr_w(temp); 72 | } 73 | } 74 | 75 | #endif /* NVM_H_ */ 76 | -------------------------------------------------------------------------------- /firmwares/MuxTO/UPDI_hi_lvl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | UPDI_hi_lvl.cpp 3 | 4 | Created: 15-02-2018 23:08:39 5 | Author: JMR_2 6 | */ 7 | 8 | #include "UPDI_hi_lvl.h" 9 | 10 | void UPDI::CPU_reset() { 11 | // Request reset 12 | UPDI::stcs(UPDI::reg::ASI_Reset_Request, UPDI::RESET_ON); 13 | // Release reset (System remains in reset state until released) 14 | UPDI::stcs(UPDI::reg::ASI_Reset_Request, UPDI::RESET_OFF); 15 | 16 | // Wait for the reset process to end. 17 | // Either NVMPROG, UROWPROG or BOOTDONE bit will be set in the ASI_SYS_STATUS UPDI register. 18 | // This indicates reset is complete. 19 | while ( UPDI::CPU_mode<0x0E>() == 0 ); 20 | } 21 | -------------------------------------------------------------------------------- /firmwares/MuxTO/UPDI_hi_lvl.h: -------------------------------------------------------------------------------- 1 | /* 2 | UPDI_hi_lvl.h 3 | 4 | Created: 15-02-2018 23:12:54 5 | Author: JMR_2 6 | */ 7 | 8 | 9 | #ifndef UPDI_HI_LVL_H_ 10 | #define UPDI_HI_LVL_H_ 11 | 12 | #include "UPDI_lo_lvl.h" 13 | 14 | namespace UPDI { 15 | // Constant Expressions 16 | constexpr uint8_t RESET_ON = 0x59; 17 | constexpr uint8_t RESET_OFF = 0x00; 18 | 19 | // Function prototypes 20 | void CPU_reset(); 21 | 22 | // returns the current CPU mode, optionally a mask can be applied to ignore "don't care" status bits 23 | template 24 | uint8_t CPU_mode() { 25 | uint8_t mode = UPDI::lcds(UPDI::reg::ASI_System_Status); 26 | return mode & mask; 27 | } 28 | } 29 | 30 | #endif /* UPDI_HI_LVL_H_ */ 31 | -------------------------------------------------------------------------------- /firmwares/MuxTO/UPDI_lo_lvl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | UPDI_cmd.cpp 3 | 4 | Created: 23-11-2017 22:48:36 5 | Author: JMR_2 6 | */ 7 | 8 | // Includes 9 | #include "UPDI_lo_lvl.h" 10 | 11 | // Special optimization options 12 | // Unused r/w I/O registers residing in the space addressable by in/out instructions 13 | // can be used as temporary registers to save a few bytes/cycles. 14 | // Warning: MCU specific!!! 15 | //#define TEMP0 EEARL 16 | //#define TEMP1 GPIOR0 17 | //#define TEMP2 GPIOR1 18 | 19 | // Keys 20 | uint8_t UPDI::Chip_Erase[8] {0x65, 0x73, 0x61, 0x72, 0x45, 0x4D, 0x56, 0x4E}; 21 | uint8_t UPDI::NVM_Prog[8] {0x20, 0x67, 0x6F, 0x72, 0x50, 0x4D, 0x56, 0x4E}; 22 | uint8_t UPDI::UserRow_Write[8] {0x65, 0x74, 0x26, 0x73, 0x55, 0x4D, 0x56, 0x4E}; 23 | 24 | // Functions 25 | void UPDI::rep(uint8_t repeats) { 26 | # ifdef TEMP0 27 | TEMP0 = repeats; 28 | # endif 29 | UPDI_io::put(UPDI::SYNCH); 30 | UPDI_io::put(0xA0); 31 | # ifdef TEMP0 32 | UPDI_io::put(TEMP0); 33 | # else 34 | UPDI_io::put(repeats); 35 | # endif 36 | } 37 | 38 | void UPDI::stcs(reg r, uint8_t data) { 39 | UPDI_io::put(UPDI::SYNCH); 40 | UPDI_io::put(0xC0 + r); 41 | UPDI_io::put(data); 42 | } 43 | 44 | uint8_t UPDI::lcds(reg r) { 45 | UPDI_io::put(UPDI::SYNCH); 46 | UPDI_io::put(0x80 + r); 47 | return UPDI_io::get(); 48 | } 49 | 50 | void UPDI::read_sib(uint8_t (& buffer)[16]) { 51 | UPDI_io::put(UPDI::SYNCH); 52 | UPDI_io::put(0xE5); 53 | for (uint8_t i = 0; i < 16; i++) { 54 | buffer[i] = UPDI_io::get(); 55 | } 56 | } 57 | 58 | uint8_t UPDI::lds_b(uint16_t address) { 59 | UPDI_io::put(UPDI::SYNCH); 60 | UPDI_io::put(0x04); 61 | UPDI_io::put(address & 0xFF); 62 | UPDI_io::put(address >> 8); 63 | return UPDI_io::get(); 64 | } 65 | 66 | uint16_t UPDI::lds_w(uint16_t address) { 67 | UPDI_io::put(UPDI::SYNCH); 68 | UPDI_io::put(0x05); 69 | UPDI_io::put(address & 0xFF); 70 | UPDI_io::put(address >> 8); 71 | return UPDI_io::get() | (UPDI_io::get() << 8); 72 | } 73 | 74 | void UPDI::sts_b(uint16_t address, uint8_t data) { 75 | # ifdef TEMP0 76 | TEMP0 = data; 77 | # endif 78 | # ifdef TEMP1 79 | TEMP1 = address & 0xFF; 80 | # endif 81 | # ifdef TEMP2 82 | TEMP2 = address >> 8; 83 | # endif 84 | UPDI_io::put(UPDI::SYNCH); 85 | UPDI_io::put(0x44); 86 | # ifdef TEMP1 87 | UPDI_io::put(TEMP1); 88 | # else 89 | UPDI_io::put(address & 0xFF); 90 | # endif 91 | # ifdef TEMP2 92 | UPDI_io::put(TEMP2); 93 | # else 94 | UPDI_io::put(address >> 8); 95 | # endif 96 | UPDI_io::get(); 97 | # ifdef TEMP0 98 | UPDI_io::put(TEMP0); 99 | # else 100 | UPDI_io::put(data); 101 | # endif 102 | UPDI_io::get(); 103 | } 104 | 105 | void UPDI::sts_w(uint16_t address, uint16_t data) { 106 | UPDI_io::put(UPDI::SYNCH); 107 | UPDI_io::put(0x45); 108 | UPDI_io::put(address & 0xFF); 109 | UPDI_io::put(address >> 8); 110 | UPDI_io::get(); 111 | UPDI_io::put(data & 0xFF); 112 | UPDI_io::put(data >> 8); 113 | UPDI_io::get(); 114 | } 115 | 116 | uint8_t UPDI::ldptr_b() { 117 | UPDI_io::put(UPDI::SYNCH); 118 | UPDI_io::put(0x28); 119 | return UPDI_io::get(); 120 | } 121 | 122 | uint16_t UPDI::ldptr_w() { 123 | UPDI_io::put(UPDI::SYNCH); 124 | UPDI_io::put(0x29); 125 | # ifdef TEMP0 126 | TEMP0 = UPDI_io::get(); 127 | return (UPDI_io::get() << 8) | TEMP0; 128 | # else 129 | return UPDI_io::get() | (UPDI_io::get() << 8); 130 | # endif 131 | } 132 | 133 | uint8_t UPDI::ld_b() { 134 | UPDI_io::put(UPDI::SYNCH); 135 | UPDI_io::put(0x20); 136 | return UPDI_io::get(); 137 | } 138 | 139 | uint16_t UPDI::ld_w() { 140 | UPDI_io::put(UPDI::SYNCH); 141 | UPDI_io::put(0x21); 142 | return UPDI_io::get() | (UPDI_io::get() << 8); 143 | } 144 | 145 | uint8_t UPDI::ldinc_b() { 146 | UPDI_io::put(UPDI::SYNCH); 147 | UPDI_io::put(0x24); 148 | return UPDI_io::get(); 149 | } 150 | 151 | uint16_t UPDI::ldinc_w() { 152 | UPDI_io::put(UPDI::SYNCH); 153 | UPDI_io::put(0x25); 154 | return UPDI_io::get() | (UPDI_io::get() << 8); 155 | } 156 | 157 | void UPDI::stptr_b(uint8_t address) { 158 | UPDI_io::put(UPDI::SYNCH); 159 | UPDI_io::put(0x68); 160 | UPDI_io::put(address); 161 | UPDI_io::get(); 162 | } 163 | 164 | void UPDI::stptr_w(uint16_t address) { 165 | # ifdef TEMP0 166 | TEMP0 = address & 0xFF; 167 | # endif 168 | # ifdef TEMP1 169 | TEMP1 = address >> 8; 170 | # endif 171 | UPDI_io::put(UPDI::SYNCH); 172 | UPDI_io::put(0x69); 173 | # ifdef TEMP0 174 | UPDI_io::put(TEMP0); 175 | # else 176 | UPDI_io::put(address & 0xFF); 177 | # endif 178 | # ifdef TEMP1 179 | UPDI_io::put(TEMP1); 180 | # else 181 | UPDI_io::put(address >> 8); 182 | # endif 183 | UPDI_io::get(); 184 | } 185 | 186 | void UPDI::st_b(uint8_t data) { 187 | UPDI_io::put(UPDI::SYNCH); 188 | UPDI_io::put(0x60); 189 | UPDI_io::put(data); 190 | UPDI_io::get(); 191 | } 192 | 193 | void UPDI::st_w(uint16_t data) { 194 | UPDI_io::put(UPDI::SYNCH); 195 | UPDI_io::put(0x61); 196 | UPDI_io::put(data & 0xFF); 197 | UPDI_io::put(data >> 8); 198 | UPDI_io::get(); 199 | } 200 | 201 | void UPDI::stinc_b(uint8_t data) { 202 | # ifdef TEMP0 203 | TEMP0 = data; 204 | # endif 205 | UPDI_io::put(UPDI::SYNCH); 206 | UPDI_io::put(0x64); 207 | # ifdef TEMP0 208 | UPDI_io::put(TEMP0); 209 | # else 210 | UPDI_io::put(data); 211 | # endif 212 | UPDI_io::get(); 213 | } 214 | 215 | void UPDI::stinc_w(uint16_t data) { 216 | UPDI_io::put(UPDI::SYNCH); 217 | UPDI_io::put(0x65); 218 | UPDI_io::put(data & 0xFF); 219 | UPDI_io::put(data >> 8); 220 | UPDI_io::get(); 221 | } 222 | -------------------------------------------------------------------------------- /firmwares/MuxTO/UPDI_lo_lvl.h: -------------------------------------------------------------------------------- 1 | /* 2 | UPDI_cmd.h 3 | 4 | Created: 23-11-2017 22:46:11 5 | Author: JMR_2 6 | */ 7 | 8 | 9 | #ifndef UPDI_LO_LVL_H_ 10 | #define UPDI_LO_LVL_H_ 11 | 12 | #include 13 | #include "sys.h" 14 | #include "updi_io.h" 15 | 16 | namespace UPDI { 17 | // UPDI registers 18 | enum reg { 19 | Status_A, Status_B, Control_A, Control_B, 20 | Reg_4, Reg_5, Reg_6, ASI_Key_Status, 21 | ASI_Reset_Request, ASI_Control_A, ASI_System_Control_A, ASI_System_Status, 22 | ASI_CRC_Status, Reg_13, Reg_14, Reg_15 23 | }; 24 | 25 | 26 | // Constant Expressions 27 | constexpr uint8_t SYNCH = 0x55; 28 | constexpr uint8_t ACK = 0x40; 29 | 30 | // Activation Keys 31 | extern uint8_t Chip_Erase[8]; 32 | extern uint8_t NVM_Prog[8]; 33 | extern uint8_t UserRow_Write[8]; 34 | 35 | 36 | // Function prototypes 37 | void rep(uint8_t); 38 | 39 | void stcs(reg, uint8_t); 40 | uint8_t lcds(reg); 41 | 42 | void read_sib(uint8_t (&)[16]); 43 | 44 | uint8_t lds_b(uint16_t); 45 | uint16_t lds_w(uint16_t); 46 | 47 | void sts_b(uint16_t address, uint8_t data); /* Store data at address */ 48 | void sts_w(uint16_t, uint16_t); 49 | 50 | uint8_t ldptr_b(); 51 | uint16_t ldptr_w(); 52 | uint8_t ld_b(); 53 | uint16_t ld_w(); 54 | uint8_t ldinc_b(); 55 | uint16_t ldinc_w(); 56 | 57 | void stptr_b(uint8_t); 58 | void stptr_w(uint16_t); 59 | void st_b(uint8_t); 60 | void st_w(uint16_t); 61 | void stinc_b(uint8_t); 62 | void stinc_w(uint16_t); 63 | 64 | template 65 | inline void write_key(T (& k)[8]) __attribute__(( optimize("no-tree-loop-optimize") )); 66 | 67 | // Function Templates 68 | template 69 | void write_key(T (& k)[8]) { 70 | UPDI_io::put(SYNCH); 71 | UPDI_io::put(0xE0); 72 | T* key_ptr = k; 73 | for (uint8_t i = 8; i != 0; i--) { 74 | UPDI_io::put(*key_ptr); 75 | key_ptr++; 76 | } 77 | } 78 | } 79 | 80 | #endif /* UPDI_LO_LVL_H_ */ 81 | -------------------------------------------------------------------------------- /firmwares/MuxTO/crc16.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | crc16.cpp 3 | 4 | Created: 16-01-2018 23:06:40 5 | Author: JMR_2 6 | */ 7 | 8 | #include "crc16.h" 9 | #include "sys.h" 10 | #include "JICE_io.h" 11 | 12 | namespace { 13 | static const uint16_t crc_table[256] = 14 | { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 15 | 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 16 | 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 17 | 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 18 | 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 19 | 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 20 | 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 21 | 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 22 | 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 23 | 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 24 | 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 25 | 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 26 | 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 27 | 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 28 | 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 29 | 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 30 | 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 31 | 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 32 | 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 33 | 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 34 | 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 35 | 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 36 | 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 37 | 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 38 | 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 39 | 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 40 | 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 41 | 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 42 | 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 43 | 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 44 | 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 45 | 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 46 | }; 47 | } 48 | 49 | uint16_t CRC::next(uint8_t newchar, uint16_t previous) { 50 | union { 51 | uint16_t word; 52 | struct { 53 | uint8_t low; 54 | uint8_t high; 55 | } byte; 56 | } crc; 57 | crc.word = previous; 58 | crc.word = crc_table[crc.byte.low ^ newchar]; 59 | crc.byte.low ^= (previous >> 8); 60 | return crc.word; 61 | } 62 | -------------------------------------------------------------------------------- /firmwares/MuxTO/crc16.h: -------------------------------------------------------------------------------- 1 | /* 2 | crc16.h 3 | 4 | Created: 16-01-2018 23:07:05 5 | Author: JMR_2 6 | */ 7 | 8 | 9 | #ifndef CRC16_H_ 10 | #define CRC16_H_ 11 | 12 | #include 13 | 14 | namespace CRC { 15 | uint16_t next (uint8_t newchar, uint16_t previous = 0xFFFF); // 'previous' defaults to CRC seed value, 0xFFFF 16 | } 17 | 18 | #endif /* CRC16_H_ */ 19 | -------------------------------------------------------------------------------- /firmwares/MuxTO/lock.h: -------------------------------------------------------------------------------- 1 | #ifndef _ARCH_LOCK_H_ 2 | #define _ARCH_LOCK_H_ 3 | 4 | struct lock { 5 | uint32_t primask; 6 | }; 7 | 8 | #define LOCK_INIT (struct lock) {} 9 | 10 | static inline void lock_init(struct lock *lock) 11 | { 12 | } 13 | 14 | // source: 15 | // http://embeddedfreak.wordpress.com/2009/08/14/cortex-m3-global-interruptexception-control/ 16 | // 17 | // confirm this is correct by printing primask before after 18 | 19 | // note arm architecture v7m rm... setting PRIMASK raises priority to 0 20 | 21 | static inline void lock(struct lock *lock) 22 | { 23 | uint32_t tmp; 24 | asm volatile ( 25 | "mrs %0, PRIMASK\n\t" 26 | "cpsid i\n\t" 27 | : "=r" (tmp) ); 28 | lock->primask = tmp; 29 | } 30 | 31 | static inline void unlock(struct lock *lock) 32 | { 33 | asm volatile ( 34 | "msr PRIMASK, %0\n\t" 35 | : : "r" (lock->primask) ); 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /firmwares/MuxTO/sys.cpp: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /firmwares/MuxTO/sys.h: -------------------------------------------------------------------------------- 1 | /* 2 | sys.h 3 | 4 | Created: 02-10-2018 13:07:18 5 | Author: JMR_2 6 | */ 7 | 8 | #ifndef SYS_H_ 9 | #define SYS_H_ 10 | 11 | #define FLASH const 12 | 13 | template 14 | class flash { 15 | private: 16 | const T data; 17 | 18 | public: 19 | // normal constructor 20 | constexpr flash (T _data) : data(_data) {} 21 | // default constructor 22 | constexpr flash () : data(0) {} 23 | 24 | operator T() const { 25 | switch (sizeof(T)) { 26 | case 1: return pgm_read_byte(&data); 27 | case 2: return pgm_read_word(&data); 28 | case 4: return pgm_read_dword(&data); 29 | } 30 | } 31 | }; 32 | 33 | #ifndef F_CPU 34 | #define F_CPU 16000000U 35 | #endif 36 | 37 | constexpr unsigned int baud(unsigned long b) { 38 | return F_CPU / (b * 8.0) - 0.5; 39 | } 40 | 41 | 42 | #endif /* SYS_H_ */ 43 | -------------------------------------------------------------------------------- /firmwares/MuxTO/updi_io.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | updi_io.cpp 3 | 4 | Created: 18-11-2017 10:36:54 5 | Author: JMR_2 6 | */ 7 | 8 | // Includes 9 | #include 10 | #include 11 | #include "updi_io.h" 12 | 13 | // Functions 14 | /* Sends regular characters through the UPDI link */ 15 | uint8_t UPDI_io::put(char c) { 16 | Serial2.write(c); 17 | Serial2.flush(); 18 | //delayMicroseconds(10); 19 | long start = millis(); 20 | while (!Serial2.available() && millis() - start < 20) {} 21 | char d = Serial2.read(); 22 | if (c != d) { 23 | // Serial.println("echo failed! " + String(d, HEX)); 24 | } 25 | return c; 26 | } 27 | 28 | /* Sends special sequences through the UPDI link */ 29 | uint8_t UPDI_io::put(ctrl c) 30 | { 31 | Serial2.begin(300, SERIAL_8N1); 32 | 33 | switch (c) { 34 | case double_break: 35 | Serial2.write((uint8_t)0x00); 36 | Serial2.flush(); 37 | Serial2.write((uint8_t)0x00); 38 | Serial2.flush(); 39 | break; 40 | case single_break: 41 | Serial2.write((uint8_t)0x00); 42 | Serial2.flush(); 43 | break; 44 | default: 45 | break; 46 | } 47 | delay(15); 48 | while (Serial2.available()) { 49 | Serial2.read(); 50 | } 51 | Serial2.begin(230400, SERIAL_8E2); 52 | return 0; 53 | } 54 | 55 | uint8_t UPDI_io::get() { 56 | uint8_t c; 57 | while (!Serial2.available()) {} 58 | c = Serial2.read(); 59 | //delayMicroseconds(5); 60 | //Serial.println("get! " + String(c, HEX)); 61 | return c; 62 | } 63 | 64 | void UPDI_io::init(void) 65 | { 66 | Serial2.begin(230400, SERIAL_8E2); 67 | //Serial.begin(115200); 68 | } 69 | -------------------------------------------------------------------------------- /firmwares/MuxTO/updi_io.h: -------------------------------------------------------------------------------- 1 | /* 2 | updi_io.h 3 | 4 | Created: 18-11-2017 10:38:31 5 | Author: JMR_2 6 | */ 7 | 8 | 9 | #ifndef UPDI_IO_H_ 10 | #define UPDI_IO_H_ 11 | 12 | namespace UPDI_io { 13 | // Enums 14 | enum ctrl {single_break, double_break, enable}; 15 | 16 | // Function prototypes 17 | uint8_t put(char) __attribute__((optimize("no-tree-loop-optimize"))); 18 | uint8_t put(ctrl); 19 | uint8_t get() __attribute__((optimize("no-tree-loop-optimize"))); 20 | void init(void); 21 | } 22 | 23 | #endif /* UPDI_IO_H_ */ 24 | -------------------------------------------------------------------------------- /firmwares/MuxTO/updi_io_soft.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | updi_io_soft.cpp 3 | 4 | Created: 11-08-2018 22:08:14 5 | Author: Cristian Balint 6 | */ 7 | 8 | #ifdef __AVR_ATmega16__ 9 | 10 | // Includes 11 | #include 12 | #include 13 | 14 | #include "sys.h" 15 | #include "updi_io.h" 16 | 17 | // Defines 18 | #ifndef F_CPU 19 | # define F_CPU 16000000U 20 | #endif 21 | #ifndef UPDI_BAUD 22 | # define UPDI_BAUD 225000U // (max 225000 min approx. F_CPU/100) 23 | #endif 24 | 25 | // Cycle timing 26 | #define TXDELAY (uint8_t)(((F_CPU/UPDI_BAUD) - 9) / 3) 27 | #define RXDELAY (uint8_t)(((F_CPU/UPDI_BAUD) - 9) / 3) 28 | #define RXHALFD (uint8_t) (RXDELAY / 2) 29 | 30 | // Check 31 | #if ( (((F_CPU/UPDI_BAUD) - 9) / 3) > 254 ) 32 | # error Low baud rates are not supported - use higher UPDI_BAUD 33 | #endif 34 | 35 | // Functions 36 | /* Sends regular characters through the UPDI link */ 37 | uint8_t UPDI_io::get() { 38 | 39 | // rx input 40 | DDR(UPDI_PORT) &= ~(1 << UPDI_PIN); 41 | // no pullup 42 | PORT(UPDI_PORT) &= ~(1 << UPDI_PIN); 43 | 44 | uint8_t c; 45 | 46 | __asm volatile 47 | ( 48 | " ldi %0, 0 \n\t" // init 49 | " ldi r20, 8 \n\t" // 8 bits 50 | " ldi r19, 3 \n\t" // 1 parity + 2 stop bits 51 | 52 | // wait for start edge 53 | "WaitStart: \n\t" 54 | " sbic %[uart_port], %[uart_pin] \n\t" 55 | " rjmp WaitStart \n\t" 56 | 57 | // skew into middle of edge 58 | " ldi r18, %[rxhalfd] \n\t" // 0.5 bit cycle delay 59 | "HBitDelay: \n\t" 60 | " dec r18 \n\t" 61 | " brne HBitDelay \n\t" 62 | 63 | // 8 bits 64 | "RxBLoop: \n\t" 65 | " ldi r18, %[rxdelay] \n\t" // 1 bit cycle delay 66 | "RxBDelay: \n\t" 67 | " dec r18 \n\t" 68 | " brne RxBDelay \n\t" 69 | " in r21, %[uart_port] \n\t" // get current bit from serial link 70 | " bst r21, %[uart_pin] \n\t" // use T flag 71 | " bld r22, 0\n\t" // to move current data bit 72 | " lsr r22 \n\t" // into carry 73 | " ror %0 \n\t" // accumulate serial data bits into result 74 | " dec r20 \n\t" 75 | " brne RxBLoop \n\t" 76 | " nop \n\t" 77 | 78 | // 1 parity + 2 stop bits 79 | "RxSLoop: \n\t" 80 | " ldi r18, %[rxdelay] \n\t" // 1 bit cycle delay 81 | "RxSDelay: \n\t" 82 | " dec r18 \n\t" 83 | " brne RxSDelay \n\t" 84 | " in r21, %[uart_port] \n\t" // get current bit from serial link 85 | " bst r21, %[uart_pin] \n\t" // use T flag 86 | " bld r22, 0\n\t" // to move current data bit 87 | " lsr r22 \n\t" // into carry 88 | " nop \n\t" // accumulate serial data bits into result 89 | " dec r19 \n\t" 90 | " brne RxSLoop \n\t" 91 | " nop \n\t" 92 | 93 | : "=r" (c) 94 | : [uart_port] "i" (_SFR_IO_ADDR(PIN(UPDI_PORT))), 95 | [uart_pin] "i" (UPDI_PIN), 96 | [rxdelay] "i" (RXDELAY), 97 | [rxhalfd] "i" (RXHALFD) 98 | : "r0", "r18", "r19", "r20", "r21", "r22" 99 | ); 100 | 101 | // re-enable pull up 102 | PORT(UPDI_PORT) |= (1 << UPDI_PIN); 103 | 104 | return c; 105 | } 106 | 107 | uint8_t UPDI_io::put(char c) { 108 | 109 | // tx enable 110 | DDR(UPDI_PORT) |= (1 << UPDI_PIN); 111 | 112 | __asm volatile 113 | ( 114 | " in r0, %[uart_port] \n\t" // port state 115 | " ldi r26, 2 \n\t" // 2 bit stop 116 | " ldi r27, 8 \n\t" // 8 bit parity 117 | " ldi r28, %[txdelay] \n\t" // delay counter 118 | " ldi r30, 8 \n\t" // 8 bit loop 119 | 120 | // pre delay 121 | // 2 bit time 122 | " mov r29, r28 \n\t" 123 | "TxDelay: \n\t" 124 | " nop \n\t" 125 | " dec r29 \n\t" 126 | " brne TxDelay \n\t" 127 | 128 | // start bit 129 | " mov r29, r28 \n\t" 130 | "TxDelayS: \n\t" 131 | " dec r29 \n\t" 132 | " brne TxDelayS \n\t" 133 | " bclr 6 \n\t" 134 | " bld r0, %[uart_pin] \n\t" 135 | " nop \n\t" 136 | " nop \n\t" 137 | " nop \n\t" 138 | " out %[uart_port], r0 \n\t" 139 | " nop \n\t" 140 | " nop \n\t" 141 | 142 | // 8 bits 143 | "TxLoop: \n\t" 144 | " mov r29, r28 \n\t" // load delay counter 145 | "TxDelayB: \n\t" // delay (3 cycle * delayCount) - 1 146 | " dec r29 \n\t" 147 | " brne TxDelayB \n\t" 148 | " bst %[ch], 0 \n\t" // load bit in T 149 | " bld r0, %[uart_pin] \n\t" // store T bit in r0 150 | " ror %[ch] \n\t" // shift right into carry 151 | " sbci r27, 0 \n\t" // subtract carry (accumulate parity) 152 | " dec r30 \n\t" // decrement bits counter 153 | " out %[uart_port], r0 \n\t" // send bit out 154 | " brne TxLoop \n\t" // loop for each bit 155 | " nop \n\t" 156 | 157 | // parity bit 158 | " mov r29, r28 \n\t" 159 | "TxDelayP: \n\t" 160 | " dec r29 \n\t" 161 | " brne TxDelayP \n\t" 162 | " bst r27, 0 \n\t" // extract accumulated parity 163 | " bld r0, %[uart_pin] \n\t" 164 | " nop \n\t" 165 | " nop \n\t" 166 | " nop \n\t" 167 | " out %[uart_port], r0 \n\t" // send bit out to serial link 168 | " nop \n\t" 169 | " nop \n\t" 170 | 171 | // stop bits 172 | "StopLoop: \n\t" 173 | " mov r29, r28 \n\t" 174 | "TxDelayStop: \n\t" 175 | " dec r29 \n\t" 176 | " brne TxDelayStop \n\t" 177 | " bset 6 \n\t" 178 | " bld r0, %[uart_pin] \n\t" 179 | " nop \n\t" 180 | " nop \n\t" 181 | " dec r26 \n\t" 182 | " out %[uart_port], r0 \n\t" // send bit out to serial link 183 | " brne StopLoop \n\t" // loop for each bit 184 | " nop \n\t" 185 | 186 | : 187 | : [uart_port] "i" (_SFR_IO_ADDR(PORT(UPDI_PORT))), 188 | [uart_pin] "i" (UPDI_PIN), 189 | [txdelay] "i" (TXDELAY), 190 | [ch] "r" (c) 191 | : "r0", "r26", "r27", "r28", "r29", "r30" 192 | ); 193 | 194 | // Ready for RX input 195 | DDR(UPDI_PORT) &= ~(1 << UPDI_PIN); 196 | 197 | return c; 198 | } 199 | 200 | static inline void send_break() { 201 | 202 | // tx enable 203 | DDR(UPDI_PORT) |= (1 << UPDI_PIN); 204 | 205 | // 206 | // 13 cycles = 24.60ms 207 | // 208 | 209 | // low 12 cycle 210 | PORT(UPDI_PORT) &= ~(1 << UPDI_PIN); 211 | _delay_us(2048 * 11); 212 | 213 | // high 1 cycle 214 | PORT(UPDI_PORT) |= (1 << UPDI_PIN); 215 | _delay_us(2048); 216 | 217 | // RX enable 218 | DDR(UPDI_PORT) &= ~(1 << UPDI_PIN); 219 | 220 | return; 221 | } 222 | 223 | /* Sends special sequences through the UPDI link */ 224 | uint8_t UPDI_io::put(ctrl c) { 225 | 226 | switch (c) { 227 | 228 | case double_break: 229 | send_break(); 230 | send_break(); 231 | break; 232 | 233 | case single_break: 234 | send_break(); 235 | break; 236 | 237 | case enable: 238 | 239 | default: 240 | break; 241 | } 242 | 243 | return 0; 244 | } 245 | 246 | void UPDI_io::init(void) { 247 | 248 | } 249 | 250 | #endif //__AVR_ATmega16__ 251 | -------------------------------------------------------------------------------- /fuses/fuses_4809.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoCore-megaavr/5e639ee40afa693354d3d056ba7fb795a8948c11/fuses/fuses_4809.bin -------------------------------------------------------------------------------- /libraries/EEPROM/README.md: -------------------------------------------------------------------------------- 1 | ## **EEPROM Library V2.0** for Arduino 2 | 3 | **Written by:** _Christopher Andrews_. 4 | 5 | ### **What is the EEPROM library.** 6 | 7 | Th EEPROM library provides an easy to use interface to interact with the internal non-volatile storage found in AVR based Arduino boards. This library will work on many AVR devices like ATtiny and ATmega chips. 8 | 9 | ### **How to use it** 10 | The EEPROM library is included in your IDE download. To add its functionality to your sketch you'll need to reference the library header file. You do this by adding an include directive to the top of your sketch. 11 | 12 | ```Arduino 13 | #include 14 | 15 | void setup(){ 16 | 17 | } 18 | 19 | void loop(){ 20 | 21 | } 22 | 23 | ``` 24 | 25 | The library provides a global variable named `EEPROM`, you use this variable to access the library functions. The methods provided in the EEPROM class are listed below. 26 | 27 | You can view all the examples [here](examples/). 28 | 29 | ### **Library functions** 30 | 31 | #### **`EEPROM.read( address )`** [[_example_]](examples/eeprom_read/eeprom_read.ino) 32 | 33 | This function allows you to read a single byte of data from the eeprom. 34 | Its only parameter is an `int` which should be set to the address you wish to read. 35 | 36 | The function returns an `unsigned char` containing the value read. 37 | 38 | #### **`EEPROM.write( address, value )`** [[_example_]](examples/eeprom_write/eeprom_write.ino) 39 | 40 | The `write()` method allows you to write a single byte of data to the EEPROM. 41 | Two parameters are needed. The first is an `int` containing the address that is to be written, and the second is a the data to be written (`unsigned char`). 42 | 43 | This function does not return any value. 44 | 45 | #### **`EEPROM.update( address, value )`** [[_example_]](examples/eeprom_update/eeprom_update.ino) 46 | 47 | This function is similar to `EEPROM.write()` however this method will only write data if the cell contents pointed to by `address` is different to `value`. This method can help prevent unnecessary wear on the EEPROM cells. 48 | 49 | This function does not return any value. 50 | 51 | #### **`EEPROM.get( address, object )`** [[_example_]](examples/eeprom_get/eeprom_get.ino) 52 | 53 | This function will retrieve any object from the EEPROM. 54 | Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to read. 55 | 56 | This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. 57 | 58 | #### **`EEPROM.put( address, object )`** [[_example_]](examples/eeprom_put/eeprom_put.ino) 59 | 60 | This function will write any object to the EEPROM. 61 | Two parameters are needed to call this function. The first is an `int` containing the address that is to be written, and the second is the object you would like to write. 62 | 63 | This function uses the _update_ method to write its data, and therefore only rewrites changed cells. 64 | 65 | This function returns a reference to the `object` passed in. It does not need to be used and is only returned for conveience. 66 | 67 | #### **Subscript operator: `EEPROM[address]`** [[_example_]](examples/eeprom_crc/eeprom_crc.ino) 68 | 69 | This operator allows using the identifier `EEPROM` like an array. 70 | EEPROM cells can be read _and_ **_written_** directly using this method. 71 | 72 | This operator returns a reference to the EEPROM cell. 73 | 74 | ```c++ 75 | unsigned char val; 76 | 77 | //Read first EEPROM cell. 78 | val = EEPROM[ 0 ]; 79 | 80 | //Write first EEPROM cell. 81 | EEPROM[ 0 ] = val; 82 | 83 | //Compare contents 84 | if( val == EEPROM[ 0 ] ){ 85 | //Do something... 86 | } 87 | ``` 88 | 89 | #### **`EEPROM.length()`** 90 | 91 | This function returns an `unsigned int` containing the number of cells in the EEPROM. 92 | 93 | --- 94 | 95 | ### **Advanced features** 96 | 97 | This library uses a component based approach to provide its functionality. This means you can also use these components to design a customized approach. Two background classes are available for use: `EERef` & `EEPtr`. 98 | 99 | #### **`EERef` class** 100 | 101 | This object references an EEPROM cell. 102 | Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. 103 | This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. 104 | 105 | ```C++ 106 | EERef ref = EEPROM[ 10 ]; //Create a reference to 11th cell. 107 | 108 | ref = 4; //write to EEPROM cell. 109 | 110 | unsigned char val = ref; //Read referenced cell. 111 | ``` 112 | 113 | #### **`EEPtr` class** 114 | 115 | This object is a bidirectional pointer to EEPROM cells represented by `EERef` objects. 116 | Just like a normal pointer type, this type can be dereferenced and repositioned using 117 | increment/decrement operators. 118 | 119 | ```C++ 120 | EEPtr ptr = 10; //Create a pointer to 11th cell. 121 | 122 | *ptr = 4; //dereference and write to EEPROM cell. 123 | 124 | unsigned char val = *ptr; //dereference and read. 125 | 126 | ptr++; //Move to next EEPROM cell. 127 | ``` 128 | 129 | #### **`EEPROM.begin()`** 130 | 131 | This function returns an `EEPtr` pointing to the first cell in the EEPROM. 132 | This is useful for STL objects, custom iteration and C++11 style ranged for loops. 133 | 134 | #### **`EEPROM.end()`** 135 | 136 | This function returns an `EEPtr` pointing at the location after the last EEPROM cell. 137 | Used with `begin()` to provide custom iteration. 138 | 139 | **Note:** The `EEPtr` returned is invalid as it is out of range. Infact the hardware causes wrapping of the address (overflow) and `EEPROM.end()` actually references the first EEPROM cell. 140 | -------------------------------------------------------------------------------- /libraries/EEPROM/examples/eeprom_clear/eeprom_clear.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Clear 3 | * 4 | * Sets all of the bytes of the EEPROM to 0. 5 | * Please see eeprom_iteration for a more in depth 6 | * look at how to traverse the EEPROM. 7 | * 8 | * This example code is in the public domain. 9 | */ 10 | 11 | #include 12 | 13 | void setup() { 14 | // initialize the LED pin as an output. 15 | pinMode(13, OUTPUT); 16 | 17 | /*** 18 | Iterate through each byte of the EEPROM storage. 19 | 20 | Larger AVR processors have larger EEPROM sizes, E.g: 21 | - Arduno Duemilanove: 512b EEPROM storage. 22 | - Arduino Uno: 1kb EEPROM storage. 23 | - Arduino Mega: 4kb EEPROM storage. 24 | 25 | Rather than hard-coding the length, you should use the pre-provided length function. 26 | This will make your code portable to all AVR processors. 27 | ***/ 28 | 29 | for (int i = 0 ; i < EEPROM.length() ; i++) { 30 | EEPROM.write(i, 0); 31 | } 32 | 33 | // turn the LED on when we're done 34 | digitalWrite(13, HIGH); 35 | } 36 | 37 | void loop() { 38 | /** Empty loop. **/ 39 | } 40 | -------------------------------------------------------------------------------- /libraries/EEPROM/examples/eeprom_crc/eeprom_crc.ino: -------------------------------------------------------------------------------- 1 | /*** 2 | Written by Christopher Andrews. 3 | CRC algorithm generated by pycrc, MIT licence ( https://github.com/tpircher/pycrc ). 4 | 5 | A CRC is a simple way of checking whether data has changed or become corrupted. 6 | This example calculates a CRC value directly on the EEPROM values. 7 | The purpose of this example is to highlight how the EEPROM object can be used just like an array. 8 | ***/ 9 | 10 | #include 11 | #include 12 | 13 | void setup() { 14 | 15 | //Start serial 16 | Serial.begin(9600); 17 | while (!Serial) { 18 | ; // wait for serial port to connect. Needed for native USB port only 19 | } 20 | 21 | //Print length of data to run CRC on. 22 | Serial.print("EEPROM length: "); 23 | Serial.println(EEPROM.length()); 24 | 25 | //Print the result of calling eeprom_crc() 26 | Serial.print("CRC32 of EEPROM data: 0x"); 27 | Serial.println(eeprom_crc(), HEX); 28 | Serial.print("\n\nDone!"); 29 | } 30 | 31 | void loop() { 32 | /* Empty loop */ 33 | } 34 | 35 | unsigned long eeprom_crc(void) { 36 | 37 | const unsigned long crc_table[16] = { 38 | 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 39 | 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 40 | 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 41 | 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 42 | }; 43 | 44 | unsigned long crc = ~0L; 45 | 46 | for (int index = 0 ; index < EEPROM.length() ; ++index) { 47 | crc = crc_table[(crc ^ EEPROM[index]) & 0x0f] ^ (crc >> 4); 48 | crc = crc_table[(crc ^ (EEPROM[index] >> 4)) & 0x0f] ^ (crc >> 4); 49 | crc = ~crc; 50 | } 51 | return crc; 52 | } 53 | -------------------------------------------------------------------------------- /libraries/EEPROM/examples/eeprom_get/eeprom_get.ino: -------------------------------------------------------------------------------- 1 | /*** 2 | eeprom_get example. 3 | 4 | This shows how to use the EEPROM.get() method. 5 | 6 | To pre-set the EEPROM data, run the example sketch eeprom_put. 7 | This sketch will run without it, however, the values shown 8 | will be shown from what ever is already on the EEPROM. 9 | 10 | This may cause the serial object to print out a large string 11 | of garbage if there is no null character inside one of the strings 12 | loaded. 13 | 14 | Written by Christopher Andrews 2015 15 | Released under MIT licence. 16 | ***/ 17 | 18 | #include 19 | 20 | void setup() { 21 | 22 | float f = 0.00f; //Variable to store data read from EEPROM. 23 | int eeAddress = 0; //EEPROM address to start reading from 24 | 25 | Serial.begin(9600); 26 | while (!Serial) { 27 | ; // wait for serial port to connect. Needed for native USB port only 28 | } 29 | Serial.print("Read float from EEPROM: "); 30 | 31 | //Get the float data from the EEPROM at position 'eeAddress' 32 | EEPROM.get(eeAddress, f); 33 | Serial.println(f, 3); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float. 34 | 35 | /*** 36 | As get also returns a reference to 'f', you can use it inline. 37 | E.g: Serial.print( EEPROM.get( eeAddress, f ) ); 38 | ***/ 39 | 40 | /*** 41 | Get can be used with custom structures too. 42 | I have separated this into an extra function. 43 | ***/ 44 | 45 | secondTest(); //Run the next test. 46 | } 47 | 48 | struct MyObject { 49 | float field1; 50 | byte field2; 51 | char name[10]; 52 | }; 53 | 54 | void secondTest() { 55 | int eeAddress = sizeof(float); //Move address to the next byte after float 'f'. 56 | 57 | MyObject customVar; //Variable to store custom object read from EEPROM. 58 | EEPROM.get(eeAddress, customVar); 59 | 60 | Serial.println("Read custom object from EEPROM: "); 61 | Serial.println(customVar.field1); 62 | Serial.println(customVar.field2); 63 | Serial.println(customVar.name); 64 | } 65 | 66 | void loop() { 67 | /* Empty loop */ 68 | } 69 | -------------------------------------------------------------------------------- /libraries/EEPROM/examples/eeprom_iteration/eeprom_iteration.ino: -------------------------------------------------------------------------------- 1 | /*** 2 | eeprom_iteration example. 3 | 4 | A set of example snippets highlighting the 5 | simplest methods for traversing the EEPROM. 6 | 7 | Running this sketch is not necessary, this is 8 | simply highlighting certain programming methods. 9 | 10 | Written by Christopher Andrews 2015 11 | Released under MIT licence. 12 | ***/ 13 | 14 | #include 15 | 16 | void setup() { 17 | 18 | /*** 19 | Iterate the EEPROM using a for loop. 20 | ***/ 21 | 22 | for (int index = 0 ; index < EEPROM.length() ; index++) { 23 | 24 | //Add one to each cell in the EEPROM 25 | EEPROM[ index ] += 1; 26 | } 27 | 28 | /*** 29 | Iterate the EEPROM using a while loop. 30 | ***/ 31 | 32 | int index = 0; 33 | 34 | while (index < EEPROM.length()) { 35 | 36 | //Add one to each cell in the EEPROM 37 | EEPROM[ index ] += 1; 38 | index++; 39 | } 40 | 41 | /*** 42 | Iterate the EEPROM using a do-while loop. 43 | ***/ 44 | 45 | int idx = 0; //Used 'idx' to avoid name conflict with 'index' above. 46 | 47 | do { 48 | 49 | //Add one to each cell in the EEPROM 50 | EEPROM[ idx ] += 1; 51 | idx++; 52 | } while (idx < EEPROM.length()); 53 | 54 | 55 | } //End of setup function. 56 | 57 | void loop() {} -------------------------------------------------------------------------------- /libraries/EEPROM/examples/eeprom_put/eeprom_put.ino: -------------------------------------------------------------------------------- 1 | /*** 2 | eeprom_put example. 3 | 4 | This shows how to use the EEPROM.put() method. 5 | Also, this sketch will pre-set the EEPROM data for the 6 | example sketch eeprom_get. 7 | 8 | Note, unlike the single byte version EEPROM.write(), 9 | the put method will use update semantics. As in a byte 10 | will only be written to the EEPROM if the data is actually 11 | different. 12 | 13 | Written by Christopher Andrews 2015 14 | Released under MIT licence. 15 | ***/ 16 | 17 | #include 18 | 19 | struct MyObject { 20 | float field1; 21 | byte field2; 22 | char name[10]; 23 | }; 24 | 25 | void setup() { 26 | 27 | Serial.begin(9600); 28 | while (!Serial) { 29 | ; // wait for serial port to connect. Needed for native USB port only 30 | } 31 | 32 | float f = 123.456f; //Variable to store in EEPROM. 33 | int eeAddress = 0; //Location we want the data to be put. 34 | 35 | 36 | //One simple call, with the address first and the object second. 37 | EEPROM.put(eeAddress, f); 38 | 39 | Serial.println("Written float data type!"); 40 | 41 | /** Put is designed for use with custom structures also. **/ 42 | 43 | //Data to store. 44 | MyObject customVar = { 45 | 3.14f, 46 | 65, 47 | "Working!" 48 | }; 49 | 50 | eeAddress += sizeof(float); //Move address to the next byte after float 'f'. 51 | 52 | EEPROM.put(eeAddress, customVar); 53 | Serial.print("Written custom data type! \n\nView the example sketch eeprom_get to see how you can retrieve the values!"); 54 | } 55 | 56 | void loop() { 57 | /* Empty loop */ 58 | } 59 | -------------------------------------------------------------------------------- /libraries/EEPROM/examples/eeprom_read/eeprom_read.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Read 3 | * 4 | * Reads the value of each byte of the EEPROM and prints it 5 | * to the computer. 6 | * This example code is in the public domain. 7 | */ 8 | 9 | #include 10 | 11 | // start reading from the first byte (address 0) of the EEPROM 12 | int address = 0; 13 | byte value; 14 | 15 | void setup() { 16 | // initialize serial and wait for port to open: 17 | Serial.begin(9600); 18 | while (!Serial) { 19 | ; // wait for serial port to connect. Needed for native USB port only 20 | } 21 | } 22 | 23 | void loop() { 24 | // read a byte from the current address of the EEPROM 25 | value = EEPROM.read(address); 26 | 27 | Serial.print(address); 28 | Serial.print("\t"); 29 | Serial.print(value, DEC); 30 | Serial.println(); 31 | 32 | /*** 33 | Advance to the next address, when at the end restart at the beginning. 34 | 35 | Larger AVR processors have larger EEPROM sizes, E.g: 36 | - Arduno Duemilanove: 512b EEPROM storage. 37 | - Arduino Uno: 1kb EEPROM storage. 38 | - Arduino Mega: 4kb EEPROM storage. 39 | 40 | Rather than hard-coding the length, you should use the pre-provided length function. 41 | This will make your code portable to all AVR processors. 42 | ***/ 43 | address = address + 1; 44 | if (address == EEPROM.length()) { 45 | address = 0; 46 | } 47 | 48 | /*** 49 | As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an 50 | EEPROM address is also doable by a bitwise and of the length - 1. 51 | 52 | ++address &= EEPROM.length() - 1; 53 | ***/ 54 | 55 | delay(500); 56 | } 57 | -------------------------------------------------------------------------------- /libraries/EEPROM/examples/eeprom_update/eeprom_update.ino: -------------------------------------------------------------------------------- 1 | /*** 2 | EEPROM Update method 3 | 4 | Stores values read from analog input 0 into the EEPROM. 5 | These values will stay in the EEPROM when the board is 6 | turned off and may be retrieved later by another sketch. 7 | 8 | If a value has not changed in the EEPROM, it is not overwritten 9 | which would reduce the life span of the EEPROM unnecessarily. 10 | 11 | Released using MIT licence. 12 | ***/ 13 | 14 | #include 15 | 16 | /** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ 17 | int address = 0; 18 | 19 | void setup() { 20 | /** EMpty setup **/ 21 | } 22 | 23 | void loop() { 24 | /*** 25 | need to divide by 4 because analog inputs range from 26 | 0 to 1023 and each byte of the EEPROM can only hold a 27 | value from 0 to 255. 28 | ***/ 29 | int val = analogRead(0) / 4; 30 | 31 | /*** 32 | Update the particular EEPROM cell. 33 | these values will remain there when the board is 34 | turned off. 35 | ***/ 36 | EEPROM.update(address, val); 37 | 38 | /*** 39 | The function EEPROM.update(address, val) is equivalent to the following: 40 | 41 | if( EEPROM.read(address) != val ){ 42 | EEPROM.write(address, val); 43 | } 44 | ***/ 45 | 46 | 47 | /*** 48 | Advance to the next address, when at the end restart at the beginning. 49 | 50 | Larger AVR processors have larger EEPROM sizes, E.g: 51 | - Arduno Duemilanove: 512b EEPROM storage. 52 | - Arduino Uno: 1kb EEPROM storage. 53 | - Arduino Mega: 4kb EEPROM storage. 54 | 55 | Rather than hard-coding the length, you should use the pre-provided length function. 56 | This will make your code portable to all AVR processors. 57 | ***/ 58 | address = address + 1; 59 | if (address == EEPROM.length()) { 60 | address = 0; 61 | } 62 | 63 | /*** 64 | As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an 65 | EEPROM address is also doable by a bitwise and of the length - 1. 66 | 67 | ++address &= EEPROM.length() - 1; 68 | ***/ 69 | 70 | delay(100); 71 | } 72 | -------------------------------------------------------------------------------- /libraries/EEPROM/examples/eeprom_write/eeprom_write.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * EEPROM Write 3 | * 4 | * Stores values read from analog input 0 into the EEPROM. 5 | * These values will stay in the EEPROM when the board is 6 | * turned off and may be retrieved later by another sketch. 7 | */ 8 | 9 | #include 10 | 11 | /** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ 12 | int addr = 0; 13 | 14 | void setup() { 15 | /** Empty setup. **/ 16 | } 17 | 18 | void loop() { 19 | /*** 20 | Need to divide by 4 because analog inputs range from 21 | 0 to 1023 and each byte of the EEPROM can only hold a 22 | value from 0 to 255. 23 | ***/ 24 | 25 | int val = analogRead(0) / 4; 26 | 27 | /*** 28 | Write the value to the appropriate byte of the EEPROM. 29 | these values will remain there when the board is 30 | turned off. 31 | ***/ 32 | 33 | EEPROM.write(addr, val); 34 | 35 | /*** 36 | Advance to the next address, when at the end restart at the beginning. 37 | 38 | Larger AVR processors have larger EEPROM sizes, E.g: 39 | - Arduno Duemilanove: 512b EEPROM storage. 40 | - Arduino Uno: 1kb EEPROM storage. 41 | - Arduino Mega: 4kb EEPROM storage. 42 | 43 | Rather than hard-coding the length, you should use the pre-provided length function. 44 | This will make your code portable to all AVR processors. 45 | ***/ 46 | addr = addr + 1; 47 | if (addr == EEPROM.length()) { 48 | addr = 0; 49 | } 50 | 51 | /*** 52 | As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an 53 | EEPROM address is also doable by a bitwise and of the length - 1. 54 | 55 | ++addr &= EEPROM.length() - 1; 56 | ***/ 57 | 58 | 59 | delay(100); 60 | } 61 | -------------------------------------------------------------------------------- /libraries/EEPROM/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For EEPROM 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | EEPROM KEYWORD1 10 | EERef KEYWORD1 11 | EEPtr KEYWORD2 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | 17 | update KEYWORD2 18 | 19 | ####################################### 20 | # Constants (LITERAL1) 21 | ####################################### 22 | 23 | -------------------------------------------------------------------------------- /libraries/EEPROM/library.properties: -------------------------------------------------------------------------------- 1 | name=EEPROM 2 | version=2.0 3 | author=Arduino, Christopher Andrews 4 | maintainer=Arduino 5 | sentence=Enables reading and writing to the permanent board storage. 6 | paragraph=This library allows to read and write data in a memory type, the EEPROM, that keeps its content also when the board is powered off. The amount of EEPROM available depends on the microcontroller type. 7 | category=Data Storage 8 | url=http://www.arduino.cc/en/Reference/EEPROM 9 | architectures=megaavr 10 | 11 | -------------------------------------------------------------------------------- /libraries/EEPROM/src/EEPROM.h: -------------------------------------------------------------------------------- 1 | /* 2 | EEPROM.h - EEPROM library 3 | Original Copyright (c) 2006 David A. Mellis. All right reserved. 4 | New version by Christopher Andrews 2015. 5 | 6 | This library is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU Lesser General Public 8 | License as published by the Free Software Foundation; either 9 | version 2.1 of the License, or (at your option) any later version. 10 | 11 | This library is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | Lesser General Public License for more details. 15 | 16 | You should have received a copy of the GNU Lesser General Public 17 | License along with this library; if not, write to the Free Software 18 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef EEPROM_h 22 | #define EEPROM_h 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | /*** 29 | EERef class. 30 | 31 | This object references an EEPROM cell. 32 | Its purpose is to mimic a typical byte of RAM, however its storage is the EEPROM. 33 | This class has an overhead of two bytes, similar to storing a pointer to an EEPROM cell. 34 | ***/ 35 | 36 | struct EERef{ 37 | 38 | EERef( const int index ) 39 | : index( index ) {} 40 | 41 | //Access/read members. 42 | uint8_t operator*() const { return eeprom_read_byte( (uint8_t*) index ); } 43 | operator uint8_t() const { return **this; } 44 | 45 | //Assignment/write members. 46 | EERef &operator=( const EERef &ref ) { return *this = *ref; } 47 | EERef &operator=( uint8_t in ) { return eeprom_write_byte( (uint8_t*) index, in ), *this; } 48 | EERef &operator +=( uint8_t in ) { return *this = **this + in; } 49 | EERef &operator -=( uint8_t in ) { return *this = **this - in; } 50 | EERef &operator *=( uint8_t in ) { return *this = **this * in; } 51 | EERef &operator /=( uint8_t in ) { return *this = **this / in; } 52 | EERef &operator ^=( uint8_t in ) { return *this = **this ^ in; } 53 | EERef &operator %=( uint8_t in ) { return *this = **this % in; } 54 | EERef &operator &=( uint8_t in ) { return *this = **this & in; } 55 | EERef &operator |=( uint8_t in ) { return *this = **this | in; } 56 | EERef &operator <<=( uint8_t in ) { return *this = **this << in; } 57 | EERef &operator >>=( uint8_t in ) { return *this = **this >> in; } 58 | 59 | EERef &update( uint8_t in ) { return in != *this ? *this = in : *this; } 60 | 61 | /** Prefix increment/decrement **/ 62 | EERef& operator++() { return *this += 1; } 63 | EERef& operator--() { return *this -= 1; } 64 | 65 | /** Postfix increment/decrement **/ 66 | uint8_t operator++ (int){ 67 | uint8_t ret = **this; 68 | return ++(*this), ret; 69 | } 70 | 71 | uint8_t operator-- (int){ 72 | uint8_t ret = **this; 73 | return --(*this), ret; 74 | } 75 | 76 | int index; //Index of current EEPROM cell. 77 | }; 78 | 79 | /*** 80 | EEPtr class. 81 | 82 | This object is a bidirectional pointer to EEPROM cells represented by EERef objects. 83 | Just like a normal pointer type, this can be dereferenced and repositioned using 84 | increment/decrement operators. 85 | ***/ 86 | 87 | struct EEPtr{ 88 | 89 | EEPtr( const int index ) 90 | : index( index ) {} 91 | 92 | operator int() const { return index; } 93 | EEPtr &operator=( int in ) { return index = in, *this; } 94 | 95 | //Iterator functionality. 96 | bool operator!=( const EEPtr &ptr ) { return index != ptr.index; } 97 | EERef operator*() { return index; } 98 | 99 | /** Prefix & Postfix increment/decrement **/ 100 | EEPtr& operator++() { return ++index, *this; } 101 | EEPtr& operator--() { return --index, *this; } 102 | EEPtr operator++ (int) { return index++; } 103 | EEPtr operator-- (int) { return index--; } 104 | 105 | int index; //Index of current EEPROM cell. 106 | }; 107 | 108 | /*** 109 | EEPROMClass class. 110 | 111 | This object represents the entire EEPROM space. 112 | It wraps the functionality of EEPtr and EERef into a basic interface. 113 | This class is also 100% backwards compatible with earlier Arduino core releases. 114 | ***/ 115 | 116 | struct EEPROMClass{ 117 | 118 | //Basic user access methods. 119 | EERef operator[]( const int idx ) { return idx; } 120 | uint8_t read( int idx ) { return EERef( idx ); } 121 | void write( int idx, uint8_t val ) { (EERef( idx )) = val; } 122 | void update( int idx, uint8_t val ) { EERef( idx ).update( val ); } 123 | 124 | //STL and C++11 iteration capability. 125 | EEPtr begin() { return 0x00; } 126 | EEPtr end() { return length(); } //Standards requires this to be the item after the last valid entry. The returned pointer is invalid. 127 | uint16_t length() { return EEPROM_SIZE; } 128 | 129 | //Functionality to 'get' and 'put' objects to and from EEPROM. 130 | template< typename T > T &get( int idx, T &t ){ 131 | EEPtr e = idx; 132 | uint8_t *ptr = (uint8_t*) &t; 133 | for( int count = sizeof(T) ; count ; --count, ++e ) *ptr++ = *e; 134 | return t; 135 | } 136 | 137 | template< typename T > const T &put( int idx, const T &t ){ 138 | EEPtr e = idx; 139 | const uint8_t *ptr = (const uint8_t*) &t; 140 | for( int count = sizeof(T) ; count ; --count, ++e ) (*e).update( *ptr++ ); 141 | return t; 142 | } 143 | }; 144 | 145 | static EEPROMClass EEPROM; 146 | #endif 147 | -------------------------------------------------------------------------------- /libraries/SPI/examples/BarometricPressureSensor/BarometricPressureSensor.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SCP1000 Barometric Pressure Sensor Display 3 | 4 | Shows the output of a Barometric Pressure Sensor on a 5 | Uses the SPI library. For details on the sensor, see: 6 | http://www.sparkfun.com/commerce/product_info.php?products_id=8161 7 | http://www.vti.fi/en/support/obsolete_products/pressure_sensors/ 8 | 9 | This sketch adapted from Nathan Seidle's SCP1000 example for PIC: 10 | http://www.sparkfun.com/datasheets/Sensors/SCP1000-Testing.zip 11 | 12 | Circuit: 13 | SCP1000 sensor attached to pins 6, 7, 10 - 13: 14 | DRDY: pin 6 15 | CSB: pin 7 16 | MOSI: pin 11 17 | MISO: pin 12 18 | SCK: pin 13 19 | 20 | created 31 July 2010 21 | modified 14 August 2010 22 | by Tom Igoe 23 | */ 24 | 25 | // the sensor communicates using SPI, so include the library: 26 | #include 27 | 28 | //Sensor's memory register addresses: 29 | const int PRESSURE = 0x1F; //3 most significant bits of pressure 30 | const int PRESSURE_LSB = 0x20; //16 least significant bits of pressure 31 | const int TEMPERATURE = 0x21; //16 bit temperature reading 32 | const byte READ = 0b11111100; // SCP1000's read command 33 | const byte WRITE = 0b00000010; // SCP1000's write command 34 | 35 | // pins used for the connection with the sensor 36 | // the other you need are controlled by the SPI library): 37 | const int dataReadyPin = 6; 38 | const int chipSelectPin = 7; 39 | 40 | void setup() { 41 | Serial.begin(9600); 42 | 43 | // start the SPI library: 44 | SPI.begin(); 45 | 46 | // initalize the data ready and chip select pins: 47 | pinMode(dataReadyPin, INPUT); 48 | pinMode(chipSelectPin, OUTPUT); 49 | 50 | //Configure SCP1000 for low noise configuration: 51 | writeRegister(0x02, 0x2D); 52 | writeRegister(0x01, 0x03); 53 | writeRegister(0x03, 0x02); 54 | // give the sensor time to set up: 55 | delay(100); 56 | } 57 | 58 | void loop() { 59 | //Select High Resolution Mode 60 | writeRegister(0x03, 0x0A); 61 | 62 | // don't do anything until the data ready pin is high: 63 | if (digitalRead(dataReadyPin) == HIGH) { 64 | //Read the temperature data 65 | int tempData = readRegister(0x21, 2); 66 | 67 | // convert the temperature to celsius and display it: 68 | float realTemp = (float)tempData / 20.0; 69 | Serial.print("Temp[C]="); 70 | Serial.print(realTemp); 71 | 72 | 73 | //Read the pressure data highest 3 bits: 74 | byte pressure_data_high = readRegister(0x1F, 1); 75 | pressure_data_high &= 0b00000111; //you only needs bits 2 to 0 76 | 77 | //Read the pressure data lower 16 bits: 78 | unsigned int pressure_data_low = readRegister(0x20, 2); 79 | //combine the two parts into one 19-bit number: 80 | long pressure = ((pressure_data_high << 16) | pressure_data_low) / 4; 81 | 82 | // display the temperature: 83 | Serial.println("\tPressure [Pa]=" + String(pressure)); 84 | } 85 | } 86 | 87 | //Read from or write to register from the SCP1000: 88 | unsigned int readRegister(byte thisRegister, int bytesToRead) { 89 | byte inByte = 0; // incoming byte from the SPI 90 | unsigned int result = 0; // result to return 91 | Serial.print(thisRegister, BIN); 92 | Serial.print("\t"); 93 | // SCP1000 expects the register name in the upper 6 bits 94 | // of the byte. So shift the bits left by two bits: 95 | thisRegister = thisRegister << 2; 96 | // now combine the address and the command into one byte 97 | byte dataToSend = thisRegister & READ; 98 | Serial.println(thisRegister, BIN); 99 | // take the chip select low to select the device: 100 | digitalWrite(chipSelectPin, LOW); 101 | // send the device the register you want to read: 102 | SPI.transfer(dataToSend); 103 | // send a value of 0 to read the first byte returned: 104 | result = SPI.transfer(0x00); 105 | // decrement the number of bytes left to read: 106 | bytesToRead--; 107 | // if you still have another byte to read: 108 | if (bytesToRead > 0) { 109 | // shift the first byte left, then get the second byte: 110 | result = result << 8; 111 | inByte = SPI.transfer(0x00); 112 | // combine the byte you just got with the previous one: 113 | result = result | inByte; 114 | // decrement the number of bytes left to read: 115 | bytesToRead--; 116 | } 117 | // take the chip select high to de-select: 118 | digitalWrite(chipSelectPin, HIGH); 119 | // return the result: 120 | return (result); 121 | } 122 | 123 | 124 | //Sends a write command to SCP1000 125 | 126 | void writeRegister(byte thisRegister, byte thisValue) { 127 | 128 | // SCP1000 expects the register address in the upper 6 bits 129 | // of the byte. So shift the bits left by two bits: 130 | thisRegister = thisRegister << 2; 131 | // now combine the register address and the command into one byte: 132 | byte dataToSend = thisRegister | WRITE; 133 | 134 | // take the chip select low to select the device: 135 | digitalWrite(chipSelectPin, LOW); 136 | 137 | SPI.transfer(dataToSend); //Send register location 138 | SPI.transfer(thisValue); //Send value to record into register 139 | 140 | // take the chip select high to de-select: 141 | digitalWrite(chipSelectPin, HIGH); 142 | } 143 | 144 | -------------------------------------------------------------------------------- /libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Digital Pot Control 3 | 4 | This example controls an Analog Devices AD5206 digital potentiometer. 5 | The AD5206 has 6 potentiometer channels. Each channel's pins are labeled 6 | A - connect this to voltage 7 | W - this is the pot's wiper, which changes when you set it 8 | B - connect this to ground. 9 | 10 | The AD5206 is SPI-compatible,and to command it, you send two bytes, 11 | one with the channel number (0 - 5) and one with the resistance value for the 12 | channel (0 - 255). 13 | 14 | The circuit: 15 | * All A pins of AD5206 connected to +5V 16 | * All B pins of AD5206 connected to ground 17 | * An LED and a 220-ohm resisor in series connected from each W pin to ground 18 | * CS - to digital pin 10 (SS pin) 19 | * SDI - to digital pin 11 (MOSI pin) 20 | * CLK - to digital pin 13 (SCK pin) 21 | 22 | created 10 Aug 2010 23 | by Tom Igoe 24 | 25 | Thanks to Heather Dewey-Hagborg for the original tutorial, 2005 26 | 27 | */ 28 | 29 | 30 | // inslude the SPI library: 31 | #include 32 | 33 | 34 | // set pin 10 as the slave select for the digital pot: 35 | const int slaveSelectPin = 10; 36 | 37 | void setup() { 38 | // set the slaveSelectPin as an output: 39 | pinMode(slaveSelectPin, OUTPUT); 40 | // initialize SPI: 41 | SPI.begin(); 42 | } 43 | 44 | void loop() { 45 | // go through the six channels of the digital pot: 46 | for (int channel = 0; channel < 6; channel++) { 47 | // change the resistance on this channel from min to max: 48 | for (int level = 0; level < 255; level++) { 49 | digitalPotWrite(channel, level); 50 | delay(10); 51 | } 52 | // wait a second at the top: 53 | delay(100); 54 | // change the resistance on this channel from max to min: 55 | for (int level = 0; level < 255; level++) { 56 | digitalPotWrite(channel, 255 - level); 57 | delay(10); 58 | } 59 | } 60 | 61 | } 62 | 63 | void digitalPotWrite(int address, int value) { 64 | // take the SS pin low to select the chip: 65 | digitalWrite(slaveSelectPin, LOW); 66 | delay(100); 67 | // send in the address and value via SPI: 68 | SPI.transfer(address); 69 | SPI.transfer(value); 70 | delay(100); 71 | // take the SS pin high to de-select the chip: 72 | digitalWrite(slaveSelectPin, HIGH); 73 | } 74 | -------------------------------------------------------------------------------- /libraries/SPI/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map SPI 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | SPI KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | begin KEYWORD2 15 | end KEYWORD2 16 | transfer KEYWORD2 17 | setBitOrder KEYWORD2 18 | setDataMode KEYWORD2 19 | setClockDivider KEYWORD2 20 | 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | SPI_CLOCK_DIV4 LITERAL1 26 | SPI_CLOCK_DIV16 LITERAL1 27 | SPI_CLOCK_DIV64 LITERAL1 28 | SPI_CLOCK_DIV128 LITERAL1 29 | SPI_CLOCK_DIV2 LITERAL1 30 | SPI_CLOCK_DIV8 LITERAL1 31 | SPI_CLOCK_DIV32 LITERAL1 32 | SPI_CLOCK_DIV64 LITERAL1 33 | SPI_MODE0 LITERAL1 34 | SPI_MODE1 LITERAL1 35 | SPI_MODE2 LITERAL1 36 | SPI_MODE3 LITERAL1 -------------------------------------------------------------------------------- /libraries/SPI/library.properties: -------------------------------------------------------------------------------- 1 | name=SPI 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. 6 | paragraph=SPI is a synchronous serial data protocol used by microcontrollers for communicating with one or more peripheral devices quickly over short distances. It uses three lines common to all devices (MISO, MOSI and SCK) and one specific for each device. 7 | category=Communication 8 | url=http://www.arduino.cc/en/Reference/SPI 9 | architectures=megaavr 10 | 11 | -------------------------------------------------------------------------------- /libraries/SoftwareSerial/examples/SoftwareSerialExample/SoftwareSerialExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Software serial multple serial test 3 | 4 | Receives from the hardware serial, sends to software serial. 5 | Receives from software serial, sends to hardware serial. 6 | 7 | The circuit: 8 | * RX is digital pin 10 (connect to TX of other device) 9 | * TX is digital pin 11 (connect to RX of other device) 10 | 11 | Note: 12 | Not all pins on the Mega and Mega 2560 support change interrupts, 13 | so only the following can be used for RX: 14 | 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 15 | 16 | Not all pins on the Leonardo and Micro support change interrupts, 17 | so only the following can be used for RX: 18 | 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). 19 | 20 | created back in the mists of time 21 | modified 25 May 2012 22 | by Tom Igoe 23 | based on Mikal Hart's example 24 | 25 | This example code is in the public domain. 26 | 27 | */ 28 | #include 29 | 30 | SoftwareSerial mySerial(10, 11); // RX, TX 31 | 32 | void setup() { 33 | // Open serial communications and wait for port to open: 34 | Serial.begin(57600); 35 | while (!Serial) { 36 | ; // wait for serial port to connect. Needed for native USB port only 37 | } 38 | 39 | 40 | Serial.println("Goodnight moon!"); 41 | 42 | // set the data rate for the SoftwareSerial port 43 | mySerial.begin(4800); 44 | mySerial.println("Hello, world?"); 45 | } 46 | 47 | void loop() { // run over and over 48 | if (mySerial.available()) { 49 | Serial.write(mySerial.read()); 50 | } 51 | if (Serial.available()) { 52 | mySerial.write(Serial.read()); 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /libraries/SoftwareSerial/examples/TwoPortReceive/TwoPortReceive.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Software serial multple serial test 3 | 4 | Receives from the two software serial ports, 5 | sends to the hardware serial port. 6 | 7 | In order to listen on a software port, you call port.listen(). 8 | When using two software serial ports, you have to switch ports 9 | by listen()ing on each one in turn. Pick a logical time to switch 10 | ports, like the end of an expected transmission, or when the 11 | buffer is empty. This example switches ports when there is nothing 12 | more to read from a port 13 | 14 | The circuit: 15 | Two devices which communicate serially are needed. 16 | * First serial device's TX attached to digital pin 10(RX), RX to pin 11(TX) 17 | * Second serial device's TX attached to digital pin 8(RX), RX to pin 9(TX) 18 | 19 | Note: 20 | Not all pins on the Mega and Mega 2560 support change interrupts, 21 | so only the following can be used for RX: 22 | 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69 23 | 24 | Not all pins on the Leonardo support change interrupts, 25 | so only the following can be used for RX: 26 | 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI). 27 | 28 | created 18 Apr. 2011 29 | modified 19 March 2016 30 | by Tom Igoe 31 | based on Mikal Hart's twoPortRXExample 32 | 33 | This example code is in the public domain. 34 | 35 | */ 36 | 37 | #include 38 | // software serial #1: RX = digital pin 10, TX = digital pin 11 39 | SoftwareSerial portOne(10, 11); 40 | 41 | // software serial #2: RX = digital pin 8, TX = digital pin 9 42 | // on the Mega, use other pins instead, since 8 and 9 don't work on the Mega 43 | SoftwareSerial portTwo(8, 9); 44 | 45 | void setup() { 46 | // Open serial communications and wait for port to open: 47 | Serial.begin(9600); 48 | while (!Serial) { 49 | ; // wait for serial port to connect. Needed for native USB port only 50 | } 51 | 52 | 53 | // Start each software serial port 54 | portOne.begin(9600); 55 | portTwo.begin(9600); 56 | } 57 | 58 | void loop() { 59 | // By default, the last intialized port is listening. 60 | // when you want to listen on a port, explicitly select it: 61 | portOne.listen(); 62 | Serial.println("Data from port one:"); 63 | // while there is data coming in, read it 64 | // and send to the hardware serial port: 65 | while (portOne.available() > 0) { 66 | char inByte = portOne.read(); 67 | Serial.write(inByte); 68 | } 69 | 70 | // blank line to separate data from the two ports: 71 | Serial.println(); 72 | 73 | // Now listen on the second port 74 | portTwo.listen(); 75 | // while there is data coming in, read it 76 | // and send to the hardware serial port: 77 | Serial.println("Data from port two:"); 78 | while (portTwo.available() > 0) { 79 | char inByte = portTwo.read(); 80 | Serial.write(inByte); 81 | } 82 | 83 | // blank line to separate data from the two ports: 84 | Serial.println(); 85 | } 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /libraries/SoftwareSerial/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map for SoftwareSerial 3 | # (formerly NewSoftSerial) 4 | ####################################### 5 | 6 | ####################################### 7 | # Datatypes (KEYWORD1) 8 | ####################################### 9 | 10 | SoftwareSerial KEYWORD1 11 | 12 | ####################################### 13 | # Methods and Functions (KEYWORD2) 14 | ####################################### 15 | 16 | begin KEYWORD2 17 | end KEYWORD2 18 | read KEYWORD2 19 | write KEYWORD2 20 | available KEYWORD2 21 | isListening KEYWORD2 22 | overflow KEYWORD2 23 | flush KEYWORD2 24 | listen KEYWORD2 25 | peek KEYWORD2 26 | 27 | ####################################### 28 | # Constants (LITERAL1) 29 | ####################################### 30 | 31 | -------------------------------------------------------------------------------- /libraries/SoftwareSerial/library.properties: -------------------------------------------------------------------------------- 1 | name=SoftwareSerial 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=Enables serial communication on any digital pin. 6 | paragraph=The SoftwareSerial library has been developed to allow serial communication on any digital pin of the board, using software to replicate the functionality of the hardware UART. It is possible to have multiple software serial ports with speeds up to 115200 bps. 7 | category=Communication 8 | url=http://www.arduino.cc/en/Reference/SoftwareSerial 9 | architectures=megaavr 10 | 11 | -------------------------------------------------------------------------------- /libraries/SoftwareSerial/src/SoftwareSerial.h: -------------------------------------------------------------------------------- 1 | /* 2 | SoftwareSerial.h (formerly NewSoftSerial.h) - 3 | Multi-instance software serial library for Arduino/Wiring 4 | -- Interrupt-driven receive and other improvements by ladyada 5 | (http://ladyada.net) 6 | -- Tuning, circular buffer, derivation from class Print/Stream, 7 | multi-instance support, porting to 8MHz processors, 8 | various optimizations, PROGMEM delay tables, inverse logic and 9 | direct port writing by Mikal Hart (http://www.arduiniana.org) 10 | -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com) 11 | -- 20MHz processor support by Garrett Mace (http://www.macetech.com) 12 | -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/) 13 | 14 | This library is free software; you can redistribute it and/or 15 | modify it under the terms of the GNU Lesser General Public 16 | License as published by the Free Software Foundation; either 17 | version 2.1 of the License, or (at your option) any later version. 18 | 19 | This library is distributed in the hope that it will be useful, 20 | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 | Lesser General Public License for more details. 23 | 24 | You should have received a copy of the GNU Lesser General Public 25 | License along with this library; if not, write to the Free Software 26 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 | 28 | The latest version of this library can always be found at 29 | http://arduiniana.org. 30 | */ 31 | 32 | #ifndef SoftwareSerial_h 33 | #define SoftwareSerial_h 34 | 35 | #include 36 | #include 37 | 38 | /****************************************************************************** 39 | * Definitions 40 | ******************************************************************************/ 41 | 42 | #ifndef _SS_MAX_RX_BUFF 43 | #define _SS_MAX_RX_BUFF 64 // RX buffer size 44 | #endif 45 | 46 | #ifndef GCC_VERSION 47 | #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 48 | #endif 49 | 50 | class SoftwareSerial : public Stream 51 | { 52 | private: 53 | // per object data 54 | uint8_t _receivePin; 55 | uint8_t _receiveBitMask; 56 | volatile uint8_t *_receivePortRegister; 57 | uint8_t _transmitBitMask; 58 | volatile uint8_t *_transmitPortRegister; 59 | volatile uint8_t *_pcint_maskreg; 60 | uint8_t _pcint_maskvalue; 61 | 62 | // Expressed as 4-cycle delays (must never be 0!) 63 | uint16_t _rx_delay_centering; 64 | uint16_t _rx_delay_intrabit; 65 | uint16_t _rx_delay_stopbit; 66 | uint16_t _tx_delay; 67 | 68 | uint16_t _buffer_overflow:1; 69 | uint16_t _inverse_logic:1; 70 | 71 | // static data 72 | static uint8_t _receive_buffer[_SS_MAX_RX_BUFF]; 73 | static volatile uint8_t _receive_buffer_tail; 74 | static volatile uint8_t _receive_buffer_head; 75 | static SoftwareSerial *active_object; 76 | 77 | // private methods 78 | inline void recv() __attribute__((__always_inline__)); 79 | uint8_t rx_pin_read(); 80 | void setTX(uint8_t transmitPin); 81 | void setRX(uint8_t receivePin); 82 | inline void setRxIntMsk(bool enable) __attribute__((__always_inline__)); 83 | 84 | // Return num - sub, or 1 if the result would be < 1 85 | static uint16_t subtract_cap(uint16_t num, uint16_t sub); 86 | 87 | // private static method for timing 88 | static inline void tunedDelay(uint16_t delay); 89 | 90 | public: 91 | // public methods 92 | SoftwareSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false); 93 | ~SoftwareSerial(); 94 | void begin(long speed); 95 | bool listen(); 96 | void end(); 97 | bool isListening() { return this == active_object; } 98 | bool stopListening(); 99 | bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; } 100 | int peek(); 101 | 102 | virtual size_t write(uint8_t byte); 103 | virtual int read(); 104 | virtual int available(); 105 | virtual void flush(); 106 | explicit operator bool() { return true; } 107 | 108 | using Print::write; 109 | 110 | // public only for easy access by interrupt handlers 111 | static inline void handle_interrupt() __attribute__((__always_inline__)); 112 | }; 113 | 114 | // Arduino 0012 workaround 115 | #undef int 116 | #undef char 117 | #undef long 118 | #undef byte 119 | #undef float 120 | #undef abs 121 | #undef round 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /libraries/Wire/examples/SFRRanger_reader/SFRRanger_reader.ino: -------------------------------------------------------------------------------- 1 | // I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder 2 | // by Nicholas Zambetti 3 | // and James Tichenor 4 | 5 | // Demonstrates use of the Wire library reading data from the 6 | // Devantech Utrasonic Rangers SFR08 and SFR10 7 | 8 | // Created 29 April 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(); // join i2c bus (address optional for master) 17 | Serial.begin(9600); // start serial communication at 9600bps 18 | } 19 | 20 | int reading = 0; 21 | 22 | void loop() { 23 | // step 1: instruct sensor to read echoes 24 | Wire.beginTransmission(112); // transmit to device #112 (0x70) 25 | // the address specified in the datasheet is 224 (0xE0) 26 | // but i2c adressing uses the high 7 bits so it's 112 27 | Wire.write(byte(0x00)); // sets register pointer to the command register (0x00) 28 | Wire.write(byte(0x50)); // command sensor to measure in "inches" (0x50) 29 | // use 0x51 for centimeters 30 | // use 0x52 for ping microseconds 31 | Wire.endTransmission(); // stop transmitting 32 | 33 | // step 2: wait for readings to happen 34 | delay(70); // datasheet suggests at least 65 milliseconds 35 | 36 | // step 3: instruct sensor to return a particular echo reading 37 | Wire.beginTransmission(112); // transmit to device #112 38 | Wire.write(byte(0x02)); // sets register pointer to echo #1 register (0x02) 39 | Wire.endTransmission(); // stop transmitting 40 | 41 | // step 4: request reading from sensor 42 | Wire.requestFrom(112, 2); // request 2 bytes from slave device #112 43 | 44 | // step 5: receive reading from sensor 45 | if (2 <= Wire.available()) { // if two bytes were received 46 | reading = Wire.read(); // receive high byte (overwrites previous reading) 47 | reading = reading << 8; // shift high byte to be high 8 bits 48 | reading |= Wire.read(); // receive low byte as lower 8 bits 49 | Serial.println(reading); // print the reading 50 | } 51 | 52 | delay(250); // wait a bit since people have to read the output :) 53 | } 54 | 55 | 56 | /* 57 | 58 | // The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08) 59 | // usage: changeAddress(0x70, 0xE6); 60 | 61 | void changeAddress(byte oldAddress, byte newAddress) 62 | { 63 | Wire.beginTransmission(oldAddress); 64 | Wire.write(byte(0x00)); 65 | Wire.write(byte(0xA0)); 66 | Wire.endTransmission(); 67 | 68 | Wire.beginTransmission(oldAddress); 69 | Wire.write(byte(0x00)); 70 | Wire.write(byte(0xAA)); 71 | Wire.endTransmission(); 72 | 73 | Wire.beginTransmission(oldAddress); 74 | Wire.write(byte(0x00)); 75 | Wire.write(byte(0xA5)); 76 | Wire.endTransmission(); 77 | 78 | Wire.beginTransmission(oldAddress); 79 | Wire.write(byte(0x00)); 80 | Wire.write(newAddress); 81 | Wire.endTransmission(); 82 | } 83 | 84 | */ 85 | -------------------------------------------------------------------------------- /libraries/Wire/examples/digital_potentiometer/digital_potentiometer.ino: -------------------------------------------------------------------------------- 1 | // I2C Digital Potentiometer 2 | // by Nicholas Zambetti 3 | // and Shawn Bonkowski 4 | 5 | // Demonstrates use of the Wire library 6 | // Controls AD5171 digital potentiometer via I2C/TWI 7 | 8 | // Created 31 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(); // join i2c bus (address optional for master) 17 | } 18 | 19 | byte val = 0; 20 | 21 | void loop() { 22 | Wire.beginTransmission(44); // transmit to device #44 (0x2c) 23 | // device address is specified in datasheet 24 | Wire.write(byte(0x00)); // sends instruction byte 25 | Wire.write(val); // sends potentiometer value byte 26 | Wire.endTransmission(); // stop transmitting 27 | 28 | val++; // increment value 29 | if (val == 64) { // if reached 64th position (max) 30 | val = 0; // start over from lowest value 31 | } 32 | delay(500); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /libraries/Wire/examples/master_reader/master_reader.ino: -------------------------------------------------------------------------------- 1 | // Wire Master Reader 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Reads data from an I2C/TWI slave device 6 | // Refer to the "Wire Slave Sender" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(); // join i2c bus (address optional for master) 17 | Serial.begin(9600); // start serial for output 18 | } 19 | 20 | void loop() { 21 | Wire.requestFrom(8, 6); // request 6 bytes from slave device #8 22 | 23 | while (Wire.available()) { // slave may send less than requested 24 | char c = Wire.read(); // receive a byte as character 25 | Serial.print(c); // print the character 26 | } 27 | 28 | delay(500); 29 | } 30 | -------------------------------------------------------------------------------- /libraries/Wire/examples/master_writer/master_writer.ino: -------------------------------------------------------------------------------- 1 | // Wire Master Writer 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Writes data to an I2C/TWI slave device 6 | // Refer to the "Wire Slave Receiver" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(); // join i2c bus (address optional for master) 17 | } 18 | 19 | byte x = 0; 20 | 21 | void loop() { 22 | Wire.beginTransmission(8); // transmit to device #8 23 | Wire.write("x is "); // sends five bytes 24 | Wire.write(x); // sends one byte 25 | Wire.endTransmission(); // stop transmitting 26 | 27 | x++; 28 | delay(500); 29 | } 30 | -------------------------------------------------------------------------------- /libraries/Wire/examples/slave_receiver/slave_receiver.ino: -------------------------------------------------------------------------------- 1 | // Wire Slave Receiver 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Receives data as an I2C/TWI slave device 6 | // Refer to the "Wire Master Writer" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(8); // join i2c bus with address #8 17 | Wire.onReceive(receiveEvent); // register event 18 | Serial.begin(9600); // start serial for output 19 | } 20 | 21 | void loop() { 22 | delay(100); 23 | } 24 | 25 | // function that executes whenever data is received from master 26 | // this function is registered as an event, see setup() 27 | void receiveEvent(int howMany) { 28 | while (1 < Wire.available()) { // loop through all but the last 29 | char c = Wire.read(); // receive byte as a character 30 | Serial.print(c); // print the character 31 | } 32 | int x = Wire.read(); // receive byte as an integer 33 | Serial.println(x); // print the integer 34 | } 35 | -------------------------------------------------------------------------------- /libraries/Wire/examples/slave_sender/slave_sender.ino: -------------------------------------------------------------------------------- 1 | // Wire Slave Sender 2 | // by Nicholas Zambetti 3 | 4 | // Demonstrates use of the Wire library 5 | // Sends data as an I2C/TWI slave device 6 | // Refer to the "Wire Master Reader" example for use with this 7 | 8 | // Created 29 March 2006 9 | 10 | // This example code is in the public domain. 11 | 12 | 13 | #include 14 | 15 | void setup() { 16 | Wire.begin(8); // join i2c bus with address #8 17 | Wire.onRequest(requestEvent); // register event 18 | } 19 | 20 | void loop() { 21 | delay(100); 22 | } 23 | 24 | // function that executes whenever data is requested by master 25 | // this function is registered as an event, see setup() 26 | void requestEvent() { 27 | Wire.write("hello "); // respond with message of 6 bytes 28 | // as expected by master 29 | } 30 | -------------------------------------------------------------------------------- /libraries/Wire/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Wire 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Wire KEYWORD2 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | setClock KEYWORD2 17 | beginTransmission KEYWORD2 18 | endTransmission KEYWORD2 19 | requestFrom KEYWORD2 20 | onReceive KEYWORD2 21 | onRequest KEYWORD2 22 | 23 | ####################################### 24 | # Constants (LITERAL1) 25 | ####################################### 26 | 27 | -------------------------------------------------------------------------------- /libraries/Wire/library.properties: -------------------------------------------------------------------------------- 1 | name=Wire 2 | version=1.0 3 | author=Arduino 4 | maintainer=Arduino 5 | sentence=This library allows you to communicate with I2C and Two Wire Interface devices. 6 | paragraph=It allows the communication with I2C devices like temperature sensors, realtime clocks and many others using SDA (Data Line) and SCL (Clock Line). 7 | category=Communication 8 | url=http://www.arduino.cc/en/Reference/Wire 9 | architectures=megaavr 10 | 11 | -------------------------------------------------------------------------------- /libraries/Wire/src/Wire.h: -------------------------------------------------------------------------------- 1 | /* 2 | TwoWire.h - TWI/I2C library for Arduino & Wiring 3 | Copyright (c) 2006 Nicholas Zambetti. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | 19 | Modified 2012 by Todd Krein (todd@krein.org) to implement repeated starts 20 | */ 21 | 22 | #ifndef TwoWire_h 23 | #define TwoWire_h 24 | 25 | #include 26 | #include 27 | 28 | #define BUFFER_LENGTH 128 29 | 30 | // WIRE_HAS_END means Wire has end() 31 | #define WIRE_HAS_END 1 32 | 33 | class TwoWire : public HardwareI2C 34 | { 35 | private: 36 | static uint8_t rxBuffer[]; 37 | static uint8_t rxBufferIndex; 38 | static uint8_t rxBufferLength; 39 | 40 | static uint8_t txAddress; 41 | static uint8_t txBuffer[]; 42 | static uint8_t txBufferIndex; 43 | static uint8_t txBufferLength; 44 | 45 | static uint8_t transmitting; 46 | static void (*user_onRequest)(void); 47 | static void (*user_onReceive)(int); 48 | static uint8_t onRequestService(void); 49 | static void onReceiveService(int); 50 | public: 51 | TwoWire(); 52 | void begin(); 53 | void begin(uint8_t); 54 | void begin(int); 55 | void end(); 56 | void setClock(uint32_t); 57 | void beginTransmission(uint8_t); 58 | void beginTransmission(int); 59 | uint8_t endTransmission(void); 60 | uint8_t endTransmission(bool); 61 | size_t requestFrom(uint8_t, size_t); 62 | size_t requestFrom(uint8_t, size_t, bool); 63 | size_t requestFrom(int, int); 64 | size_t requestFrom(int, int, int); 65 | virtual size_t write(uint8_t); 66 | virtual size_t write(const uint8_t *, size_t); 67 | virtual int available(void); 68 | virtual int read(void); 69 | virtual int peek(void); 70 | virtual void flush(void); 71 | void onReceive( void (*)(int) ); 72 | void onRequest( void (*)(void) ); 73 | 74 | inline size_t write(unsigned long n) { return write((uint8_t)n); } 75 | inline size_t write(long n) { return write((uint8_t)n); } 76 | inline size_t write(unsigned int n) { return write((uint8_t)n); } 77 | inline size_t write(int n) { return write((uint8_t)n); } 78 | using Print::write; 79 | }; 80 | 81 | extern TwoWire Wire; 82 | 83 | #endif 84 | 85 | -------------------------------------------------------------------------------- /libraries/Wire/src/utility/twi.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoCore-megaavr/5e639ee40afa693354d3d056ba7fb795a8948c11/libraries/Wire/src/utility/twi.c -------------------------------------------------------------------------------- /libraries/Wire/src/utility/twi.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arduino/ArduinoCore-megaavr/5e639ee40afa693354d3d056ba7fb795a8948c11/libraries/Wire/src/utility/twi.h -------------------------------------------------------------------------------- /post_install.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | set ARGS=/A /SE /SW /SA 3 | if "%PROCESSOR_ARCHITECTURE%" == "AMD64" ( 4 | drivers\dpinst-amd64.exe %ARGS% 5 | ) ELSE IF "%PROCESSOR_ARCHITEW6432%" == "AMD64" ( 6 | drivers\dpinst-amd64.exe %ARGS% 7 | ) ELSE ( 8 | drivers\dpinst-x86.exe %ARGS% 9 | ) 10 | exit /b 0 11 | -------------------------------------------------------------------------------- /post_install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | megaAVR_rules () { 4 | echo "" 5 | echo "# Arduino Mega AVR boards bootloader mode udev rules" 6 | echo "" 7 | cat < /etc/udev/rules.d/60-arduino-megaAVR.rules 23 | 24 | # reload udev rules 25 | echo "Reload rules..." 26 | udevadm control --reload-rules 27 | udevadm trigger 28 | 29 | -------------------------------------------------------------------------------- /programmers.txt: -------------------------------------------------------------------------------- 1 | medbg.name=Onboard Atmel mEDBG (UNO WiFi Rev2) 2 | medbg.communication=usb 3 | medbg.protocol=xplainedmini_updi 4 | medbg.program.protocol=xplainedmini_updi 5 | medbg.program.tool=avrdude 6 | medbg.program.tool.default=avrdude 7 | medbg.program.extra_params=-Pusb 8 | -------------------------------------------------------------------------------- /variants/nona4809/timers.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMERS_H__ 2 | #define __TIMERS_H__ 3 | 4 | #define TIME_TRACKING_TIMER_PERIOD 0xFF 5 | #define TIME_TRACKING_TICKS_PER_OVF (TIME_TRACKING_TIMER_PERIOD + 1) // Timer ticks per overflow of TCB3 6 | #define TIME_TRACKING_TIMER_DIVIDER 64 // Clock divider for TCB0 7 | #define TIME_TRACKING_CYCLES_PER_OVF (TIME_TRACKING_TICKS_PER_OVF * TIME_TRACKING_TIMER_DIVIDER) 8 | 9 | #define PWM_TIMER_PERIOD 0xFF // For frequency 10 | #define PWM_TIMER_COMPARE 0x80 // For duty cycle 11 | 12 | #endif -------------------------------------------------------------------------------- /variants/nona4809/variant.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pins_arduino.h" 4 | #include "api/Common.h" 5 | 6 | #define FORCE_INLINE __attribute__((always_inline)) inline 7 | 8 | void setup_timers() { 9 | 10 | // TYPE A TIMER 11 | 12 | // PORTMUX setting for TCA -> all outputs [0:2] point to PORTB pins [0:2] 13 | PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTB_gc; 14 | 15 | // Setup timers for single slope PWM, but do not enable, will do in analogWrite() 16 | TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc; 17 | 18 | // Period setting, 16 bit register but val resolution is 8 bit 19 | TCA0.SINGLE.PER = PWM_TIMER_PERIOD; 20 | 21 | // Default duty 50%, will re-assign in analogWrite() 22 | TCA0.SINGLE.CMP0BUF = PWM_TIMER_COMPARE; 23 | TCA0.SINGLE.CMP1BUF = PWM_TIMER_COMPARE; 24 | TCA0.SINGLE.CMP2BUF = PWM_TIMER_COMPARE; 25 | 26 | // Use DIV64 prescaler (giving 250kHz clock), enable TCA timer 27 | TCA0.SINGLE.CTRLA = (TCA_SINGLE_CLKSEL_DIV64_gc) | (TCA_SINGLE_ENABLE_bm); 28 | 29 | // TYPE B TIMERS 30 | 31 | // Setup TCB0 routing 32 | #if defined(TCB0) 33 | PORTMUX.TCBROUTEA |= PORTMUX_TCB0_bm; // Route signal to PF4 34 | #endif 35 | 36 | // Setup TCB1 routing 37 | #if defined(TCB1) 38 | PORTMUX.TCBROUTEA |= PORTMUX_TCB1_bm; // Route signal to PF5 39 | #endif 40 | 41 | // Start with TCB0 42 | TCB_t *timer_B = (TCB_t *)&TCB0; 43 | 44 | // Find end timer 45 | #if defined(TCB3) 46 | TCB_t *timer_B_end = (TCB_t *)&TCB3; 47 | #elif defined(TCB2) 48 | TCB_t *timer_B_end = (TCB_t *)&TCB2; 49 | #elif defined(TCB1) 50 | TCB_t *timer_B_end = (TCB_t *)&TCB1; 51 | #else 52 | TCB_t *timer_B_end = (TCB_t *)&TCB0; 53 | #endif 54 | 55 | // Timer B Setup loop for TCB[0:3] 56 | do 57 | { 58 | // 8 bit PWM mode, but do not enable output yet, will do in analogWrite() 59 | timer_B->CTRLB = (TCB_CNTMODE_PWM8_gc); 60 | 61 | // Assign 8-bit period 62 | timer_B->CCMPL = PWM_TIMER_PERIOD; 63 | 64 | // default duty 50%, set when output enabled 65 | timer_B->CCMPH = PWM_TIMER_COMPARE; 66 | 67 | // Use TCA clock (250kHz) and enable 68 | // (sync update commented out, might try to synchronize later 69 | timer_B->CTRLA = (TCB_CLKSEL_CLKTCA_gc) 70 | //|(TCB_SYNCUPD_bm) 71 | |(TCB_ENABLE_bm); 72 | 73 | // Increment pointer to next TCB instance 74 | timer_B++; 75 | 76 | // Stop when pointing to TCB3 77 | } while (timer_B <= timer_B_end); 78 | 79 | // Stuff for synchronizing PWM timers 80 | // // Restart TCA to sync TCBs 81 | // // should not be needed 82 | // TCA0.SINGLE.CTRLESET = TCA_SINGLE_CMD_RESTART_gc; 83 | // TCA0.SINGLE.CTRLECLR = TCA_SINGLE_CMD_RESTART_gc; 84 | // 85 | // timer_B = (TCB_t *)&TCB0; 86 | // 87 | // // TCB are sync to TCA, remove setting 88 | // for (uint8_t digitial_pin_timer = (TIMERB0 - TIMERB0); 89 | // digitial_pin_timer < (TIMERB3 - TIMERB0); 90 | // digitial_pin_timer++) 91 | // { 92 | // // disable sync with tca 93 | // timer_B->CTRLA &= ~ (TCB_SYNCUPD_bm); 94 | // 95 | // // Add offset to register 96 | // timer_B++; 97 | // 98 | // } 99 | } 100 | 101 | FORCE_INLINE bool isDoubleBondedActive(uint8_t pin) { 102 | (void)pin; 103 | 104 | /* Check if TWI is operating on double bonded pin (Master Enable is high 105 | in both Master and Slave mode for bus error detection, so this can 106 | indicate an active state for Wire) */ 107 | //if(((pin == PIN_A4) || (pin == PIN_A5)) && (TWI0.MCTRLA & TWI_ENABLE_bm)) return true; 108 | 109 | /* Special check for SPI_SS double bonded pin -- no action if SPI is active 110 | (Using SPI Enable bit as indicator of SPI activity) */ 111 | //if((pin == 10) && (SPI0.CTRLA & SPI_ENABLE_bm)) return true; 112 | 113 | return false; 114 | } 115 | 116 | void initVariant() { 117 | } 118 | -------------------------------------------------------------------------------- /variants/uno2018/timers.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMERS_H__ 2 | #define __TIMERS_H__ 3 | 4 | #define TIME_TRACKING_TIMER_PERIOD 0xFF 5 | #define TIME_TRACKING_TICKS_PER_OVF (TIME_TRACKING_TIMER_PERIOD + 1) // Timer ticks per overflow of TCB3 6 | #define TIME_TRACKING_TIMER_DIVIDER 64 // Clock divider for TCB0 7 | #define TIME_TRACKING_CYCLES_PER_OVF (TIME_TRACKING_TICKS_PER_OVF * TIME_TRACKING_TIMER_DIVIDER) 8 | 9 | #define PWM_TIMER_PERIOD 0xFF // For frequency 10 | #define PWM_TIMER_COMPARE 0x80 // For duty cycle 11 | 12 | #endif -------------------------------------------------------------------------------- /variants/uno2018/variant.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "pins_arduino.h" 4 | #include "api/Common.h" 5 | 6 | #define FORCE_INLINE __attribute__((always_inline)) inline 7 | 8 | void setup_timers() { 9 | 10 | // TYPE A TIMER 11 | 12 | // PORTMUX setting for TCA -> all outputs [0:2] point to PORTB pins [0:2] 13 | PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTB_gc; 14 | 15 | // Setup timers for single slope PWM, but do not enable, will do in analogWrite() 16 | TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_SINGLESLOPE_gc; 17 | 18 | // Period setting, 16 bit register but val resolution is 8 bit 19 | TCA0.SINGLE.PER = PWM_TIMER_PERIOD; 20 | 21 | // Default duty 50%, will re-assign in analogWrite() 22 | TCA0.SINGLE.CMP0BUF = PWM_TIMER_COMPARE; 23 | TCA0.SINGLE.CMP1BUF = PWM_TIMER_COMPARE; 24 | TCA0.SINGLE.CMP2BUF = PWM_TIMER_COMPARE; 25 | 26 | // Use DIV64 prescaler (giving 250kHz clock), enable TCA timer 27 | TCA0.SINGLE.CTRLA = (TCA_SINGLE_CLKSEL_DIV64_gc) | (TCA_SINGLE_ENABLE_bm); 28 | 29 | // TYPE B TIMERS 30 | 31 | // Setup TCB0 routing 32 | #if defined(TCB0) 33 | PORTMUX.TCBROUTEA |= PORTMUX_TCB0_bm; // Route signal to PF4 34 | #endif 35 | 36 | // Setup TCB1 routing 37 | #if defined(TCB1) 38 | PORTMUX.TCBROUTEA |= PORTMUX_TCB1_bm; // Route signal to PF5 39 | #endif 40 | 41 | // Start with TCB0 42 | TCB_t *timer_B = (TCB_t *)&TCB0; 43 | 44 | // Find end timer 45 | #if defined(TCB3) 46 | TCB_t *timer_B_end = (TCB_t *)&TCB3; 47 | #elif defined(TCB2) 48 | TCB_t *timer_B_end = (TCB_t *)&TCB2; 49 | #elif defined(TCB1) 50 | TCB_t *timer_B_end = (TCB_t *)&TCB1; 51 | #else 52 | TCB_t *timer_B_end = (TCB_t *)&TCB0; 53 | #endif 54 | 55 | // Timer B Setup loop for TCB[0:3] 56 | do 57 | { 58 | // 8 bit PWM mode, but do not enable output yet, will do in analogWrite() 59 | timer_B->CTRLB = (TCB_CNTMODE_PWM8_gc); 60 | 61 | // Assign 8-bit period 62 | timer_B->CCMPL = PWM_TIMER_PERIOD; 63 | 64 | // default duty 50%, set when output enabled 65 | timer_B->CCMPH = PWM_TIMER_COMPARE; 66 | 67 | // Use TCA clock (250kHz) and enable 68 | // (sync update commented out, might try to synchronize later 69 | timer_B->CTRLA = (TCB_CLKSEL_CLKTCA_gc) 70 | //|(TCB_SYNCUPD_bm) 71 | |(TCB_ENABLE_bm); 72 | 73 | // Increment pointer to next TCB instance 74 | timer_B++; 75 | 76 | // Stop when pointing to TCB3 77 | } while (timer_B <= timer_B_end); 78 | 79 | // Stuff for synchronizing PWM timers 80 | // // Restart TCA to sync TCBs 81 | // // should not be needed 82 | // TCA0.SINGLE.CTRLESET = TCA_SINGLE_CMD_RESTART_gc; 83 | // TCA0.SINGLE.CTRLECLR = TCA_SINGLE_CMD_RESTART_gc; 84 | // 85 | // timer_B = (TCB_t *)&TCB0; 86 | // 87 | // // TCB are sync to TCA, remove setting 88 | // for (uint8_t digitial_pin_timer = (TIMERB0 - TIMERB0); 89 | // digitial_pin_timer < (TIMERB3 - TIMERB0); 90 | // digitial_pin_timer++) 91 | // { 92 | // // disable sync with tca 93 | // timer_B->CTRLA &= ~ (TCB_SYNCUPD_bm); 94 | // 95 | // // Add offset to register 96 | // timer_B++; 97 | // 98 | // } 99 | } 100 | 101 | FORCE_INLINE bool isDoubleBondedActive(uint8_t pin) { 102 | (void)pin; 103 | 104 | /* Check if TWI is operating on double bonded pin (Master Enable is high 105 | in both Master and Slave mode for bus error detection, so this can 106 | indicate an active state for Wire) */ 107 | //if(((pin == PIN_A4) || (pin == PIN_A5)) && (TWI0.MCTRLA & TWI_ENABLE_bm)) return true; 108 | 109 | /* Special check for SPI_SS double bonded pin -- no action if SPI is active 110 | (Using SPI Enable bit as indicator of SPI activity) */ 111 | //if((pin == 10) && (SPI0.CTRLA & SPI_ENABLE_bm)) return true; 112 | 113 | return false; 114 | } 115 | 116 | void initVariant() { 117 | // NINA - SPI boot 118 | pinMode(NINA_GPIO0, OUTPUT); 119 | digitalWrite(NINA_GPIO0, HIGH); 120 | 121 | // disable the NINA 122 | pinMode(NINA_RESETN, OUTPUT); 123 | digitalWrite(NINA_RESETN, HIGH); 124 | 125 | // NINA SS HIGH by default 126 | pinMode(SPIWIFI_SS, OUTPUT); 127 | digitalWrite(SPIWIFI_SS, HIGH); 128 | 129 | // IMU SS HIGH by default 130 | pinMode(SPIIMU_SS, OUTPUT); 131 | digitalWrite(SPIIMU_SS, HIGH); 132 | } 133 | --------------------------------------------------------------------------------