Compare commits
9 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
251f76ad66 | ||
|
|
c4bb46002a | ||
|
|
6ec89e5911 | ||
|
|
f6a4451e66 | ||
|
|
ecf801eb9d | ||
|
|
5a27c5dc44 | ||
|
|
fee7b4cf35 | ||
|
|
45013af3a3 | ||
|
|
f4cedd7e48 |
349 changed files with 1228 additions and 30203 deletions
95
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
95
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -1,95 +0,0 @@
|
||||||
name: Bug Report
|
|
||||||
description: Report a problem
|
|
||||||
labels: 'Bug'
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thanks for taking the time to fill out this bug report!
|
|
||||||
It's okay to leave some blank if it doesn't apply to your problem.
|
|
||||||
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: Operating System
|
|
||||||
options:
|
|
||||||
- Linux
|
|
||||||
- MacOS
|
|
||||||
- RaspberryPi OS
|
|
||||||
- Windows 7
|
|
||||||
- Windows 10
|
|
||||||
- Windows 11
|
|
||||||
- Others
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: Arduino IDE version
|
|
||||||
placeholder: e.g Arduino 1.8.15
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: Board
|
|
||||||
placeholder: e.g Metro M4 Express
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: ArduinoCore version
|
|
||||||
description: Can be found under "Board Manager" menu
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Sketch as ATTACHED TXT
|
|
||||||
placeholder: |
|
|
||||||
e.g examples/MassStorage/msc_ramdisk.
|
|
||||||
If it is custom sketch, please provide it as **ATTACHED** files or link to it.
|
|
||||||
Pasting raw long code that hurts readability can get your issue **closed**
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Compiled Log as ATTACHED TXT
|
|
||||||
placeholder: |
|
|
||||||
Compiled log from Arduino IDE as **ATTACHED** txt.
|
|
||||||
Pasting raw long log that hurts readability can get your issue **closed**
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: What happened ?
|
|
||||||
placeholder: A clear and concise description of what the bug is.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: How to reproduce ?
|
|
||||||
placeholder: |
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. See error
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Debug Log as ATTACHED TXT
|
|
||||||
placeholder: |
|
|
||||||
Debug log where the issue occurred as attached txt file, best with comments to explain the actual events.
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Screenshots
|
|
||||||
description: If applicable, add screenshots to help explain your problem.
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
|
|
@ -1,5 +0,0 @@
|
||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: Adafruit Support Forum
|
|
||||||
url: https://forums.adafruit.com
|
|
||||||
about: If you have other questions or need help, post it here.
|
|
||||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
|
@ -1,20 +0,0 @@
|
||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: Feature
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
||||||
|
|
||||||
**Describe the solution you'd like**
|
|
||||||
A clear and concise description of what you want to happen.
|
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context or screenshots about the feature request here.
|
|
||||||
61
.github/workflows/githubci.yml
vendored
61
.github/workflows/githubci.yml
vendored
|
|
@ -1,61 +0,0 @@
|
||||||
name: Build
|
|
||||||
|
|
||||||
on: [pull_request, push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
board:
|
|
||||||
# Alphabetical order
|
|
||||||
- 'circuitplayground_m0'
|
|
||||||
- 'feather_m4_can'
|
|
||||||
- 'hallowing'
|
|
||||||
- 'hallowing_m4'
|
|
||||||
- 'metro_m0'
|
|
||||||
- 'metro_m4'
|
|
||||||
- 'pybadge_m4'
|
|
||||||
- 'pygamer_m4'
|
|
||||||
- 'pyportal_m4'
|
|
||||||
- 'pyportal_m4_titano'
|
|
||||||
# with TinyUSB
|
|
||||||
- 'metro_m0:usbstack=tinyusb'
|
|
||||||
- 'metro_m4:speed=120,usbstack=tinyusb'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: 'true'
|
|
||||||
|
|
||||||
- name: Install Arduino CLI and Tools
|
|
||||||
run: |
|
|
||||||
# make all our directories we need for files and libraries
|
|
||||||
mkdir $HOME/.arduino15
|
|
||||||
mkdir $HOME/.arduino15/packages
|
|
||||||
mkdir $HOME/Arduino
|
|
||||||
mkdir $HOME/Arduino/libraries
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
|
|
||||||
echo "$GITHUB_WORKSPACE/bin" >> $GITHUB_PATH
|
|
||||||
|
|
||||||
- name: Install BSP and Libraries
|
|
||||||
env:
|
|
||||||
BSP_URL: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
|
|
||||||
BSP_PATH: .arduino15/packages/adafruit/hardware/samd
|
|
||||||
run: |
|
|
||||||
arduino-cli config init
|
|
||||||
arduino-cli core update-index
|
|
||||||
arduino-cli core update-index --additional-urls $BSP_URL
|
|
||||||
arduino-cli core install arduino:samd --additional-urls $BSP_URL
|
|
||||||
arduino-cli core install adafruit:samd --additional-urls $BSP_URL
|
|
||||||
# Replace release BSP with our code
|
|
||||||
BSP_VERSION=`eval ls $HOME/$BSP_PATH`
|
|
||||||
rm -r $HOME/$BSP_PATH/*
|
|
||||||
ln -s $GITHUB_WORKSPACE $HOME/$BSP_PATH/$BSP_VERSION
|
|
||||||
arduino-cli lib install "Adafruit NeoPixel" "Adafruit seesaw Library" "Adafruit SPIFlash" "FlashStorage" "MIDI Library" "SD" "SdFat - Adafruit Fork"
|
|
||||||
|
|
||||||
- name: Build examples
|
|
||||||
run: python3 tools/build_all.py ${{ matrix.board }}
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -2,5 +2,4 @@
|
||||||
*.atsuo
|
*.atsuo
|
||||||
|
|
||||||
bootloaders/*/build/
|
bootloaders/*/build/
|
||||||
*~
|
*~
|
||||||
/libraries/**/build/
|
|
||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -1,6 +0,0 @@
|
||||||
[submodule "libraries/Adafruit_TinyUSB_Arduino"]
|
|
||||||
path = libraries/Adafruit_TinyUSB_Arduino
|
|
||||||
url = https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
|
|
||||||
[submodule "libraries/Adafruit_ZeroDMA"]
|
|
||||||
path = libraries/Adafruit_ZeroDMA
|
|
||||||
url = https://github.com/adafruit/Adafruit_ZeroDMA
|
|
||||||
35
CHANGELOG
35
CHANGELOG
|
|
@ -1,40 +1,5 @@
|
||||||
SAMD CORE ?.?.?? ????.??.??
|
SAMD CORE ?.?.?? ????.??.??
|
||||||
|
|
||||||
SAMD CORE 1.6.21 2019.04.01
|
|
||||||
|
|
||||||
* MKR boards: changed I2C to sercom2, SPI1 + Serial2 to sercom4
|
|
||||||
* Improved accuracy of delay() function. Thanks @BenF
|
|
||||||
* MKR 1500: Changed SARA module to be powered off on boot
|
|
||||||
|
|
||||||
SAMD CORE 1.6.20 2018.11.28
|
|
||||||
|
|
||||||
* Replaced boolean type with bool in examples. Thanks @per1234
|
|
||||||
* Added c++ linker command to allow to include libstdc++ when linking. Thanks @helmut64
|
|
||||||
* CPX driver fixes. Thanks @dhalbert
|
|
||||||
* I2S: Changed library to use 8 MHz oscillator source if 48MHz divider does not fit in 8 bits
|
|
||||||
* UART: Added frame error handling
|
|
||||||
* USB: Fixed memory leak on reconnects
|
|
||||||
* SDU: Added support for Arduino M0. Thanks @jandrassy
|
|
||||||
* Added arduinoOTA upload keys for Arduino M0. Thanks @jandrassy
|
|
||||||
* USB: Fixed USB Host failures and fixed memory overwrite in USBHost. Thanks @gdsports
|
|
||||||
* USB: Added method to return USB error code. Thanks @MarkFischer
|
|
||||||
* CDC: Clear line state on end()
|
|
||||||
* USB: Added USB device end() method
|
|
||||||
* Removed requirement that the DAC is on A0. Thanks @GabrielNotman
|
|
||||||
* Added alternate ports 44, 45 to make the SWCLK and SWDIO pins available on the Zero. Thanks @helmut64
|
|
||||||
* Added defines for MKR pin layout
|
|
||||||
* Fixed freeze in tone()
|
|
||||||
* Added MKR NB 1500 variant and bootloader
|
|
||||||
* Increased the default serial buffer size to 256
|
|
||||||
|
|
||||||
SAMD CORE 1.6.19 2018.07.11
|
|
||||||
|
|
||||||
* Fixed bootloader tools for .org boards
|
|
||||||
* M0: Updated pin definitions for D6, D7 and D13 to match Zero
|
|
||||||
* SPI: Fixed interrupt mask to block. Thanks @ggajoch
|
|
||||||
* Added MKR WiFi 1010 variant and bootloader
|
|
||||||
* Updated Windows Drivers to 1.4.0 and re-signed Adafruit_Circuit_Playground_Express.inf
|
|
||||||
|
|
||||||
SAMD CORE 1.6.18 2018.03.05
|
SAMD CORE 1.6.18 2018.03.05
|
||||||
|
|
||||||
* Wire: Added support for general call (broadcast)
|
* Wire: Added support for general call (broadcast)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
# Arduino Core for SAMD21 and SAMD51 CPU
|
# Arduino Core for SAMD21 and SAMD51 CPU
|
||||||
|
|
||||||
[](https://github.com/adafruit/ArduinoCore-samd/actions)
|
|
||||||
|
|
||||||
This repository contains the source code and configuration files of the Arduino Core
|
This repository contains the source code and configuration files of the Arduino Core
|
||||||
for Atmel's SAMD21 and SAMD51 processor (used on the Arduino/Genuino Zero, MKR1000 and MKRZero boards).
|
for Atmel's SAMD21 and SAMD51 processor (used on the Arduino/Genuino Zero, MKR1000 and MKRZero boards).
|
||||||
|
|
||||||
|
|
|
||||||
2386
boards.txt
2386
boards.txt
File diff suppressed because it is too large
Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,502 +0,0 @@
|
||||||
:10000000FC7F0020810B0000710B0000750B0000CD
|
|
||||||
:1000100000000000000000000000000000000000E0
|
|
||||||
:10002000000000000000000000000000790B00004C
|
|
||||||
:1000300000000000000000007D0B0000D50C000057
|
|
||||||
:1000400010B5064C2378002B07D1054B002B02D0AE
|
|
||||||
:10005000044800E000BF0123237010BD5C000020B5
|
|
||||||
:1000600000000000D41E000008B5084B002B03D090
|
|
||||||
:100070000748084900E000BF07480368002B03D089
|
|
||||||
:10008000064B002B00D0984708BDC046000000007A
|
|
||||||
:10009000D41E000060000020580000200000000076
|
|
||||||
:1000A000064B0322104002040549586808401043DB
|
|
||||||
:1000B0005860DA695107FCD47047C0460008004216
|
|
||||||
:1000C000FFFFFCFF38B5284A284B5A805A7852B2B5
|
|
||||||
:1000D000002AFBDB264B04211A6A264D0A431A62CA
|
|
||||||
:1000E0002B68012213432B602A680123214C1A42FA
|
|
||||||
:1000F000FAD1E2691A42F7D11423236041001E4865
|
|
||||||
:1001000001F00CFD421EE068FF231A4098431043A3
|
|
||||||
:10011000E0602368022213432360EA69154B9107CC
|
|
||||||
:10012000FBD45A8B30218A4310210A435A83EB694E
|
|
||||||
:1001300001205A07FBD4114B02241A7802431A708B
|
|
||||||
:100140000F4B0F22197891431970197821431970B8
|
|
||||||
:100150000C490C782043087019780A401A701A78F4
|
|
||||||
:1001600020210A431A7038BD14400000000C0040E2
|
|
||||||
:100170000004004000080042006CDC0248440041DA
|
|
||||||
:100180003444004149440041F7B500230F1C01925B
|
|
||||||
:100190001D1C994254D001212A4E4000084333705F
|
|
||||||
:1001A000C1B2294B0322588B1C1C000910400128A6
|
|
||||||
:1001B00004D05B8B1B091A40022AF2D1606AC00A84
|
|
||||||
:1001C000C00208436062217E1F4B0122880708D4C9
|
|
||||||
:1001D000197E1142F7D05968C02292020A435A6030
|
|
||||||
:1001E00003E05B8B9B08134201D0002528E03270AE
|
|
||||||
:1001F000237E9907FCD5154A154B117801251970F6
|
|
||||||
:100200006268BD4212D0134B022013406360FFF7B7
|
|
||||||
:1002100047FF33785A1C3270227E9007FCD50B4979
|
|
||||||
:100220000B480A780135C254EDB2E9E78023DB02BE
|
|
||||||
:10023000134363600199002902D00320FFF730FFC8
|
|
||||||
:10024000281CFEBD7800002000080042280800425B
|
|
||||||
:1002500099000020FFFFFBFF024B00221870024BA9
|
|
||||||
:100260001A7070477A00002079000020F8B5274BFB
|
|
||||||
:100270001C786400E4B2264B03215D8B1A1C2D0907
|
|
||||||
:100280000D40012D04D05B8B1B0919400229F2D1CE
|
|
||||||
:10029000536ADB0ADB0223435362117E01231942B6
|
|
||||||
:1002A000FBD01B49498B8908194204D00320FFF772
|
|
||||||
:1002B000F7FE022427E017490D782B1C002B11D0E4
|
|
||||||
:1002C000154EEC1A365D154C2670114E177E012422
|
|
||||||
:1002D000768B274202D12642F7D00BE0B6082642A1
|
|
||||||
:1002E0000ED007E00B701C1C00280CD00320FFF779
|
|
||||||
:1002F000D7FE08E003200B700324FFF7D1FE02E0D5
|
|
||||||
:10030000013BDBB2DAE7201CF8BDC0467A000020D2
|
|
||||||
:1003100000080042790000207B00002028080042ED
|
|
||||||
:10032000034A1378591C1170024AD05401207047B7
|
|
||||||
:10033000790000207B000020154A164B1178002917
|
|
||||||
:1003400009D11549187809784118C9B21970802067
|
|
||||||
:1003500012494003C86111780131C9B2117019788E
|
|
||||||
:10036000F02902D81978092909D80B4908784042A0
|
|
||||||
:10037000C0B20870187809784118C9B2197012789B
|
|
||||||
:100380001B789A4203D18022044B5203DA617047F2
|
|
||||||
:100390007D000020010000200000002000440041FA
|
|
||||||
:1003A00010B5041C6B20FFF757FF201CFFF7B8FFA8
|
|
||||||
:1003B0000120FFF75BFF01210A1C6B20FFF7E4FE21
|
|
||||||
:1003C000014B187810BDC0469900002038B5051CB7
|
|
||||||
:1003D0006B200C1CFFF740FF281CFFF7A1FF201C1F
|
|
||||||
:1003E000FFF79EFF0120FFF741FF022038BD08B54F
|
|
||||||
:1003F0000520FFF7D5FFCE23011C19400520FFF78C
|
|
||||||
:10040000E5FF012008BD000010B5041C0020FFF727
|
|
||||||
:10041000C7FF78232D4A9843C1B2944242D018D8DE
|
|
||||||
:100420002B4B9C4238D009D82A4B9C4230D02A4BC7
|
|
||||||
:100430009C422FD0294B9C4245D13FE0284B9C4207
|
|
||||||
:100440002CD0284B9C422BD0274B9C423BD12023C5
|
|
||||||
:1004500033E0264A94422BD00AD8254B9C4223D025
|
|
||||||
:10046000244B9C4222D0244B9C422CD1402324E09C
|
|
||||||
:10047000224A94421ED004D8214B9C4223D16023AF
|
|
||||||
:100480001BE0204A944217D01F4A944215D01AE02C
|
|
||||||
:10049000082312E0102310E018230EE028230CE0BC
|
|
||||||
:1004A00030230AE0382308E0482306E0502304E024
|
|
||||||
:1004B000582302E0682300E0702319430020FFF76F
|
|
||||||
:1004C00085FF012000E0002010BDC046581100004B
|
|
||||||
:1004D00018100000780F0000C80F0000280F00005F
|
|
||||||
:1004E000B810000008110000681000009812000009
|
|
||||||
:1004F000F811000048120000A81100003813000095
|
|
||||||
:10050000E812000088130000D813000010B5041C86
|
|
||||||
:100510000020FFF745FF07239843E122C1B2920074
|
|
||||||
:10052000944220D008D8962C18D0FA235B009C4225
|
|
||||||
:1005300017D0642C22D11CE0114A944215D005D862
|
|
||||||
:100540009623DB009C4219D1042311E0FA22D20049
|
|
||||||
:1005500094420CD00B4A94420AD00FE0012421436C
|
|
||||||
:1005600007E0022304E0032302E0052300E0062362
|
|
||||||
:1005700019430020FFF72AFF012000E0002010BDF2
|
|
||||||
:10058000DC050000B80B000070B504AC267805ACA3
|
|
||||||
:100590002578441EA041C401002901D040210C430C
|
|
||||||
:1005A000002A01D020221443002B01D010231C4329
|
|
||||||
:1005B000002E01D008231C43002D01D004231C432E
|
|
||||||
:1005C0000220FFF7EDFE0125011C294021430220F6
|
|
||||||
:1005D000FFF7FCFE281C70BD10B5041C0420FFF7BB
|
|
||||||
:1005E000DFFE03231840084B9C4204D0074B9C427B
|
|
||||||
:1005F00008D1B02100E0982101430420FFF7E6FE76
|
|
||||||
:10060000012000E0002010BD10100000701000005C
|
|
||||||
:1006100008B50120FFF7C4FECF23011C19400120BB
|
|
||||||
:10062000FFF7D4FE012008BD07B5FFF7E0FEFFF796
|
|
||||||
:10063000EFFF0948FFF7E8FEFA20C000FFF766FF6A
|
|
||||||
:10064000002300930193181C191C1A1CFFF79CFF30
|
|
||||||
:100650000248FFF7C1FF07BD08110000101000009D
|
|
||||||
:1006600008B50348FFF72EFDFFF7DEFF08BDC046C3
|
|
||||||
:10067000A086010010B5C3699C07FCD4036802245E
|
|
||||||
:10068000A3430360C46901231C42FBD104682343D4
|
|
||||||
:1006900003600368DC07FCD4C46901231C42FBD15E
|
|
||||||
:1006A000C469DC401C42F7D1084B1A430260C3699D
|
|
||||||
:1006B0005A07FCD4C0239B0243608181C3699C0715
|
|
||||||
:1006C000FCD4036802221343036010BD0400004001
|
|
||||||
:1006D000037EDA07FCD5018570470000027E012306
|
|
||||||
:1006E0005107FBD5428B1A4207D1428BDA401A429E
|
|
||||||
:1006F00003D1428B92081A4202D0034B01221A7096
|
|
||||||
:10070000008DC0B27047C0467E00002070B50368FF
|
|
||||||
:10071000041C988B1A1C0821FF32084226D0802026
|
|
||||||
:1007200099839872112353704021144B9171507129
|
|
||||||
:100730005E68134DC0202E40800506435E605E69F2
|
|
||||||
:100740003540284358610F4818600F4818615D68AC
|
|
||||||
:100750000E4828408025AD02284358605868800B19
|
|
||||||
:100760008003586000235171237105E0137ADA0683
|
|
||||||
:1007700002D5201C00F0E8FA207970BD9C01002011
|
|
||||||
:10078000FFFFFF8F9C0000201C010020FF3F00F0B6
|
|
||||||
:10079000002303714371044B016083600B780222D4
|
|
||||||
:1007A00013430B707047C0460D07000038B5364B39
|
|
||||||
:1007B0002021DA6901200A43DA61344B06241A78D1
|
|
||||||
:1007C00002431A70324B0F2219789143197019782D
|
|
||||||
:1007D000214319702F490C782043087019780A407A
|
|
||||||
:1007E0001A701A7860210A431A702B4B2B4A5A80D0
|
|
||||||
:1007F0005A7852B2002AFBDB294B01211A780A43AE
|
|
||||||
:100800001A709A78D107FCD426480268510B1F222F
|
|
||||||
:100810001140914200D1052111408C011D8D2249CA
|
|
||||||
:100820002940214319850468A10C0A401F2A00D1E0
|
|
||||||
:100830001D221C8D1F210A408C4322431A85026809
|
|
||||||
:100840000721D20D0A408A4200D103220A40188DA6
|
|
||||||
:100850001103164A02400A431A8519787F220A407A
|
|
||||||
:100860001A701A78042112480A431A7058621A89B9
|
|
||||||
:100870000C218A431A811A8901218A431A81002195
|
|
||||||
:10088000802201F0A4F938BD000400405844004122
|
|
||||||
:100890003C44004159440041000C00400640000027
|
|
||||||
:1008A00000500041246080003FF8FFFFFF8FFFFFF2
|
|
||||||
:1008B0009C010020F7B5141C1F4A5F0101971D1C05
|
|
||||||
:1008C000D319061C5869271C4000400F0330103311
|
|
||||||
:1008D000C74006D00F1C8022596812060A435A608E
|
|
||||||
:1008E00009E02F1C7B1E9F41144BBF01FF18381CD1
|
|
||||||
:1008F000221C01F063F901990F480835421817616D
|
|
||||||
:10090000131C5269A104920B890C92030A435A6189
|
|
||||||
:1009100059690B4A0A405A616B01F3180222DA71D5
|
|
||||||
:100920005979802252420A435A716B01F318DB79DC
|
|
||||||
:100930009A07FAD5201CFEBD9C0100201C01002056
|
|
||||||
:10094000FF3F00F0F8B51A4E051C3378141C002B3D
|
|
||||||
:1009500012D1184B184A1A645A6C920B92035A64BB
|
|
||||||
:10096000586C164A02405A64A2235B00EA5C40209D
|
|
||||||
:100970000243EA54012333704827FF37EA5D01231D
|
|
||||||
:10098000134012D00B4B5A6C9204920CA24202D22A
|
|
||||||
:100990005C6CA404A40C081C221C074901F00EF98D
|
|
||||||
:1009A0000123EB550023337000E01C1C201CF8BD14
|
|
||||||
:1009B0007F0000209C010020DC000020FF3F00F0B1
|
|
||||||
:1009C000FF3083792022002900D110221343837144
|
|
||||||
:1009D00070470000084BFF305A69920B92035A612E
|
|
||||||
:1009E00002230372827980235B4213438371037A6B
|
|
||||||
:1009F0009A07FCD57047C0469C01002080235B42CB
|
|
||||||
:100A00001943C9B28172704770B5A02303225B00FD
|
|
||||||
:100A1000C254134B134A5C6CC021144089050C432B
|
|
||||||
:100A200046255C64FF35402444550F4D30261D6437
|
|
||||||
:100A300090256D0046555D6B1540294392255963FD
|
|
||||||
:100A40006D0080214155094D1D63B0256D00445551
|
|
||||||
:100A50005C6F22405A67B2235B00C15470BDC04630
|
|
||||||
:100A60009C010020FFFFFF8FDC0000205C010020C4
|
|
||||||
:100A700030B5364A1E235168082099430223194392
|
|
||||||
:100A8000516033498A6902438A613248324A90820E
|
|
||||||
:100A9000908A03439382D3689807FCD52F4B01209B
|
|
||||||
:100AA00018701878C40704D52C48407840B2002844
|
|
||||||
:100AB000F7DB01209860587840B20028FBDB284C17
|
|
||||||
:100AC00026484460587840B20028FBDB8224234843
|
|
||||||
:100AD000E4014480587840B20028FBDB908C8024ED
|
|
||||||
:100AE000A0439084D068C506FCD51E4C1A48C46249
|
|
||||||
:100AF000D4681948E506FBD5848C1B4D2C438484AF
|
|
||||||
:100B0000D4681548E506FBD5848C02252C438484E3
|
|
||||||
:100B1000D0680406FCD51048C0684506F8D5D068F2
|
|
||||||
:100B2000C406FCD500229A605A7852B2002AFBDB38
|
|
||||||
:100B30000E480A4A50605A7852B2002AFBDB002362
|
|
||||||
:100B40000B724B728B72CB7230BDC04600400041BD
|
|
||||||
:100B5000000400400C06000000080040000C0040AB
|
|
||||||
:100B600001050100B805FF7D040A0000000703002D
|
|
||||||
:100B70000EBEFEE70DBEFEE705BEFEE702BEFEE7C7
|
|
||||||
:100B80000E4A0F4838B5824204D10E4A0E4B9342AA
|
|
||||||
:100B90000ED10AE00D4C9442F7D00023D1188842C0
|
|
||||||
:100BA000F3D9E55804330D60F8E700F011F804E0DC
|
|
||||||
:100BB0009342FAD2002102C3FAE7FEE700000020C8
|
|
||||||
:100BC0005C000020AC0300205C000020D81E000068
|
|
||||||
:100BD00038B5344D2B6801331AD0334B2A1D1A60B7
|
|
||||||
:100BE000EAB2002A14D1314B197801231940304B55
|
|
||||||
:100BF0000AD118682F4A904201D1196008E01A60A2
|
|
||||||
:100C00002D4A013A002AFCD11A602C4B01221A709D
|
|
||||||
:100C1000FFF72EFF62B6FFF723FD284B284C1B7809
|
|
||||||
:100C2000002B0AD02B6883F308881E4BFF229343C6
|
|
||||||
:100C3000A3601D4B1B681B68184700F09DFD00F06A
|
|
||||||
:100C40004FF8204B802252039A601F4B1F4A051C0D
|
|
||||||
:100C50005A60216AC0220902090A12060A43226266
|
|
||||||
:100C600000229A6007221A60AB68281C9847184B2C
|
|
||||||
:100C7000002801D001221A701A78002A05D000201D
|
|
||||||
:100C800000F08CFA00F004FBFCE71B78002BEBD1A2
|
|
||||||
:100C900000F0E6FD0028E7D0012000F07FFA00F028
|
|
||||||
:100CA000F7FAFCE7002000001C0200203804004096
|
|
||||||
:100CB000FC7F00203581730748E801008000002098
|
|
||||||
:100CC00000ED00E00044004110E000E0E703000018
|
|
||||||
:100CD0008100002008B5FFF72FFB00F0C3FA08BD24
|
|
||||||
:100CE00010B5054B054C2360FFF760FD201C216803
|
|
||||||
:100CF000FFF74EFD201C10BD0050004120020020D7
|
|
||||||
:100D000070B5051CC0B0081C161C0C1C00F067FF59
|
|
||||||
:100D100040006A46032302305370107076080123A6
|
|
||||||
:100D2000E218013A11785A00002906D1281C6946B8
|
|
||||||
:100D30000023FFF7BFFD40B070BDB342F6DA68464E
|
|
||||||
:100D400081520133ECE70000F7B5BA4A0468137822
|
|
||||||
:100D5000B949271CFF37051C102038720B705378D7
|
|
||||||
:100D6000B648B74E037093783380D1783388090240
|
|
||||||
:100D70000B4333801179B34B1980517918880902DC
|
|
||||||
:100D8000084318809079B0490880D2790888120207
|
|
||||||
:100D900002430A8040227A71A84F3A78A64F120285
|
|
||||||
:100DA00038780F1C0243A9488446181C624500D1BC
|
|
||||||
:100DB000C2E020DC802149008A4200D16EE109DCDA
|
|
||||||
:100DC000812A00D192E0822A00D195E0802A00D0C9
|
|
||||||
:100DD00064E18BE081235B009A4200D1CFE000DA2E
|
|
||||||
:100DE00058E1C0239B009A4200D157E1984B9A42A8
|
|
||||||
:100DF00000D14FE152E190231B019A4269D015DCEA
|
|
||||||
:100E0000D023DB009A4222D088231B019A4269D06A
|
|
||||||
:100E1000A023DB009A4200D040E1201CFFF7DAFD5E
|
|
||||||
:100E20003188286889B2FFF7E9FD3BE1894B9A4296
|
|
||||||
:100E300000D12FE100DC31E1874B9A4200D11DE166
|
|
||||||
:100E4000864B9A4200D029E133886B7122E13388C6
|
|
||||||
:100E50001B0A012B08D10B8812222868934201D863
|
|
||||||
:100E60000A8892B27E4911E133881B0A022B08D10D
|
|
||||||
:100E70000B8843222868934201D80A8892B27949A4
|
|
||||||
:100E800004E133881B0A032B00D007E13388DBB26F
|
|
||||||
:100E9000012B17D0002B07D0022B00D0FEE00A88D0
|
|
||||||
:100EA0002868D2B2704911E0042201A86F4900F00D
|
|
||||||
:100EB00085FE3B8804222868934201D83A8892B282
|
|
||||||
:100EC00001A9E3E00A8828686949D2B2FFF718FF50
|
|
||||||
:100ED000E8E03388201C2B71FFF77CFD201CFFF716
|
|
||||||
:100EE00093FDDFE0291C01C90122CFE06149002305
|
|
||||||
:100EF0000B8028680222CAE05E4900220A80188816
|
|
||||||
:100F0000502210405C4A10701E880F20304018801C
|
|
||||||
:100F10001888032800D9C1E012781B8808335B01C8
|
|
||||||
:100F2000E418A379002A01D09B0600E0DB06DB0F62
|
|
||||||
:100F30000B8028680222A9E019887F2291434E4A3B
|
|
||||||
:100F4000C9B2117018880F21014019803188002919
|
|
||||||
:100F500000D0A3E01988002900D19FE01988032957
|
|
||||||
:100F600000D99BE012781B8808335B01E318002A44
|
|
||||||
:100F700002D020225A718DE0102159718AE0028836
|
|
||||||
:100F80007F239A433C4BD2B21A7001880F220A4049
|
|
||||||
:100F900002803288002A00D080E00288002A00D136
|
|
||||||
:100FA0007CE00288032A00D978E01B78002B1FD050
|
|
||||||
:100FB000038808335B01E3189B799A066AD5038896
|
|
||||||
:100FC000202208335B01E3181A71038808335B01A0
|
|
||||||
:100FD000E318DB795F065DD50388402208335B01A7
|
|
||||||
:100FE000E318DA710388022208335B01E3181EE07C
|
|
||||||
:100FF000038808335B01E3189B79D9064AD5038837
|
|
||||||
:10100000102208335B01E3181A71038808335B016F
|
|
||||||
:10101000E318DB799A063DD50388202208335B016B
|
|
||||||
:10102000E318DA710388012208335B01E3181A71AF
|
|
||||||
:1010300030E0C0469C000020830000208800002093
|
|
||||||
:101040008A0000208C00002086000020020300009F
|
|
||||||
:101050000103000021200000A12100002122000046
|
|
||||||
:10106000281C000004000020141C0000041C0000C8
|
|
||||||
:10107000081C000084000020820000200B88082249
|
|
||||||
:101080002868934201D80A8892B207490023FFF7E3
|
|
||||||
:1010900011FC07E0201CFFF79DFC03E0201C012150
|
|
||||||
:1010A000FFF78EFCF7BDC0464800002007B5054B92
|
|
||||||
:1010B0000122019001A91868131CFFF7FBFB012016
|
|
||||||
:1010C0000EBDC0462002002013B5054B6C46073408
|
|
||||||
:1010D0001868211C0122FFF735FC207816BDC04698
|
|
||||||
:1010E0002002002010B5074C201CFFF70FFB031C4B
|
|
||||||
:1010F0000020834205D022684823FF33D05C0123BF
|
|
||||||
:10110000184010BD2002002010B5054A0C1C031C1D
|
|
||||||
:10111000191C10680123221CFFF7CCFB201C10BDFA
|
|
||||||
:101120002002002070B5084C061C201C0D1CFFF787
|
|
||||||
:10113000EDFA0023984205D02068311C2A1CFFF7E5
|
|
||||||
:1011400001FC031C181C70BD20020020F8B50C4CDB
|
|
||||||
:10115000051C201C0E1CFFF7D9FA0023271C341C89
|
|
||||||
:1011600098420AD0002C07D0291C221C3868FFF7AF
|
|
||||||
:10117000E9FB241A2D18F5E7331C181CF8BDC046EE
|
|
||||||
:101180002002002008B5031C081C111C9847024BC4
|
|
||||||
:1011900064221A8008BDC04692000020012805D1B3
|
|
||||||
:1011A000054B064A1A60064B187004E0002802D16D
|
|
||||||
:1011B000044A014B1A607047900200205C1C00003A
|
|
||||||
:1011C00098000020A81C000030B50A1C1C4985B0FE
|
|
||||||
:1011D0000978031C00292AD0042A01D1006804E000
|
|
||||||
:1011E000022A01D1008800E00078520004A98B187F
|
|
||||||
:1011F0000B3B9C1AA3420BD00F210140092902D8B6
|
|
||||||
:101200003025294300E0373119700009013BF1E72F
|
|
||||||
:1012100001A930230B7078234B700A208B1898702B
|
|
||||||
:101220000D20D870074B04321B68D86803E00549CD
|
|
||||||
:101230000968C868191CFFF7A5FF05B030BDC04696
|
|
||||||
:101240008E0000209002002072B6EFF30883044A5B
|
|
||||||
:101250001360036883F30888436818477047C046E3
|
|
||||||
:1012600094020020084B1A88002A03D01A88013AF9
|
|
||||||
:1012700092B21A80054B1A88002A03D01A88013AC4
|
|
||||||
:1012800092B21A807047C046920000209000002061
|
|
||||||
:10129000F0B591B008A9CC4A0B1C31CA31C351CA70
|
|
||||||
:1012A00051C360CA60C3C94BC9489A687A255203C2
|
|
||||||
:1012B000520F92005258C74902609C68A4B2624320
|
|
||||||
:1012C0000C60C54900240A60C44A1460C44C2570EF
|
|
||||||
:1012D000C44CC54D2368281C1B6940219847002831
|
|
||||||
:1012E00002D0C24B64221A80C14B00221860C14B4D
|
|
||||||
:1012F0001D60C14BC04DBE4F1A602A683B689A42C0
|
|
||||||
:10130000E6D2BC4B1B681A78FF2A00D114E2232ACC
|
|
||||||
:1013100000D0EBE1B94E3378002B06D0B14BB84981
|
|
||||||
:101320001B680222D868FFF72DFFAD4B1B78532BAB
|
|
||||||
:101330003CD13B682A6893421ED9AE4801322A60EC
|
|
||||||
:101340009A1AB04B01681B6801310160AE4E9A4297
|
|
||||||
:1013500001D2326000E03360A04832680068049037
|
|
||||||
:1013600000F02CFC336829685A182A60A14A1668D4
|
|
||||||
:10137000F1181160A54A13702B68013B2B609D4B3F
|
|
||||||
:101380001A68013A1A60A14B9E4A1B7811688B4279
|
|
||||||
:101390000AD222689148C91A0068926990470028C9
|
|
||||||
:1013A00002D0924B64221A80C0468DE1522B0AD1A2
|
|
||||||
:1013B0008A48944A2368006811685B6903909847DB
|
|
||||||
:1013C0006422934B0DE04F2B05D1844B8D4A1B6853
|
|
||||||
:1013D00012681A7078E1482B05D1804B894A1B6846
|
|
||||||
:1013E00012681A8070E1572B05D17C4B854A1B6827
|
|
||||||
:1013F00012681A6068E16F2B03D1784B01211868DD
|
|
||||||
:1014000007E0682B08D1754B7E481B6802211B88BA
|
|
||||||
:101410000360FFF7D9FE57E1772B06D16F4B794870
|
|
||||||
:101420001B6804211B680360F3E7472B13D1754B3E
|
|
||||||
:101430001868FFF709FF774B1B6883F3088862B6CB
|
|
||||||
:10144000754B1B78002B00D13EE1664B06201B68D4
|
|
||||||
:101450001B68984738E1542B04D101233370614B4A
|
|
||||||
:101460001B6864E04E2B0CD13378002B06D15D4B0A
|
|
||||||
:1014700063491B680222D868FFF784FE002333709B
|
|
||||||
:1014800022E1562B57D123686449D8680122FFF71F
|
|
||||||
:1014900079FE23686249D8680322FFF773FE614D25
|
|
||||||
:1014A0002368291CD8680122FFF76CFE23685E4977
|
|
||||||
:1014B000D8680D22FFF766FE2368291CD868012230
|
|
||||||
:1014C000FFF760FE4B4F4C4D5849002339602B60AD
|
|
||||||
:1014D0003A1C281C13685E1C16601B780593002BB1
|
|
||||||
:1014E00003D0036801330360F4E73E4E2A68336893
|
|
||||||
:1014F000D868FFF747FE33684A49D8680122FFF7EA
|
|
||||||
:1015000041FE059929604A4939603A4A1368581CD6
|
|
||||||
:1015100010601B78002B04D0374B1A6801321A6018
|
|
||||||
:10152000F3E733682A68D868FFF72CFE3368D86879
|
|
||||||
:1015300033490222C6E0334A582B17D1244E264D98
|
|
||||||
:10154000366813682A68B10093420AD21F4D5808C2
|
|
||||||
:10155000E861384828801D4D287DC607FBD55B18FB
|
|
||||||
:10156000F2E7204B34491B68D868AAE0592B79D19F
|
|
||||||
:1015700012681A4B3149002A02D11B680B606CE0DB
|
|
||||||
:10158000124D086819686B68104E8025AB439208AD
|
|
||||||
:101590007360002A61D02A4B0C4D2B800B4E337D9B
|
|
||||||
:1015A000DD07FBD500230A4D2D680195AD08AB4240
|
|
||||||
:1015B00003D3244D054E358046E09342F9D09D007B
|
|
||||||
:1015C000465901334E51EEE73C1C000000400041FB
|
|
||||||
:1015D00048020020400200203C0200208C02002033
|
|
||||||
:1015E00038020020900200204C02002090000020D1
|
|
||||||
:1015F0003002002034020020440200208E0000202F
|
|
||||||
:101600009C1C0000980200209C0200202C0200205C
|
|
||||||
:10161000920000209402002098000020781C000016
|
|
||||||
:10162000A11C00007A1C0000C41C00007C1C0000EF
|
|
||||||
:10163000881C000002A5FFFF911C00009400002000
|
|
||||||
:1016400044A5FFFF04A5FFFF3F4E357DEE07FBD508
|
|
||||||
:101650009D0049194019D21A9BE73C4B3C491B6835
|
|
||||||
:10166000D8682EE05A2B2FD13A4B17681D680026F8
|
|
||||||
:10167000EF19BD4206D02878311C00F013F901356E
|
|
||||||
:10168000061CF6E7314B34491B680122D868FFF786
|
|
||||||
:1016900079FD07230F223240111C36093031092A07
|
|
||||||
:1016A00000DD07311820C0186A468154013BF1D291
|
|
||||||
:1016B000236806A9D8680822FFF764FD2368274934
|
|
||||||
:1016C000D8680322FFF75EFD254B7A221A70254B5E
|
|
||||||
:1016D00000221A60244B1B7893422DD01B4B2349C8
|
|
||||||
:1016E0001B680122D868FFF74DFD25E0111C303939
|
|
||||||
:1016F000C8B21C4B092804D81D682A01114319607F
|
|
||||||
:101700001AE0111C4139052903D81E68373A310106
|
|
||||||
:1017100006E0111C6139052904D81868573A0101FF
|
|
||||||
:101720000A4308E02C2A03D10A4A1968116001E033
|
|
||||||
:101730000B490A7000221A600D4B1A6801321A60B8
|
|
||||||
:101740000C4B1A680132D5E50040004190020020A0
|
|
||||||
:10175000951C00008C020020991C00009B1C0000BE
|
|
||||||
:1017600038020020980200208E0000209F1C0000FC
|
|
||||||
:10177000440200203402002010B51C4B01201A78CE
|
|
||||||
:10178000032402431A701A4B0F22197891431970DF
|
|
||||||
:1017900019782143197017490C782043087019787B
|
|
||||||
:1017A0000A401A701A7830210A431A70124B8021AD
|
|
||||||
:1017B0001A6A0A431A62114B114A5A805A7852B275
|
|
||||||
:1017C000002AFBDBC4220F480F499203FEF752FFA9
|
|
||||||
:1017D0000E4A002313700E4A13700E4A13700E4AFD
|
|
||||||
:1017E00013700E4A13700E4A137010BDD644004198
|
|
||||||
:1017F000BB440041D744004100040040000C0040BD
|
|
||||||
:1018000019400000001C00422AF60000A00200203F
|
|
||||||
:1018100027030020A1020020A402002028030020AA
|
|
||||||
:101820002503002008B5C1B20248FEF751FF012090
|
|
||||||
:1018300008BDC046001C0042024B187E4007C00F86
|
|
||||||
:101840007047C046001C004208B5FFF7F5FF0028AE
|
|
||||||
:10185000FBD00248FEF742FF08BDC046001C004214
|
|
||||||
:1018600008B5FFF7E9FF0023984205D0FFF7ECFF2A
|
|
||||||
:10187000031C233B5A425341181C08BD70B5041C7D
|
|
||||||
:101880000D1C4618B44204D02078FFF7CBFF01347A
|
|
||||||
:10189000F8E7281C70BD10B5041CFFF7D5FF2070B9
|
|
||||||
:1018A000012010BD0B0A5840034B4000C05A0902EA
|
|
||||||
:1018B000484080B27047C046D21C0000F7B50024F3
|
|
||||||
:1018C000051C0F1C261CBC4220D0FFF7BDFF114B8E
|
|
||||||
:1018D000C0B21B780190002B1AD1311CFFF7E2FF38
|
|
||||||
:1018E0000D4B061C1A88002A04D10C4A11782A1CB8
|
|
||||||
:1018F000002907D001996A1C2970802F02D119880C
|
|
||||||
:10190000013919800134A4B2151CDCE7301C00E059
|
|
||||||
:101910000120FEBD25030020A20200202603002096
|
|
||||||
:10192000F0B53E4E85B0002203900C1C32703C4B4B
|
|
||||||
:10193000914201D1012201E03A490C801A707F23C3
|
|
||||||
:101940001C4201D080349C43FFF77EFF3378C0B245
|
|
||||||
:10195000002B07D000253570FFF776FF3378C0B233
|
|
||||||
:10196000AB4236D1432803D0712853D01528EBD190
|
|
||||||
:10197000012300930120FFF755FF0098FFF752FF66
|
|
||||||
:1019800000998025C843C0B2FFF74CFF039B002796
|
|
||||||
:101990000293244A1388002B1DD121490193097811
|
|
||||||
:1019A000002918D10198FFF73DFF391C0198FFF776
|
|
||||||
:1019B00079FF013D071C002DEBD1000AC0B2FFF7F3
|
|
||||||
:1019C00031FFF8B2FFF72EFFFFF73EFF3378002B11
|
|
||||||
:1019D0000AD035701FE00299013B09781380029B01
|
|
||||||
:1019E000019101330293DDE7C0B2062807D1009BC5
|
|
||||||
:1019F00003990133DBB280310093803C0391002CCA
|
|
||||||
:101A0000B8D10420FFF70EFFFFF71EFF044B01259E
|
|
||||||
:101A10001C7000E00025281C05B0F0BD2503002047
|
|
||||||
:101A200026030020A2020020F0B5384C87B0002326
|
|
||||||
:101A300001902370994201D1012301E0344A1180C1
|
|
||||||
:101A4000344A642613704320FFF7ECFE324FFFF751
|
|
||||||
:101A5000F3FE002803D1002F03D0013FF7E7002F4A
|
|
||||||
:101A600003D1013E002EEED14DE00125FFF7ECFE43
|
|
||||||
:101A70002378002B38D1C0B20290012805D0042869
|
|
||||||
:101A80003DD10620FFF7CEFE39E005AE0221301C25
|
|
||||||
:101A9000FFF714FF01988021FFF710FF23780390D0
|
|
||||||
:101AA000002B18D1FFF7D0FE0702FFF7CDFEBFB223
|
|
||||||
:101AB00023783F18BFB2012B0DD0039B9F4207D163
|
|
||||||
:101AC0003378AB4204D1EB437278DBB29A4204D054
|
|
||||||
:101AD0001820FFF7A7FE002303E00620FFF7A2FE71
|
|
||||||
:101AE000029B2278002A02D0002626700BE0012BF0
|
|
||||||
:101AF00005D1019A6B1C8032DDB20192B6E7054A2E
|
|
||||||
:101B0000002313700126301C07B0F0BD2503002010
|
|
||||||
:101B1000A20200202603002000350C00002934D04A
|
|
||||||
:101B20000123002210B488422CD301242407A142AF
|
|
||||||
:101B300004D2814202D209011B01F8E7E400A1426C
|
|
||||||
:101B400004D2814202D249005B00F8E7884201D307
|
|
||||||
:101B5000401A1A434C08A04202D3001B5C082243DF
|
|
||||||
:101B60008C08A04202D3001B9C082243CC08A04250
|
|
||||||
:101B700002D3001BDC082243002803D01B0901D03C
|
|
||||||
:101B80000909E3E7101C10BC7047002801D00020B1
|
|
||||||
:101B9000C04307B4024802A14018029003BDC046EA
|
|
||||||
:101BA000190000000029F0D003B5FFF7B9FF0EBC03
|
|
||||||
:101BB0004243891A1847C0467047C04610B50023F3
|
|
||||||
:101BC000934203D0CC5CC4540133F9E710BD031C2D
|
|
||||||
:101BD0008218934202D019700133FAE7704700234C
|
|
||||||
:101BE000C25C0133002AFBD1581E7047F8B5C046CD
|
|
||||||
:101BF000F8BC08BC9E467047F8B5C046F8BC08BCA7
|
|
||||||
:101C00009E4670470403090441726475696E6F2033
|
|
||||||
:101C10004C4C430041726475696E6F204D4B5220ED
|
|
||||||
:101C20004E422031353030001201000202000040E7
|
|
||||||
:101C300041235500000201020001000008000000DD
|
|
||||||
:101C400010000000200000004000000080000000A4
|
|
||||||
:101C50000001000000020000000400002518000040
|
|
||||||
:101C600049180000391800007D180000971800007E
|
|
||||||
:101C700021190000291A0000760020004E6F7620FE
|
|
||||||
:101C8000323620323031380031343A32383A333754
|
|
||||||
:101C900000580A0D00590A0D005A00230A0D003E93
|
|
||||||
:101CA00000322E3000000000AD100000C91000000E
|
|
||||||
:101CB000E5100000091100002511000009110000C5
|
|
||||||
:101CC0004D1100005B41726475696E6F3A58595A44
|
|
||||||
:101CD0005D0000002110422063308440A550C660A2
|
|
||||||
:101CE000E770088129914AA16BB18CC1ADD1CEE1D9
|
|
||||||
:101CF000EFF13112100273325222B5529442F77250
|
|
||||||
:101D0000D662399318837BB35AA3BDD39CC3FFF328
|
|
||||||
:101D1000DEE36224433420040114E664C774A4445F
|
|
||||||
:101D200085546AA54BB528850995EEE5CFF5ACC578
|
|
||||||
:101D30008DD55336722611163006D776F66695562F
|
|
||||||
:101D4000B4465BB77AA719973887DFF7FEE79DD7C8
|
|
||||||
:101D5000BCC7C448E5588668A778400861180228BF
|
|
||||||
:101D60002338CCC9EDD98EE9AFF9488969990AA918
|
|
||||||
:101D70002BB9F55AD44AB77A966A711A500A333A8F
|
|
||||||
:101D8000122AFDDBDCCBBFFB9EEB799B588B3BBB68
|
|
||||||
:101D90001AABA66C877CE44CC55C222C033C600C1F
|
|
||||||
:101DA000411CAEED8FFDECCDCDDD2AAD0BBD688DB8
|
|
||||||
:101DB000499D977EB66ED55EF44E133E322E511E6F
|
|
||||||
:101DC000700E9FFFBEEFDDDFFCCF1BBF3AAF599F08
|
|
||||||
:101DD000788F8891A981CAB1EBA10CD12DC14EF1A8
|
|
||||||
:101DE0006FE18010A100C230E3200450254046700E
|
|
||||||
:101DF0006760B9839893FBA3DAB33DC31CD37FE339
|
|
||||||
:101E00005EF3B1029012F322D2323542145277625D
|
|
||||||
:101E10005672EAB5CBA5A89589856EF54FE52CD508
|
|
||||||
:101E20000DC5E234C324A0148104667447642454AD
|
|
||||||
:101E30000544DBA7FAB79987B8975FE77EF71DC718
|
|
||||||
:101E40003CD7D326F2369106B016576676761546FD
|
|
||||||
:101E500034564CD96DC90EF92FE9C899E9898AB968
|
|
||||||
:101E6000ABA94458654806782768C018E10882384D
|
|
||||||
:101E7000A3287DCB5CDB3FEB1EFBF98BD89BBBAB78
|
|
||||||
:101E80009ABB754A545A376A167AF10AD01AB32A9D
|
|
||||||
:101E9000923A2EFD0FED6CDD4DCDAABD8BADE89DC8
|
|
||||||
:101EA000C98D267C076C645C454CA23C832CE01CED
|
|
||||||
:101EB000C10C1FEF3EFF5DCF7CDF9BAFBABFD98F58
|
|
||||||
:101EC000F89F176E367E554E745E932EB23ED10E3D
|
|
||||||
:081ED000F01E000000000000FC
|
|
||||||
:101ED80001140000090243000201008032090400D5
|
|
||||||
:101EE800000102020000052400100104240200057C
|
|
||||||
:101EF800240600010524010001070583030800FFEB
|
|
||||||
:101F080009040100020A00000007058102400000E0
|
|
||||||
:101F1800070502024000000000C20100000008009E
|
|
||||||
:0C1F280069000000410000000000000003
|
|
||||||
:0400000300000B816D
|
|
||||||
:00000001FF
|
|
||||||
|
|
@ -218,11 +218,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -222,11 +222,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -222,11 +222,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -222,11 +222,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -222,11 +222,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -218,11 +218,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -218,11 +218,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -222,11 +222,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -222,11 +222,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -222,11 +222,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -222,11 +222,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -226,11 +226,7 @@ void I2S_Handler ( void );
|
||||||
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
* \brief Configuration of the Cortex-M0+ Processor and Core Peripherals
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(LITTLE_ENDIAN) && (LITTLE_ENDIAN != 1)
|
#define LITTLE_ENDIAN 1
|
||||||
#error "Little Endian is already defined, but to different value than expected?!"
|
|
||||||
#else
|
|
||||||
#define LITTLE_ENDIAN 1
|
|
||||||
#endif
|
|
||||||
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */
|
||||||
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
#define __MPU_PRESENT 0 /*!< MPU present or not */
|
||||||
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */
|
||||||
|
|
|
||||||
|
|
@ -20,35 +20,6 @@
|
||||||
#ifndef _BOARD_DEFINITIONS_H_
|
#ifndef _BOARD_DEFINITIONS_H_
|
||||||
#define _BOARD_DEFINITIONS_H_
|
#define _BOARD_DEFINITIONS_H_
|
||||||
|
|
||||||
#if defined(BOARD_ID_arduino_zero)
|
|
||||||
#include "board_definitions_arduino_zero.h"
|
|
||||||
#elif defined(BOARD_ID_genuino_zero)
|
|
||||||
#include "board_definitions_genuino_zero.h"
|
|
||||||
#elif defined(BOARD_ID_arduino_mkr1000)
|
|
||||||
#include "board_definitions_arduino_mkr1000.h"
|
|
||||||
#elif defined(BOARD_ID_genuino_mkr1000)
|
|
||||||
#include "board_definitions_genuino_mkr1000.h"
|
|
||||||
#elif defined(BOARD_ID_arduino_mkrzero)
|
|
||||||
#include "board_definitions_arduino_mkrzero.h"
|
|
||||||
#elif defined(BOARD_ID_arduino_mkrfox1200)
|
|
||||||
#include "board_definitions_arduino_mkrfox1200.h"
|
|
||||||
#elif defined(BOARD_ID_arduino_mkrgsm1400)
|
|
||||||
#include "board_definitions_arduino_mkrgsm1400.h"
|
|
||||||
#elif defined(BOARD_ID_arduino_mkrwan1300)
|
|
||||||
#include "board_definitions_arduino_mkrwan1300.h"
|
|
||||||
#elif defined(BOARD_ID_arduino_mkrwifi1010)
|
|
||||||
#include "board_definitions_arduino_mkrwifi1010.h"
|
|
||||||
#elif defined(BOARD_ID_arduino_mkrnb1500)
|
|
||||||
#include "board_definitions_arduino_mkrnb1500.h"
|
|
||||||
#else
|
|
||||||
#error You must define a BOARD_ID and add the corresponding definitions in board_definitions.h
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Common definitions
|
|
||||||
// ------------------
|
|
||||||
|
|
||||||
#define BOOT_PIN_MASK (1U << (BOOT_LOAD_PIN & 0x1f))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by
|
* If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by
|
||||||
* quickly tapping two times on the reset button.
|
* quickly tapping two times on the reset button.
|
||||||
|
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2016 Arduino LLC. All right reserved.
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with this library; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _BOARD_DEFINITIONS_H_
|
|
||||||
#define _BOARD_DEFINITIONS_H_
|
|
||||||
|
|
||||||
/*
|
|
||||||
* USB device definitions
|
|
||||||
*/
|
|
||||||
#define STRING_PRODUCT "Arduino MKR NB 1500"
|
|
||||||
#define USB_VID_HIGH 0x23
|
|
||||||
#define USB_VID_LOW 0x41
|
|
||||||
#define USB_PID_HIGH 0x00
|
|
||||||
#define USB_PID_LOW 0x55
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If BOOT_DOUBLE_TAP_ADDRESS is defined the bootloader is started by
|
|
||||||
* quickly tapping two times on the reset button.
|
|
||||||
* BOOT_DOUBLE_TAP_ADDRESS must point to a free SRAM cell that must not
|
|
||||||
* be touched from the loaded application.
|
|
||||||
*/
|
|
||||||
#define BOOT_DOUBLE_TAP_ADDRESS (0x20007FFCul)
|
|
||||||
#define BOOT_DOUBLE_TAP_DATA (*((volatile uint32_t *) BOOT_DOUBLE_TAP_ADDRESS))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If BOOT_LOAD_PIN is defined the bootloader is started if the selected
|
|
||||||
* pin is tied LOW.
|
|
||||||
*/
|
|
||||||
//#define BOOT_LOAD_PIN PIN_PA21
|
|
||||||
//#define BOOT_LOAD_PIN PIN_PA15
|
|
||||||
|
|
||||||
#define BOOT_USART_MODULE SERCOM5
|
|
||||||
#define BOOT_USART_BUS_CLOCK_INDEX PM_APBCMASK_SERCOM5
|
|
||||||
#define BOOT_USART_PER_CLOCK_INDEX GCLK_CLKCTRL_ID_SERCOM5_CORE_Val
|
|
||||||
#define BOOT_USART_PAD_SETTINGS UART_RX_PAD3_TX_PAD2
|
|
||||||
#define BOOT_USART_PAD3 PINMUX_PB23D_SERCOM5_PAD3
|
|
||||||
#define BOOT_USART_PAD2 PINMUX_PB22D_SERCOM5_PAD2
|
|
||||||
#define BOOT_USART_PAD1 PINMUX_UNUSED
|
|
||||||
#define BOOT_USART_PAD0 PINMUX_UNUSED
|
|
||||||
|
|
||||||
/* Master clock frequency */
|
|
||||||
#define CPU_FREQUENCY (48000000ul)
|
|
||||||
#define VARIANT_MCK CPU_FREQUENCY
|
|
||||||
|
|
||||||
/* Frequency of the board main oscillator */
|
|
||||||
#define VARIANT_MAINOSC (32768ul)
|
|
||||||
|
|
||||||
/* Calibration values for DFLL48 pll */
|
|
||||||
#define NVM_SW_CALIB_DFLL48M_COARSE_VAL (58)
|
|
||||||
#define NVM_SW_CALIB_DFLL48M_FINE_VAL (64)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LEDs definitions
|
|
||||||
*/
|
|
||||||
// PA20 (digital pin 6)
|
|
||||||
#define BOARD_LED_PORT (0)
|
|
||||||
#define BOARD_LED_PIN (20)
|
|
||||||
|
|
||||||
#define CONFIGURE_PMIC 1
|
|
||||||
#define PMIC_PIN_SCL 12
|
|
||||||
#define PMIC_PIN_SDA 11
|
|
||||||
#define PMIC_SERCOM SERCOM0
|
|
||||||
|
|
||||||
// No RX/TX led
|
|
||||||
//#define BOARD_LEDRX_PORT
|
|
||||||
//#define BOARD_LEDRX_PIN
|
|
||||||
|
|
||||||
//#define BOARD_LEDTX_PORT
|
|
||||||
//#define BOARD_LEDTX_PIN
|
|
||||||
|
|
||||||
#endif // _BOARD_DEFINITIONS_H_
|
|
||||||
|
|
@ -25,8 +25,5 @@ mv -v samd21_sam_ba_arduino_mkrwan1300.* ../mkrwan1300/
|
||||||
BOARD_ID=arduino_mkrwifi1010 NAME=samd21_sam_ba_arduino_mkrwifi1010 make clean all
|
BOARD_ID=arduino_mkrwifi1010 NAME=samd21_sam_ba_arduino_mkrwifi1010 make clean all
|
||||||
mv -v samd21_sam_ba_arduino_mkrwifi1010.* ../mkrwifi1010/
|
mv -v samd21_sam_ba_arduino_mkrwifi1010.* ../mkrwifi1010/
|
||||||
|
|
||||||
BOARD_ID=arduino_mkrnb1500 NAME=samd21_sam_ba_arduino_mkrnb1500 make clean all
|
|
||||||
mv -v samd21_sam_ba_arduino_mkrnb1500.* ../mkrnb1500/
|
|
||||||
|
|
||||||
echo Done building bootloaders!
|
echo Done building bootloaders!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ extern "C"{
|
||||||
|
|
||||||
// Include Atmel headers
|
// Include Atmel headers
|
||||||
#include "sam.h"
|
#include "sam.h"
|
||||||
|
|
||||||
#include "wiring_constants.h"
|
#include "wiring_constants.h"
|
||||||
|
|
||||||
#define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L )
|
#define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L )
|
||||||
|
|
@ -96,33 +97,8 @@ void loop( void ) ;
|
||||||
#undef abs
|
#undef abs
|
||||||
#endif // abs
|
#endif // abs
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#define min(a,b) ((a)<(b)?(a):(b))
|
||||||
template<class T, class L>
|
#define max(a,b) ((a)>(b)?(a):(b))
|
||||||
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
|
|
||||||
{
|
|
||||||
return (b < a) ? b : a;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class L>
|
|
||||||
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
|
|
||||||
{
|
|
||||||
return (a < b) ? b : a;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#ifndef min
|
|
||||||
#define min(a,b) \
|
|
||||||
({ __typeof__ (a) _a = (a); \
|
|
||||||
__typeof__ (b) _b = (b); \
|
|
||||||
_a < _b ? _a : _b; })
|
|
||||||
#endif
|
|
||||||
#ifndef max
|
|
||||||
#define max(a,b) \
|
|
||||||
({ __typeof__ (a) _a = (a); \
|
|
||||||
__typeof__ (b) _b = (b); \
|
|
||||||
_a > _b ? _a : _b; })
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define abs(x) ((x)>0?(x):-(x))
|
#define abs(x) ((x)>0?(x):-(x))
|
||||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||||
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||||
|
|
@ -148,15 +124,10 @@ void loop( void ) ;
|
||||||
#define digitalPinToInterrupt(P) ( P )
|
#define digitalPinToInterrupt(P) ( P )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// USB
|
// USB Device
|
||||||
#ifdef USE_TINYUSB
|
#include "USB/USBDesc.h"
|
||||||
// Needed for declaring Serial
|
#include "USB/USBCore.h"
|
||||||
#include "Adafruit_USBD_CDC.h"
|
#include "USB/USBAPI.h"
|
||||||
#else
|
#include "USB/USB_host.h"
|
||||||
#include "USB/USBDesc.h"
|
|
||||||
#include "USB/USBCore.h"
|
|
||||||
#include "USB/USBAPI.h"
|
|
||||||
#include "USB/USB_host.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // Arduino_h
|
#endif // Arduino_h
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ class HardwareSerial : public Stream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void begin(unsigned long) {}
|
virtual void begin(unsigned long) {}
|
||||||
virtual void begin(unsigned long, uint16_t) {}
|
virtual void begin(unsigned long baudrate, uint16_t config) {}
|
||||||
virtual void end() {}
|
virtual void end() {}
|
||||||
virtual int available(void) = 0;
|
virtual int available(void) = 0;
|
||||||
virtual int peek(void) = 0;
|
virtual int peek(void) = 0;
|
||||||
|
|
|
||||||
|
|
@ -94,28 +94,6 @@ size_t Print::print(unsigned long n, int base)
|
||||||
else return printNumber(n, base);
|
else return printNumber(n, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Print::print(long long n, int base)
|
|
||||||
{
|
|
||||||
if (base == 0) {
|
|
||||||
return write(n);
|
|
||||||
} else if (base == 10) {
|
|
||||||
if (n < 0) {
|
|
||||||
int t = print('-');
|
|
||||||
n = -n;
|
|
||||||
return printULLNumber(n, 10) + t;
|
|
||||||
}
|
|
||||||
return printULLNumber(n, 10);
|
|
||||||
} else {
|
|
||||||
return printULLNumber(n, base);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(unsigned long long n, int base)
|
|
||||||
{
|
|
||||||
if (base == 0) return write(n);
|
|
||||||
else return printULLNumber(n, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::print(double n, int digits)
|
size_t Print::print(double n, int digits)
|
||||||
{
|
{
|
||||||
return printFloat(n, digits);
|
return printFloat(n, digits);
|
||||||
|
|
@ -194,20 +172,6 @@ size_t Print::println(unsigned long num, int base)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Print::println(long long num, int base)
|
|
||||||
{
|
|
||||||
size_t n = print(num, base);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(unsigned long long num, int base)
|
|
||||||
{
|
|
||||||
size_t n = print(num, base);
|
|
||||||
n += println();
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println(double num, int digits)
|
size_t Print::println(double num, int digits)
|
||||||
{
|
{
|
||||||
size_t n = print(num, digits);
|
size_t n = print(num, digits);
|
||||||
|
|
@ -222,16 +186,6 @@ size_t Print::println(const Printable& x)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Print::printf(const char format[], ...)
|
|
||||||
{
|
|
||||||
char buf[PRINTF_BUF];
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
vsnprintf(buf, sizeof(buf), format, ap);
|
|
||||||
write(buf);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private Methods /////////////////////////////////////////////////////////////
|
// Private Methods /////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
size_t Print::printNumber(unsigned long n, uint8_t base)
|
size_t Print::printNumber(unsigned long n, uint8_t base)
|
||||||
|
|
@ -254,81 +208,6 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
|
||||||
return write(str);
|
return write(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
// REFERENCE IMPLEMENTATION FOR ULL
|
|
||||||
// size_t Print::printULLNumber(unsigned long long n, uint8_t base)
|
|
||||||
// {
|
|
||||||
// // if limited to base 10 and 16 the bufsize can be smaller
|
|
||||||
// char buf[65];
|
|
||||||
// char *str = &buf[64];
|
|
||||||
|
|
||||||
// *str = '\0';
|
|
||||||
|
|
||||||
// // prevent crash if called with base == 1
|
|
||||||
// if (base < 2) base = 10;
|
|
||||||
|
|
||||||
// do {
|
|
||||||
// unsigned long long t = n / base;
|
|
||||||
// char c = n - t * base; // faster than c = n%base;
|
|
||||||
// n = t;
|
|
||||||
// *--str = c < 10 ? c + '0' : c + 'A' - 10;
|
|
||||||
// } while(n);
|
|
||||||
|
|
||||||
// return write(str);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// FAST IMPLEMENTATION FOR ULL
|
|
||||||
size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
|
|
||||||
{
|
|
||||||
// if limited to base 10 and 16 the bufsize can be 20
|
|
||||||
char buf[64];
|
|
||||||
uint8_t i = 0;
|
|
||||||
uint8_t innerLoops = 0;
|
|
||||||
|
|
||||||
// prevent crash if called with base == 1
|
|
||||||
if (base < 2) base = 10;
|
|
||||||
|
|
||||||
// process chunks that fit in "16 bit math".
|
|
||||||
uint16_t top = 0xFFFF / base;
|
|
||||||
uint16_t th16 = 1;
|
|
||||||
while (th16 < top)
|
|
||||||
{
|
|
||||||
th16 *= base;
|
|
||||||
innerLoops++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (n64 > th16)
|
|
||||||
{
|
|
||||||
// 64 bit math part
|
|
||||||
uint64_t q = n64 / th16;
|
|
||||||
uint16_t r = n64 - q*th16;
|
|
||||||
n64 = q;
|
|
||||||
|
|
||||||
// 16 bit math loop to do remainder. (note buffer is filled reverse)
|
|
||||||
for (uint8_t j=0; j < innerLoops; j++)
|
|
||||||
{
|
|
||||||
uint16_t qq = r/base;
|
|
||||||
buf[i++] = r - qq*base;
|
|
||||||
r = qq;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t n16 = n64;
|
|
||||||
while (n16 > 0)
|
|
||||||
{
|
|
||||||
uint16_t qq = n16/base;
|
|
||||||
buf[i++] = n16 - qq*base;
|
|
||||||
n16 = qq;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t bytes = i;
|
|
||||||
for (; i > 0; i--)
|
|
||||||
write((char) (buf[i - 1] < 10 ?
|
|
||||||
'0' + buf[i - 1] :
|
|
||||||
'A' + buf[i - 1] - 10));
|
|
||||||
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::printFloat(double number, uint8_t digits)
|
size_t Print::printFloat(double number, uint8_t digits)
|
||||||
{
|
{
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
|
@ -359,18 +238,17 @@ size_t Print::printFloat(double number, uint8_t digits)
|
||||||
|
|
||||||
// Print the decimal point, but only if there are digits beyond
|
// Print the decimal point, but only if there are digits beyond
|
||||||
if (digits > 0) {
|
if (digits > 0) {
|
||||||
n += print(".");
|
n += print('.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract digits from the remainder one at a time
|
// Extract digits from the remainder one at a time
|
||||||
while (digits-- > 0)
|
while (digits-- > 0)
|
||||||
{
|
{
|
||||||
remainder *= 10.0;
|
remainder *= 10.0;
|
||||||
unsigned int toPrint = (unsigned int)remainder;
|
unsigned int toPrint = (unsigned int)(remainder);
|
||||||
n += print(toPrint);
|
n += print(toPrint);
|
||||||
remainder -= toPrint;
|
remainder -= toPrint;
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h> // for size_t
|
#include <stdio.h> // for size_t
|
||||||
#include <stdarg.h> // for printf
|
|
||||||
#define PRINTF_BUF 80
|
|
||||||
|
|
||||||
#include "WString.h"
|
#include "WString.h"
|
||||||
#include "Printable.h"
|
#include "Printable.h"
|
||||||
|
|
@ -30,6 +28,9 @@
|
||||||
#define DEC 10
|
#define DEC 10
|
||||||
#define HEX 16
|
#define HEX 16
|
||||||
#define OCT 8
|
#define OCT 8
|
||||||
|
#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar
|
||||||
|
#undef BIN
|
||||||
|
#endif
|
||||||
#define BIN 2
|
#define BIN 2
|
||||||
|
|
||||||
class Print
|
class Print
|
||||||
|
|
@ -37,7 +38,6 @@ class Print
|
||||||
private:
|
private:
|
||||||
int write_error;
|
int write_error;
|
||||||
size_t printNumber(unsigned long, uint8_t);
|
size_t printNumber(unsigned long, uint8_t);
|
||||||
size_t printULLNumber(unsigned long long, uint8_t);
|
|
||||||
size_t printFloat(double, uint8_t);
|
size_t printFloat(double, uint8_t);
|
||||||
protected:
|
protected:
|
||||||
void setWriteError(int err = 1) { write_error = err; }
|
void setWriteError(int err = 1) { write_error = err; }
|
||||||
|
|
@ -70,8 +70,6 @@ class Print
|
||||||
size_t print(unsigned int, int = DEC);
|
size_t print(unsigned int, int = DEC);
|
||||||
size_t print(long, int = DEC);
|
size_t print(long, int = DEC);
|
||||||
size_t print(unsigned long, int = DEC);
|
size_t print(unsigned long, int = DEC);
|
||||||
size_t print(long long, int = DEC);
|
|
||||||
size_t print(unsigned long long, int = DEC);
|
|
||||||
size_t print(double, int = 2);
|
size_t print(double, int = 2);
|
||||||
size_t print(const Printable&);
|
size_t print(const Printable&);
|
||||||
|
|
||||||
|
|
@ -84,13 +82,9 @@ class Print
|
||||||
size_t println(unsigned int, int = DEC);
|
size_t println(unsigned int, int = DEC);
|
||||||
size_t println(long, int = DEC);
|
size_t println(long, int = DEC);
|
||||||
size_t println(unsigned long, int = DEC);
|
size_t println(unsigned long, int = DEC);
|
||||||
size_t println(long long, int = DEC);
|
|
||||||
size_t println(unsigned long long, int = DEC);
|
|
||||||
size_t println(double, int = 2);
|
size_t println(double, int = 2);
|
||||||
size_t println(const Printable&);
|
size_t println(const Printable&);
|
||||||
size_t println(void);
|
size_t println(void);
|
||||||
|
|
||||||
void printf(const char[], ...);
|
|
||||||
|
|
||||||
virtual void flush() { /* Empty implementation for backward compatibility */ }
|
virtual void flush() { /* Empty implementation for backward compatibility */ }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ extern "C" {
|
||||||
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10610)
|
#if (ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10610)
|
||||||
|
|
||||||
extern const uint32_t __text_start__;
|
extern const uint32_t __text_start__;
|
||||||
#define APP_START ((uint32_t)(&__text_start__) + 4)
|
#define APP_START ((volatile uint32_t)(&__text_start__) + 4)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,7 @@
|
||||||
// using a ring buffer (I think), in which head is the index of the location
|
// using a ring buffer (I think), in which head is the index of the location
|
||||||
// to which to write the next incoming character and tail is the index of the
|
// to which to write the next incoming character and tail is the index of the
|
||||||
// location from which to read.
|
// location from which to read.
|
||||||
|
#define SERIAL_BUFFER_SIZE 164
|
||||||
#ifndef SERIAL_BUFFER_SIZE
|
|
||||||
#define SERIAL_BUFFER_SIZE 350
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <int N>
|
template <int N>
|
||||||
class RingBufferN
|
class RingBufferN
|
||||||
|
|
|
||||||
|
|
@ -30,29 +30,11 @@
|
||||||
SERCOM::SERCOM(Sercom* s)
|
SERCOM::SERCOM(Sercom* s)
|
||||||
{
|
{
|
||||||
sercom = s;
|
sercom = s;
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
// A briefly-available but now deprecated feature had the SPI clock source
|
|
||||||
// set via a compile-time setting (MAX_SPI)...problem was this affected
|
|
||||||
// ALL SERCOMs, whereas some (anything read/write, e.g. SD cards) should
|
|
||||||
// not exceed the standard 24 MHz setting. Newer code, if it needs faster
|
|
||||||
// write-only SPI (e.g. to screen), should override the SERCOM clock on a
|
|
||||||
// per-peripheral basis. Nonetheless, we check SERCOM_SPI_FREQ_REF here
|
|
||||||
// (MAX_SPI * 2) to retain compatibility with any interim projects that
|
|
||||||
// might have relied on the compile-time setting. But please, don't.
|
|
||||||
#if SERCOM_SPI_FREQ_REF == F_CPU // F_CPU clock = GCLK0
|
|
||||||
clockSource = SERCOM_CLOCK_SOURCE_FCPU;
|
|
||||||
#elif SERCOM_SPI_FREQ_REF == 48000000 // 48 MHz clock = GCLK1 (standard)
|
|
||||||
clockSource = SERCOM_CLOCK_SOURCE_48M;
|
|
||||||
#elif SERCOM_SPI_FREQ_REF == 100000000 // 100 MHz clock = GCLK2
|
|
||||||
clockSource = SERCOM_CLOCK_SOURCE_100M;
|
|
||||||
#endif
|
|
||||||
#endif // end __SAMD51__
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================
|
/* =========================
|
||||||
* ===== Sercom UART
|
* ===== Sercom UART
|
||||||
* =========================
|
* =========================
|
||||||
*/
|
*/
|
||||||
void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
|
void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint32_t baudrate)
|
||||||
{
|
{
|
||||||
|
|
@ -60,12 +42,12 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint
|
||||||
resetUART();
|
resetUART();
|
||||||
|
|
||||||
//Setting the CTRLA register
|
//Setting the CTRLA register
|
||||||
sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(mode) |
|
sercom->USART.CTRLA.reg = SERCOM_USART_CTRLA_MODE(mode) |
|
||||||
SERCOM_USART_CTRLA_SAMPR(sampleRate);
|
SERCOM_USART_CTRLA_SAMPR(sampleRate);
|
||||||
|
|
||||||
//Setting the Interrupt register
|
//Setting the Interrupt register
|
||||||
sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC | //Received complete
|
sercom->USART.INTENSET.reg = SERCOM_USART_INTENSET_RXC | //Received complete
|
||||||
SERCOM_USART_INTENSET_ERROR; //All others errors
|
SERCOM_USART_INTENSET_ERROR; //All others errors
|
||||||
|
|
||||||
if ( mode == UART_INT_CLOCK )
|
if ( mode == UART_INT_CLOCK )
|
||||||
{
|
{
|
||||||
|
|
@ -93,22 +75,20 @@ void SERCOM::initUART(SercomUartMode mode, SercomUartSampleRate sampleRate, uint
|
||||||
void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits)
|
void SERCOM::initFrame(SercomUartCharSize charSize, SercomDataOrder dataOrder, SercomParityMode parityMode, SercomNumberStopBit nbStopBits)
|
||||||
{
|
{
|
||||||
//Setting the CTRLA register
|
//Setting the CTRLA register
|
||||||
sercom->USART.CTRLA.reg |=
|
sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_FORM( (parityMode == SERCOM_NO_PARITY ? 0 : 1) ) |
|
||||||
SERCOM_USART_CTRLA_FORM((parityMode == SERCOM_NO_PARITY ? 0 : 1) ) |
|
dataOrder << SERCOM_USART_CTRLA_DORD_Pos;
|
||||||
dataOrder << SERCOM_USART_CTRLA_DORD_Pos;
|
|
||||||
|
|
||||||
//Setting the CTRLB register
|
//Setting the CTRLB register
|
||||||
sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_CHSIZE(charSize) |
|
sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_CHSIZE(charSize) |
|
||||||
nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos |
|
nbStopBits << SERCOM_USART_CTRLB_SBMODE_Pos |
|
||||||
(parityMode == SERCOM_NO_PARITY ? 0 : parityMode) <<
|
(parityMode == SERCOM_NO_PARITY ? 0 : parityMode) << SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value
|
||||||
SERCOM_USART_CTRLB_PMODE_Pos; //If no parity use default value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SERCOM::initPads(SercomUartTXPad txPad, SercomRXPad rxPad)
|
void SERCOM::initPads(SercomUartTXPad txPad, SercomRXPad rxPad)
|
||||||
{
|
{
|
||||||
//Setting the CTRLA register
|
//Setting the CTRLA register
|
||||||
sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(txPad) |
|
sercom->USART.CTRLA.reg |= SERCOM_USART_CTRLA_TXPO(txPad) |
|
||||||
SERCOM_USART_CTRLA_RXPO(rxPad);
|
SERCOM_USART_CTRLA_RXPO(rxPad);
|
||||||
|
|
||||||
// Enable Transceiver and Receiver
|
// Enable Transceiver and Receiver
|
||||||
sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ;
|
sercom->USART.CTRLB.reg |= SERCOM_USART_CTRLB_TXEN | SERCOM_USART_CTRLB_RXEN ;
|
||||||
|
|
@ -221,9 +201,9 @@ void SERCOM::disableDataRegisterEmptyInterruptUART()
|
||||||
sercom->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE;
|
sercom->USART.INTENCLR.reg = SERCOM_USART_INTENCLR_DRE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* =========================
|
/* =========================
|
||||||
* ===== Sercom SPI
|
* ===== Sercom SPI
|
||||||
* =========================
|
* =========================
|
||||||
*/
|
*/
|
||||||
void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
|
void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder)
|
||||||
{
|
{
|
||||||
|
|
@ -231,13 +211,13 @@ void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize ch
|
||||||
initClockNVIC();
|
initClockNVIC();
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE(0x3) | // master mode
|
sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE(0x3) | //master mode
|
||||||
SERCOM_SPI_CTRLA_DOPO(mosi) |
|
SERCOM_SPI_CTRLA_DOPO(mosi) |
|
||||||
SERCOM_SPI_CTRLA_DIPO(miso) |
|
SERCOM_SPI_CTRLA_DIPO(miso) |
|
||||||
dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;
|
dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;
|
||||||
#else
|
#else
|
||||||
//Setting the CTRLA register
|
//Setting the CTRLA register
|
||||||
sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER |
|
sercom->SPI.CTRLA.reg = SERCOM_SPI_CTRLA_MODE_SPI_MASTER |
|
||||||
SERCOM_SPI_CTRLA_DOPO(mosi) |
|
SERCOM_SPI_CTRLA_DOPO(mosi) |
|
||||||
SERCOM_SPI_CTRLA_DIPO(miso) |
|
SERCOM_SPI_CTRLA_DIPO(miso) |
|
||||||
dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;
|
dataOrder << SERCOM_SPI_CTRLA_DORD_Pos;
|
||||||
|
|
@ -245,9 +225,10 @@ void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize ch
|
||||||
|
|
||||||
//Setting the CTRLB register
|
//Setting the CTRLB register
|
||||||
sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) |
|
sercom->SPI.CTRLB.reg = SERCOM_SPI_CTRLB_CHSIZE(charSize) |
|
||||||
SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver.
|
SERCOM_SPI_CTRLB_RXEN; //Active the SPI receiver.
|
||||||
|
|
||||||
while( sercom->SPI.SYNCBUSY.bit.CTRLB == 1 );
|
while( sercom->SPI.SYNCBUSY.bit.CTRLB == 1 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate)
|
void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate)
|
||||||
|
|
@ -266,8 +247,8 @@ void SERCOM::initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate)
|
||||||
cpol = 1;
|
cpol = 1;
|
||||||
|
|
||||||
//Setting the CTRLA register
|
//Setting the CTRLA register
|
||||||
sercom->SPI.CTRLA.reg |= ( cpha << SERCOM_SPI_CTRLA_CPHA_Pos ) |
|
sercom->SPI.CTRLA.reg |= ( cpha << SERCOM_SPI_CTRLA_CPHA_Pos ) |
|
||||||
( cpol << SERCOM_SPI_CTRLA_CPOL_Pos );
|
( cpol << SERCOM_SPI_CTRLA_CPOL_Pos );
|
||||||
|
|
||||||
//Synchronous arithmetic
|
//Synchronous arithmetic
|
||||||
sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate);
|
sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(baudrate);
|
||||||
|
|
@ -321,13 +302,14 @@ SercomDataOrder SERCOM::getDataOrderSPI()
|
||||||
|
|
||||||
void SERCOM::setBaudrateSPI(uint8_t divider)
|
void SERCOM::setBaudrateSPI(uint8_t divider)
|
||||||
{
|
{
|
||||||
disableSPI(); // Register is enable-protected
|
//Can't divide by 0
|
||||||
|
if(divider == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
//Register enable-protected
|
||||||
sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(freqRef / divider);
|
disableSPI();
|
||||||
#else
|
|
||||||
sercom->SPI.BAUD.reg = calculateBaudrateSynchronous(SERCOM_SPI_FREQ_REF / divider);
|
sercom->SPI.BAUD.reg = calculateBaudrateSynchronous( SERCOM_FREQ_REF / divider );
|
||||||
#endif
|
|
||||||
|
|
||||||
enableSPI();
|
enableSPI();
|
||||||
}
|
}
|
||||||
|
|
@ -358,7 +340,10 @@ uint8_t SERCOM::transferDataSPI(uint8_t data)
|
||||||
{
|
{
|
||||||
sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register
|
sercom->SPI.DATA.bit.DATA = data; // Writing data into Data register
|
||||||
|
|
||||||
while(sercom->SPI.INTFLAG.bit.RXC == 0); // Waiting Complete Reception
|
while( sercom->SPI.INTFLAG.bit.RXC == 0 )
|
||||||
|
{
|
||||||
|
// Waiting Complete Reception
|
||||||
|
}
|
||||||
|
|
||||||
return sercom->SPI.DATA.bit.DATA; // Reading data
|
return sercom->SPI.DATA.bit.DATA; // Reading data
|
||||||
}
|
}
|
||||||
|
|
@ -376,30 +361,25 @@ bool SERCOM::isDataRegisterEmptySPI()
|
||||||
|
|
||||||
//bool SERCOM::isTransmitCompleteSPI()
|
//bool SERCOM::isTransmitCompleteSPI()
|
||||||
//{
|
//{
|
||||||
// //TXC : Transmit complete
|
// //TXC : Transmit complete
|
||||||
// return sercom->SPI.INTFLAG.bit.TXC;
|
// return sercom->SPI.INTFLAG.bit.TXC;
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//bool SERCOM::isReceiveCompleteSPI()
|
//bool SERCOM::isReceiveCompleteSPI()
|
||||||
//{
|
//{
|
||||||
// //RXC : Receive complete
|
// //RXC : Receive complete
|
||||||
// return sercom->SPI.INTFLAG.bit.RXC;
|
// return sercom->SPI.INTFLAG.bit.RXC;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate) {
|
uint8_t SERCOM::calculateBaudrateSynchronous(uint32_t baudrate)
|
||||||
#if defined(__SAMD51__)
|
{
|
||||||
uint16_t b = freqRef / (2 * baudrate);
|
return SERCOM_FREQ_REF / (2 * baudrate) - 1;
|
||||||
#else
|
|
||||||
uint16_t b = SERCOM_SPI_FREQ_REF / (2 * baudrate);
|
|
||||||
#endif
|
|
||||||
if(b > 0) b--; // Don't -1 on baud calc if already at 0
|
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* =========================
|
/* =========================
|
||||||
* ===== Sercom WIRE
|
* ===== Sercom WIRE
|
||||||
* =========================
|
* =========================
|
||||||
*/
|
*/
|
||||||
void SERCOM::resetWIRE()
|
void SERCOM::resetWIRE()
|
||||||
{
|
{
|
||||||
|
|
@ -537,18 +517,8 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
|
||||||
// 7-bits address + 1-bits R/W
|
// 7-bits address + 1-bits R/W
|
||||||
address = (address << 0x1ul) | flag;
|
address = (address << 0x1ul) | flag;
|
||||||
|
|
||||||
// If another master owns the bus or the last bus owner has not properly
|
// Wait idle or owner bus mode
|
||||||
// sent a stop, return failure early. This will prevent some misbehaved
|
while ( !isBusIdleWIRE() && !isBusOwnerWIRE() );
|
||||||
// devices from deadlocking here at the cost of the caller being responsible
|
|
||||||
// for retrying the failed transmission. See SercomWireBusState for the
|
|
||||||
// possible bus states.
|
|
||||||
if(!isBusOwnerWIRE())
|
|
||||||
{
|
|
||||||
if( isBusBusyWIRE() || (isArbLostWIRE() && !isBusIdleWIRE()) || isBusUnknownWIRE() )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send start and address
|
// Send start and address
|
||||||
sercom->I2CM.ADDR.bit.ADDR = address;
|
sercom->I2CM.ADDR.bit.ADDR = address;
|
||||||
|
|
@ -556,35 +526,29 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
|
||||||
// Address Transmitted
|
// Address Transmitted
|
||||||
if ( flag == WIRE_WRITE_FLAG ) // Write mode
|
if ( flag == WIRE_WRITE_FLAG ) // Write mode
|
||||||
{
|
{
|
||||||
while( !sercom->I2CM.INTFLAG.bit.MB ) {
|
while( !sercom->I2CM.INTFLAG.bit.MB )
|
||||||
|
{
|
||||||
// Wait transmission complete
|
// Wait transmission complete
|
||||||
|
|
||||||
// If certain errors occur, the MB bit may never be set (RFTM: SAMD21 sec:28.10.6; SAMD51 sec:36.10.7).
|
|
||||||
// The data transfer errors that can occur (including BUSERR) are all
|
|
||||||
// rolled up into INTFLAG.bit.ERROR from STATUS.reg
|
|
||||||
if (sercom->I2CM.INTFLAG.bit.ERROR) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Read mode
|
else // Read mode
|
||||||
{
|
{
|
||||||
while( !sercom->I2CM.INTFLAG.bit.SB ) {
|
while( !sercom->I2CM.INTFLAG.bit.SB )
|
||||||
|
{
|
||||||
|
// If the slave NACKS the address, the MB bit will be set.
|
||||||
|
// In that case, send a stop condition and return false.
|
||||||
|
if (sercom->I2CM.INTFLAG.bit.MB) {
|
||||||
|
sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Wait transmission complete
|
// Wait transmission complete
|
||||||
|
|
||||||
// If the slave NACKS the address, the MB bit will be set.
|
|
||||||
// A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register
|
|
||||||
// In that case, send a stop condition and return false.
|
|
||||||
if (sercom->I2CM.INTFLAG.bit.MB || sercom->I2CM.INTFLAG.bit.ERROR) {
|
|
||||||
sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean the 'Slave on Bus' flag, for further usage.
|
// Clean the 'Slave on Bus' flag, for further usage.
|
||||||
//sercom->I2CM.INTFLAG.bit.SB = 0x1ul;
|
//sercom->I2CM.INTFLAG.bit.SB = 0x1ul;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//ACK received (0: ACK, 1: NACK)
|
//ACK received (0: ACK, 1: NACK)
|
||||||
if(sercom->I2CM.STATUS.bit.RXNACK)
|
if(sercom->I2CM.STATUS.bit.RXNACK)
|
||||||
{
|
{
|
||||||
|
|
@ -603,11 +567,10 @@ bool SERCOM::sendDataMasterWIRE(uint8_t data)
|
||||||
|
|
||||||
//Wait transmission successful
|
//Wait transmission successful
|
||||||
while(!sercom->I2CM.INTFLAG.bit.MB) {
|
while(!sercom->I2CM.INTFLAG.bit.MB) {
|
||||||
// If a data transfer error occurs, the MB bit may never be set.
|
|
||||||
// Check the error bit and bail if it's set.
|
// If a bus error occurs, the MB bit may never be set.
|
||||||
// The data transfer errors that can occur (including BUSERR) are all
|
// Check the bus error bit and bail if it's set.
|
||||||
// rolled up into INTFLAG.bit.ERROR from STATUS.reg
|
if (sercom->I2CM.STATUS.bit.BUSERR) {
|
||||||
if (sercom->I2CM.INTFLAG.bit.ERROR) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -651,21 +614,6 @@ bool SERCOM::isBusOwnerWIRE( void )
|
||||||
return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE;
|
return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_OWNER_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SERCOM::isBusUnknownWIRE( void )
|
|
||||||
{
|
|
||||||
return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_UNKNOWN_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SERCOM::isArbLostWIRE( void )
|
|
||||||
{
|
|
||||||
return sercom->I2CM.STATUS.bit.ARBLOST == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SERCOM::isBusBusyWIRE( void )
|
|
||||||
{
|
|
||||||
return sercom->I2CM.STATUS.bit.BUSSTATE == WIRE_BUSY_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SERCOM::isDataReadyWIRE( void )
|
bool SERCOM::isDataReadyWIRE( void )
|
||||||
{
|
{
|
||||||
return sercom->I2CS.INTFLAG.bit.DRDY;
|
return sercom->I2CS.INTFLAG.bit.DRDY;
|
||||||
|
|
@ -708,17 +656,9 @@ uint8_t SERCOM::readDataWIRE( void )
|
||||||
{
|
{
|
||||||
if(isMasterWIRE())
|
if(isMasterWIRE())
|
||||||
{
|
{
|
||||||
while (sercom->I2CM.INTFLAG.bit.SB == 0) {
|
while( sercom->I2CM.INTFLAG.bit.SB == 0 )
|
||||||
|
{
|
||||||
// Waiting complete receive
|
// Waiting complete receive
|
||||||
// A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register
|
|
||||||
// In that case, send a stop condition and return false.
|
|
||||||
// readDataWIRE should really be able to indicate an error (which would never be used
|
|
||||||
// because the readDataWIRE callers (in Wire.cpp) should have checked availableWIRE() first and timed it
|
|
||||||
// out if the data never showed up
|
|
||||||
if (sercom->I2CM.INTFLAG.bit.MB || sercom->I2CM.INTFLAG.bit.ERROR) {
|
|
||||||
sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
|
|
||||||
return 0xFF;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sercom->I2CM.DATA.bit.DATA ;
|
return sercom->I2CM.DATA.bit.DATA ;
|
||||||
|
|
@ -729,152 +669,244 @@ uint8_t SERCOM::readDataWIRE( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
Sercom *sercomPtr;
|
|
||||||
uint8_t id_core;
|
|
||||||
uint8_t id_slow;
|
|
||||||
IRQn_Type irq[4];
|
|
||||||
} sercomData[] = {
|
|
||||||
{ SERCOM0, SERCOM0_GCLK_ID_CORE, SERCOM0_GCLK_ID_SLOW,
|
|
||||||
SERCOM0_0_IRQn, SERCOM0_1_IRQn, SERCOM0_2_IRQn, SERCOM0_3_IRQn },
|
|
||||||
{ SERCOM1, SERCOM1_GCLK_ID_CORE, SERCOM1_GCLK_ID_SLOW,
|
|
||||||
SERCOM1_0_IRQn, SERCOM1_1_IRQn, SERCOM1_2_IRQn, SERCOM1_3_IRQn },
|
|
||||||
{ SERCOM2, SERCOM2_GCLK_ID_CORE, SERCOM2_GCLK_ID_SLOW,
|
|
||||||
SERCOM2_0_IRQn, SERCOM2_1_IRQn, SERCOM2_2_IRQn, SERCOM2_3_IRQn },
|
|
||||||
{ SERCOM3, SERCOM3_GCLK_ID_CORE, SERCOM3_GCLK_ID_SLOW,
|
|
||||||
SERCOM3_0_IRQn, SERCOM3_1_IRQn, SERCOM3_2_IRQn, SERCOM3_3_IRQn },
|
|
||||||
{ SERCOM4, SERCOM4_GCLK_ID_CORE, SERCOM4_GCLK_ID_SLOW,
|
|
||||||
SERCOM4_0_IRQn, SERCOM4_1_IRQn, SERCOM4_2_IRQn, SERCOM4_3_IRQn },
|
|
||||||
{ SERCOM5, SERCOM5_GCLK_ID_CORE, SERCOM5_GCLK_ID_SLOW,
|
|
||||||
SERCOM5_0_IRQn, SERCOM5_1_IRQn, SERCOM5_2_IRQn, SERCOM5_3_IRQn },
|
|
||||||
#if defined(SERCOM6)
|
|
||||||
{ SERCOM6, SERCOM6_GCLK_ID_CORE, SERCOM6_GCLK_ID_SLOW,
|
|
||||||
SERCOM6_0_IRQn, SERCOM6_1_IRQn, SERCOM6_2_IRQn, SERCOM6_3_IRQn },
|
|
||||||
#endif
|
|
||||||
#if defined(SERCOM7)
|
|
||||||
{ SERCOM7, SERCOM7_GCLK_ID_CORE, SERCOM7_GCLK_ID_SLOW,
|
|
||||||
SERCOM7_0_IRQn, SERCOM7_1_IRQn, SERCOM7_2_IRQn, SERCOM7_3_IRQn },
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#else // end if SAMD51 (prob SAMD21)
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
Sercom *sercomPtr;
|
|
||||||
uint8_t clock;
|
|
||||||
IRQn_Type irqn;
|
|
||||||
} sercomData[] = {
|
|
||||||
SERCOM0, GCM_SERCOM0_CORE, SERCOM0_IRQn,
|
|
||||||
SERCOM1, GCM_SERCOM1_CORE, SERCOM1_IRQn,
|
|
||||||
SERCOM2, GCM_SERCOM2_CORE, SERCOM2_IRQn,
|
|
||||||
SERCOM3, GCM_SERCOM3_CORE, SERCOM3_IRQn,
|
|
||||||
#if defined(SERCOM4)
|
|
||||||
SERCOM4, GCM_SERCOM4_CORE, SERCOM4_IRQn,
|
|
||||||
#endif
|
|
||||||
#if defined(SERCOM5)
|
|
||||||
SERCOM5, GCM_SERCOM5_CORE, SERCOM5_IRQn,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // end !SAMD51
|
|
||||||
|
|
||||||
int8_t SERCOM::getSercomIndex(void) {
|
|
||||||
for(uint8_t i=0; i<(sizeof(sercomData) / sizeof(sercomData[0])); i++) {
|
|
||||||
if(sercom == sercomData[i].sercomPtr) return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
// This is currently for overriding an SPI SERCOM's clock source only --
|
|
||||||
// NOT for UART or WIRE SERCOMs, where it will have unintended consequences.
|
|
||||||
// It does not check.
|
|
||||||
// SERCOM clock source override is available only on SAMD51 (not 21).
|
|
||||||
// A dummy function for SAMD21 (compiles to nothing) is present in SERCOM.h
|
|
||||||
// so user code doesn't require a lot of conditional situations.
|
|
||||||
void SERCOM::setClockSource(int8_t idx, SercomClockSource src, bool core) {
|
|
||||||
|
|
||||||
if(src == SERCOM_CLOCK_SOURCE_NO_CHANGE) return;
|
|
||||||
|
|
||||||
uint8_t clk_id = core ? sercomData[idx].id_core : sercomData[idx].id_slow;
|
|
||||||
|
|
||||||
GCLK->PCHCTRL[clk_id].bit.CHEN = 0; // Disable timer
|
|
||||||
while(GCLK->PCHCTRL[clk_id].bit.CHEN); // Wait for disable
|
|
||||||
|
|
||||||
if(core) clockSource = src; // Save SercomClockSource value
|
|
||||||
|
|
||||||
// From cores/arduino/startup.c:
|
|
||||||
// GCLK0 = F_CPU
|
|
||||||
// GCLK1 = 48 MHz
|
|
||||||
// GCLK2 = 100 MHz
|
|
||||||
// GCLK3 = XOSC32K
|
|
||||||
// GCLK4 = 12 MHz
|
|
||||||
if(src == SERCOM_CLOCK_SOURCE_FCPU) {
|
|
||||||
GCLK->PCHCTRL[clk_id].reg =
|
|
||||||
GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
|
||||||
if(core) freqRef = F_CPU; // Save clock frequency value
|
|
||||||
} else if(src == SERCOM_CLOCK_SOURCE_48M) {
|
|
||||||
GCLK->PCHCTRL[clk_id].reg =
|
|
||||||
GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
|
||||||
if(core) freqRef = 48000000;
|
|
||||||
} else if(src == SERCOM_CLOCK_SOURCE_100M) {
|
|
||||||
GCLK->PCHCTRL[clk_id].reg =
|
|
||||||
GCLK_PCHCTRL_GEN_GCLK2_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
|
||||||
if(core) freqRef = 100000000;
|
|
||||||
} else if(src == SERCOM_CLOCK_SOURCE_32K) {
|
|
||||||
GCLK->PCHCTRL[clk_id].reg =
|
|
||||||
GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
|
||||||
if(core) freqRef = 32768;
|
|
||||||
} else if(src == SERCOM_CLOCK_SOURCE_12M) {
|
|
||||||
GCLK->PCHCTRL[clk_id].reg =
|
|
||||||
GCLK_PCHCTRL_GEN_GCLK4_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
|
||||||
if(core) freqRef = 12000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(!GCLK->PCHCTRL[clk_id].bit.CHEN); // Wait for clock enable
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void SERCOM::initClockNVIC( void )
|
void SERCOM::initClockNVIC( void )
|
||||||
{
|
{
|
||||||
int8_t idx = getSercomIndex();
|
|
||||||
if(idx < 0) return; // We got a problem here
|
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
|
uint32_t clk_core;
|
||||||
|
uint32_t clk_slow;
|
||||||
|
|
||||||
|
if(sercom == SERCOM0)
|
||||||
|
{
|
||||||
|
clk_core = SERCOM0_GCLK_ID_CORE;
|
||||||
|
clk_slow = SERCOM0_GCLK_ID_SLOW;
|
||||||
|
|
||||||
for(uint8_t i=0; i<4; i++) {
|
NVIC_ClearPendingIRQ(SERCOM0_0_IRQn);
|
||||||
NVIC_ClearPendingIRQ(sercomData[idx].irq[i]);
|
NVIC_ClearPendingIRQ(SERCOM0_1_IRQn);
|
||||||
NVIC_SetPriority(sercomData[idx].irq[i], SERCOM_NVIC_PRIORITY);
|
NVIC_ClearPendingIRQ(SERCOM0_2_IRQn);
|
||||||
NVIC_EnableIRQ(sercomData[idx].irq[i]);
|
NVIC_ClearPendingIRQ(SERCOM0_3_IRQn);
|
||||||
|
|
||||||
|
NVIC_SetPriority (SERCOM0_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
|
NVIC_SetPriority (SERCOM0_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM0_2_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM0_3_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(SERCOM0_0_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM0_1_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM0_2_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM0_3_IRQn);
|
||||||
|
}
|
||||||
|
else if(sercom == SERCOM1)
|
||||||
|
{
|
||||||
|
clk_core = SERCOM1_GCLK_ID_CORE;
|
||||||
|
clk_slow = SERCOM1_GCLK_ID_SLOW;
|
||||||
|
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM1_0_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM1_1_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM1_2_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM1_3_IRQn);
|
||||||
|
|
||||||
|
NVIC_SetPriority (SERCOM1_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
|
NVIC_SetPriority (SERCOM1_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM1_2_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM1_3_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(SERCOM1_0_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM1_1_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM1_2_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM1_3_IRQn);
|
||||||
|
}
|
||||||
|
else if(sercom == SERCOM2)
|
||||||
|
{
|
||||||
|
clk_core = SERCOM2_GCLK_ID_CORE;
|
||||||
|
clk_slow = SERCOM2_GCLK_ID_SLOW;
|
||||||
|
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM2_0_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM2_1_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM2_2_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM2_3_IRQn);
|
||||||
|
|
||||||
|
NVIC_SetPriority (SERCOM2_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
|
NVIC_SetPriority (SERCOM2_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM2_2_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM2_3_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(SERCOM2_0_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM2_1_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM2_2_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM2_3_IRQn);
|
||||||
|
}
|
||||||
|
else if(sercom == SERCOM3)
|
||||||
|
{
|
||||||
|
clk_core = SERCOM3_GCLK_ID_CORE;
|
||||||
|
clk_slow = SERCOM3_GCLK_ID_SLOW;
|
||||||
|
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM3_0_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM3_1_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM3_2_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM3_3_IRQn);
|
||||||
|
|
||||||
|
NVIC_SetPriority (SERCOM3_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
|
NVIC_SetPriority (SERCOM3_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM3_2_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM3_3_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(SERCOM3_0_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM3_1_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM3_2_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM3_3_IRQn);
|
||||||
|
}
|
||||||
|
else if(sercom == SERCOM4)
|
||||||
|
{
|
||||||
|
clk_core = SERCOM4_GCLK_ID_CORE;
|
||||||
|
clk_slow = SERCOM4_GCLK_ID_SLOW;
|
||||||
|
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM4_0_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM4_1_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM4_2_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM4_3_IRQn);
|
||||||
|
|
||||||
|
NVIC_SetPriority (SERCOM4_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
|
NVIC_SetPriority (SERCOM4_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM4_2_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM4_3_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(SERCOM4_0_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM4_1_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM4_2_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM4_3_IRQn);
|
||||||
|
}
|
||||||
|
else if(sercom == SERCOM5)
|
||||||
|
{
|
||||||
|
clk_core = SERCOM5_GCLK_ID_CORE;
|
||||||
|
clk_slow = SERCOM5_GCLK_ID_SLOW;
|
||||||
|
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM5_0_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM5_1_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM5_2_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM5_3_IRQn);
|
||||||
|
|
||||||
|
NVIC_SetPriority (SERCOM5_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
|
NVIC_SetPriority (SERCOM5_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM5_2_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM5_3_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(SERCOM5_0_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM5_1_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM5_2_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM5_3_IRQn);
|
||||||
|
}
|
||||||
|
#if defined SERCOM6
|
||||||
|
else if(sercom == SERCOM6)
|
||||||
|
{
|
||||||
|
clk_core = SERCOM6_GCLK_ID_CORE;
|
||||||
|
clk_slow = SERCOM6_GCLK_ID_SLOW;
|
||||||
|
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM6_0_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM6_1_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM6_2_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM6_3_IRQn);
|
||||||
|
|
||||||
|
NVIC_SetPriority (SERCOM6_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
|
NVIC_SetPriority (SERCOM6_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM6_2_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM6_3_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(SERCOM6_0_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM6_1_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM6_2_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM6_3_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined SERCOM7
|
||||||
|
else if(sercom == SERCOM7)
|
||||||
|
{
|
||||||
|
clk_core = SERCOM7_GCLK_ID_CORE;
|
||||||
|
clk_slow = SERCOM7_GCLK_ID_SLOW;
|
||||||
|
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM7_0_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM7_1_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM7_2_IRQn);
|
||||||
|
NVIC_ClearPendingIRQ(SERCOM7_3_IRQn);
|
||||||
|
|
||||||
|
NVIC_SetPriority (SERCOM7_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
|
NVIC_SetPriority (SERCOM7_1_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM7_2_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
NVIC_SetPriority (SERCOM7_3_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(SERCOM7_0_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM7_1_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM7_2_IRQn);
|
||||||
|
NVIC_EnableIRQ(SERCOM7_3_IRQn);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
|
||||||
|
IRQn_Type IdNvic=PendSV_IRQn ; // Dummy init to intercept potential error later
|
||||||
|
|
||||||
|
uint8_t clockId = 0;
|
||||||
|
if(sercom == SERCOM0)
|
||||||
|
{
|
||||||
|
clockId = GCM_SERCOM0_CORE;
|
||||||
|
IdNvic = SERCOM0_IRQn;
|
||||||
}
|
}
|
||||||
|
else if(sercom == SERCOM1)
|
||||||
|
{
|
||||||
|
clockId = GCM_SERCOM1_CORE;
|
||||||
|
IdNvic = SERCOM1_IRQn;
|
||||||
|
}
|
||||||
|
else if(sercom == SERCOM2)
|
||||||
|
{
|
||||||
|
clockId = GCM_SERCOM2_CORE;
|
||||||
|
IdNvic = SERCOM2_IRQn;
|
||||||
|
}
|
||||||
|
else if(sercom == SERCOM3)
|
||||||
|
{
|
||||||
|
clockId = GCM_SERCOM3_CORE;
|
||||||
|
IdNvic = SERCOM3_IRQn;
|
||||||
|
}
|
||||||
|
#if defined(SERCOM4)
|
||||||
|
else if(sercom == SERCOM4)
|
||||||
|
{
|
||||||
|
clockId = GCM_SERCOM4_CORE;
|
||||||
|
IdNvic = SERCOM4_IRQn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(SERCOM5)
|
||||||
|
else if(sercom == SERCOM5)
|
||||||
|
{
|
||||||
|
clockId = GCM_SERCOM5_CORE;
|
||||||
|
IdNvic = SERCOM5_IRQn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// SPI DMA speed is dictated by the "slow clock" (I think...maybe) so
|
if ( IdNvic == PendSV_IRQn )
|
||||||
// BOTH are set to the same clock source (clk_slow isn't sourced from
|
{
|
||||||
// XOSC32K as in prior versions of SAMD core).
|
// We got a problem here
|
||||||
// This might have power implications for sleep code.
|
return ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
setClockSource(idx, clockSource, true); // true = core clock
|
#if defined(__SAMD51__)
|
||||||
setClockSource(idx, clockSource, false); // false = slow clock
|
GCLK->PCHCTRL[clk_core].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
||||||
|
GCLK->PCHCTRL[clk_slow].reg = GCLK_PCHCTRL_GEN_GCLK3_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
||||||
#else // end if SAMD51 (prob SAMD21)
|
|
||||||
|
#else
|
||||||
uint8_t clockId = sercomData[idx].clock;
|
// Setting NVIC
|
||||||
IRQn_Type IdNvic = sercomData[idx].irqn;
|
|
||||||
|
|
||||||
// Setting NVIC
|
|
||||||
NVIC_ClearPendingIRQ(IdNvic);
|
NVIC_ClearPendingIRQ(IdNvic);
|
||||||
NVIC_SetPriority(IdNvic, SERCOM_NVIC_PRIORITY);
|
NVIC_SetPriority (IdNvic, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
|
||||||
NVIC_EnableIRQ(IdNvic);
|
NVIC_EnableIRQ(IdNvic);
|
||||||
|
|
||||||
// Setting clock
|
//Setting clock
|
||||||
GCLK->CLKCTRL.reg =
|
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
|
||||||
GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
|
GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
|
||||||
GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
|
GCLK_CLKCTRL_CLKEN ;
|
||||||
GCLK_CLKCTRL_CLKEN;
|
|
||||||
|
|
||||||
while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY); // Wait for synchronization
|
while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
|
||||||
|
{
|
||||||
#endif // end !SAMD51
|
/* Wait for synchronization */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,8 @@
|
||||||
|
|
||||||
#include "sam.h"
|
#include "sam.h"
|
||||||
|
|
||||||
// SAMD51 has configurable MAX_SPI, else use peripheral clock default.
|
#define SERCOM_FREQ_REF 48000000ul
|
||||||
// Update: changing MAX_SPI via compiler flags is DEPRECATED, because
|
#define SERCOM_NVIC_PRIORITY ((1<<__NVIC_PRIO_BITS) - 1)
|
||||||
// this affects ALL SPI peripherals including some that should NOT be
|
|
||||||
// changed (e.g. anything using SD card). Instead, use setClockSource().
|
|
||||||
// This is left here for compatibility w/interim MAX_SPI-dependent code:
|
|
||||||
#if defined(MAX_SPI)
|
|
||||||
#define SERCOM_SPI_FREQ_REF (MAX_SPI * 2)
|
|
||||||
#else
|
|
||||||
#define SERCOM_SPI_FREQ_REF 48000000ul
|
|
||||||
#endif
|
|
||||||
// Other SERCOM peripherals always use the 48 MHz clock
|
|
||||||
#define SERCOM_FREQ_REF 48000000ul
|
|
||||||
#define SERCOM_NVIC_PRIORITY ((1<<__NVIC_PRIO_BITS) - 1)
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
@ -91,23 +80,23 @@ typedef enum
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
UART_TX_PAD_0 = 0x0ul, // Only for UART
|
UART_TX_PAD_0 = 0x0ul, // Only for UART
|
||||||
UART_TX_PAD_2 = 0x1ul, // Only for UART
|
UART_TX_PAD_2 = 0x1ul, // Only for UART
|
||||||
UART_TX_RTS_CTS_PAD_0_2_3 = 0x2ul, // Only for UART with TX on PAD0, RTS on PAD2 and CTS on PAD3
|
UART_TX_RTS_CTS_PAD_0_2_3 = 0x2ul, // Only for UART with TX on PAD0, RTS on PAD2 and CTS on PAD3
|
||||||
} SercomUartTXPad;
|
} SercomUartTXPad;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SAMPLE_RATE_x16 = 0x1, // Fractional
|
SAMPLE_RATE_x16 = 0x1, //Fractional
|
||||||
SAMPLE_RATE_x8 = 0x3, // Fractional
|
SAMPLE_RATE_x8 = 0x3, //Fractional
|
||||||
} SercomUartSampleRate;
|
} SercomUartSampleRate;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SERCOM_SPI_MODE_0 = 0, // CPOL : 0 | CPHA : 0
|
SERCOM_SPI_MODE_0 = 0, // CPOL : 0 | CPHA : 0
|
||||||
SERCOM_SPI_MODE_1, // CPOL : 0 | CPHA : 1
|
SERCOM_SPI_MODE_1, // CPOL : 0 | CPHA : 1
|
||||||
SERCOM_SPI_MODE_2, // CPOL : 1 | CPHA : 0
|
SERCOM_SPI_MODE_2, // CPOL : 1 | CPHA : 0
|
||||||
SERCOM_SPI_MODE_3 // CPOL : 1 | CPHA : 1
|
SERCOM_SPI_MODE_3 // CPOL : 1 | CPHA : 1
|
||||||
} SercomSpiClockMode;
|
} SercomSpiClockMode;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
@ -152,19 +141,6 @@ typedef enum
|
||||||
WIRE_MASTER_NACK_ACTION
|
WIRE_MASTER_NACK_ACTION
|
||||||
} SercomMasterAckActionWire;
|
} SercomMasterAckActionWire;
|
||||||
|
|
||||||
// SERCOM clock source override is available only on SAMD51 (not 21)
|
|
||||||
// but the enumeration is made regardless so user code doesn't need
|
|
||||||
// ifdefs or lengthy comments explaining the different situations --
|
|
||||||
// the clock-sourcing functions just compile to nothing on SAMD21.
|
|
||||||
typedef enum {
|
|
||||||
SERCOM_CLOCK_SOURCE_FCPU, // F_CPU clock (GCLK0)
|
|
||||||
SERCOM_CLOCK_SOURCE_48M, // 48 MHz peripheral clock (GCLK1) (standard)
|
|
||||||
SERCOM_CLOCK_SOURCE_100M, // 100 MHz peripheral clock (GCLK2)
|
|
||||||
SERCOM_CLOCK_SOURCE_32K, // XOSC32K clock (GCLK3)
|
|
||||||
SERCOM_CLOCK_SOURCE_12M, // 12 MHz peripheral clock (GCLK4)
|
|
||||||
SERCOM_CLOCK_SOURCE_NO_CHANGE // Leave clock source setting unchanged
|
|
||||||
} SercomClockSource;
|
|
||||||
|
|
||||||
class SERCOM
|
class SERCOM
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -195,6 +171,7 @@ class SERCOM
|
||||||
/* ========== SPI ========== */
|
/* ========== SPI ========== */
|
||||||
void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) ;
|
void initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize charSize, SercomDataOrder dataOrder) ;
|
||||||
void initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) ;
|
void initSPIClock(SercomSpiClockMode clockMode, uint32_t baudrate) ;
|
||||||
|
|
||||||
void resetSPI( void ) ;
|
void resetSPI( void ) ;
|
||||||
void enableSPI( void ) ;
|
void enableSPI( void ) ;
|
||||||
void disableSPI( void ) ;
|
void disableSPI( void ) ;
|
||||||
|
|
@ -225,9 +202,6 @@ class SERCOM
|
||||||
bool isSlaveWIRE( void ) ;
|
bool isSlaveWIRE( void ) ;
|
||||||
bool isBusIdleWIRE( void ) ;
|
bool isBusIdleWIRE( void ) ;
|
||||||
bool isBusOwnerWIRE( void ) ;
|
bool isBusOwnerWIRE( void ) ;
|
||||||
bool isBusUnknownWIRE( void ) ;
|
|
||||||
bool isArbLostWIRE( void );
|
|
||||||
bool isBusBusyWIRE( void );
|
|
||||||
bool isDataReadyWIRE( void ) ;
|
bool isDataReadyWIRE( void ) ;
|
||||||
bool isStopDetectedWIRE( void ) ;
|
bool isStopDetectedWIRE( void ) ;
|
||||||
bool isRestartDetectedWIRE( void ) ;
|
bool isRestartDetectedWIRE( void ) ;
|
||||||
|
|
@ -236,30 +210,10 @@ class SERCOM
|
||||||
bool isRXNackReceivedWIRE( void ) ;
|
bool isRXNackReceivedWIRE( void ) ;
|
||||||
int availableWIRE( void ) ;
|
int availableWIRE( void ) ;
|
||||||
uint8_t readDataWIRE( void ) ;
|
uint8_t readDataWIRE( void ) ;
|
||||||
int8_t getSercomIndex(void);
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
// SERCOM clock source override is only available on
|
|
||||||
// SAMD51 (not 21) ... but these functions are declared
|
|
||||||
// regardless so user code doesn't need ifdefs or lengthy
|
|
||||||
// comments explaining the different situations -- these
|
|
||||||
// just compile to nothing on SAMD21.
|
|
||||||
void setClockSource(int8_t idx, SercomClockSource src, bool core);
|
|
||||||
SercomClockSource getClockSource(void) { return clockSource; };
|
|
||||||
uint32_t getFreqRef(void) { return freqRef; };
|
|
||||||
#else
|
|
||||||
// The equivalent SAMD21 dummy functions...
|
|
||||||
void setClockSource(int8_t idx, SercomClockSource src, bool core) { (void)idx; (void)src; (void)core; };
|
|
||||||
SercomClockSource getClockSource(void) { return SERCOM_CLOCK_SOURCE_FCPU; };
|
|
||||||
uint32_t getFreqRef(void) { return F_CPU; };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Sercom* sercom;
|
Sercom* sercom;
|
||||||
#if defined(__SAMD51__)
|
uint8_t calculateBaudrateSynchronous(uint32_t baudrate) ;
|
||||||
SercomClockSource clockSource;
|
|
||||||
uint32_t freqRef; // Frequency corresponding to clockSource
|
|
||||||
#endif
|
|
||||||
uint8_t calculateBaudrateSynchronous(uint32_t baudrate);
|
|
||||||
uint32_t division(uint32_t dividend, uint32_t divisor) ;
|
uint32_t division(uint32_t dividend, uint32_t divisor) ;
|
||||||
void initClockNVIC( void ) ;
|
void initClockNVIC( void ) ;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ int Stream::timedRead()
|
||||||
do {
|
do {
|
||||||
c = read();
|
c = read();
|
||||||
if (c >= 0) return c;
|
if (c >= 0) return c;
|
||||||
yield(); // running TinyUSB task
|
|
||||||
} while(millis() - _startMillis < _timeout);
|
} while(millis() - _startMillis < _timeout);
|
||||||
return -1; // -1 indicates timeout
|
return -1; // -1 indicates timeout
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +47,6 @@ int Stream::timedPeek()
|
||||||
do {
|
do {
|
||||||
c = peek();
|
c = peek();
|
||||||
if (c >= 0) return c;
|
if (c >= 0) return c;
|
||||||
yield(); // running TinyUSB task
|
|
||||||
} while(millis() - _startMillis < _timeout);
|
} while(millis() - _startMillis < _timeout);
|
||||||
return -1; // -1 indicates timeout
|
return -1; // -1 indicates timeout
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,12 @@
|
||||||
#include "Tone.h"
|
#include "Tone.h"
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
|
|
||||||
|
#if defined(__SAMD51__)
|
||||||
|
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.SYNCBUSY.bit.ENABLE);
|
||||||
|
#else
|
||||||
|
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t toneMaxFrequency = F_CPU / 2;
|
uint32_t toneMaxFrequency = F_CPU / 2;
|
||||||
uint32_t lastOutputPin = 0xFFFFFFFF;
|
uint32_t lastOutputPin = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
|
@ -31,24 +37,22 @@ volatile bool toneIsActive = false;
|
||||||
volatile bool firstTimeRunning = false;
|
volatile bool firstTimeRunning = false;
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
#define TONE_TC TC0
|
#define TONE_TC TC2
|
||||||
#define TONE_TC_IRQn TC0_IRQn
|
#define TONE_TC_IRQn TC2_IRQn
|
||||||
#define TONE_TC_GCLK_ID TC0_GCLK_ID
|
#define TONE_TC_GCLK_ID TC2_GCLK_ID
|
||||||
#define Tone_Handler TC0_Handler
|
|
||||||
|
|
||||||
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.SYNCBUSY.bit.ENABLE);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define TONE_TC TC5
|
#define TONE_TC TC5
|
||||||
#define TONE_TC_IRQn TC5_IRQn
|
#define TONE_TC_IRQn TC5_IRQn
|
||||||
#define Tone_Handler TC5_Handler
|
|
||||||
|
|
||||||
#define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TONE_TC_TOP 0xFFFF
|
#define TONE_TC_TOP 0xFFFF
|
||||||
#define TONE_TC_CHANNEL 0
|
#define TONE_TC_CHANNEL 0
|
||||||
|
|
||||||
|
#if defined(__SAMD51__)
|
||||||
|
void TC2_Handler (void) __attribute__ ((weak, alias("Tone_Handler")));
|
||||||
|
#else
|
||||||
|
void TC5_Handler (void) __attribute__ ((weak, alias("Tone_Handler")));
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline void resetTC (Tc* TCx)
|
static inline void resetTC (Tc* TCx)
|
||||||
{
|
{
|
||||||
// Disable TCx
|
// Disable TCx
|
||||||
|
|
@ -68,14 +72,6 @@ void toneAccurateClock (uint32_t accurateSystemCoreClockFrequency)
|
||||||
|
|
||||||
void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Avoid divide by zero error by calling 'noTone' instead
|
|
||||||
if (frequency == 0)
|
|
||||||
{
|
|
||||||
noTone(outputPin);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure interrupt request
|
// Configure interrupt request
|
||||||
NVIC_DisableIRQ(TONE_TC_IRQn);
|
NVIC_DisableIRQ(TONE_TC_IRQn);
|
||||||
NVIC_ClearPendingIRQ(TONE_TC_IRQn);
|
NVIC_ClearPendingIRQ(TONE_TC_IRQn);
|
||||||
|
|
@ -84,16 +80,19 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
||||||
{
|
{
|
||||||
firstTimeRunning = true;
|
firstTimeRunning = true;
|
||||||
|
|
||||||
NVIC_SetPriority(TONE_TC_IRQn, 5);
|
NVIC_SetPriority(TONE_TC_IRQn, 0);
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
GCLK->PCHCTRL[TONE_TC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
GCLK->PCHCTRL[TONE_TC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
|
||||||
#else
|
#else
|
||||||
// Enable GCLK for TC4 and TC5 (timer counter input clock)
|
// Enable GCLK for TC4 and TC5 (timer counter input clock)
|
||||||
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5));
|
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5));
|
||||||
while (GCLK->STATUS.bit.SYNCBUSY);
|
while (GCLK->STATUS.bit.SYNCBUSY);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if it's a rest, set to 1Hz (below audio range)
|
||||||
|
frequency = (frequency > 0 ? frequency : 1);
|
||||||
|
|
||||||
if (toneIsActive && (outputPin != lastOutputPin))
|
if (toneIsActive && (outputPin != lastOutputPin))
|
||||||
noTone(lastOutputPin);
|
noTone(lastOutputPin);
|
||||||
|
|
@ -137,7 +136,7 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleCount = (duration > 0 ? frequency * duration * 2 / 1000UL : -1LL);
|
toggleCount = (duration > 0 ? frequency * duration * 2 / 1000UL : -1);
|
||||||
|
|
||||||
resetTC(TONE_TC);
|
resetTC(TONE_TC);
|
||||||
|
|
||||||
|
|
@ -180,19 +179,9 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
|
||||||
|
|
||||||
void noTone (uint32_t outputPin)
|
void noTone (uint32_t outputPin)
|
||||||
{
|
{
|
||||||
/* 'tone' need to run at least once in order to enable GCLK for
|
resetTC(TONE_TC);
|
||||||
* the timers used for the tone-functionality. If 'noTone' is called
|
digitalWrite(outputPin, LOW);
|
||||||
* without ever calling 'tone' before then 'WAIT_TC16_REGS_SYNC(TCx)'
|
toneIsActive = false;
|
||||||
* will wait infinitely. The variable 'firstTimeRunning' is set the
|
|
||||||
* 1st time 'tone' is set so it can be used to detect wether or not
|
|
||||||
* 'tone' has been called before.
|
|
||||||
*/
|
|
||||||
if(firstTimeRunning)
|
|
||||||
{
|
|
||||||
resetTC(TONE_TC);
|
|
||||||
digitalWrite(outputPin, LOW);
|
|
||||||
toneIsActive = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef USE_TINYUSB
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <Reset.h> // Needed for auto-reset with 1200bps port touch
|
#include <Reset.h> // Needed for auto-reset with 1200bps port touch
|
||||||
|
|
||||||
|
|
@ -152,7 +150,6 @@ void Serial_::begin(uint32_t /* baud_count */, uint8_t /* config */)
|
||||||
|
|
||||||
void Serial_::end(void)
|
void Serial_::end(void)
|
||||||
{
|
{
|
||||||
memset((void*)&_usbLineInfo, 0, sizeof(_usbLineInfo));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Serial_::available(void)
|
int Serial_::available(void)
|
||||||
|
|
@ -259,52 +256,6 @@ Serial_::operator bool()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t Serial_::readBreak() {
|
|
||||||
uint8_t enableInterrupts = ((__get_PRIMASK() & 0x1) == 0);
|
|
||||||
|
|
||||||
// disable interrupts,
|
|
||||||
// to avoid clearing a breakValue that might occur
|
|
||||||
// while processing the current break value
|
|
||||||
__disable_irq();
|
|
||||||
|
|
||||||
int32_t ret = breakValue;
|
|
||||||
|
|
||||||
breakValue = -1;
|
|
||||||
|
|
||||||
if (enableInterrupts) {
|
|
||||||
// re-enable the interrupts
|
|
||||||
__enable_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long Serial_::baud() {
|
|
||||||
return _usbLineInfo.dwDTERate;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t Serial_::stopbits() {
|
|
||||||
return _usbLineInfo.bCharFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t Serial_::paritytype() {
|
|
||||||
return _usbLineInfo.bParityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t Serial_::numbits() {
|
|
||||||
return _usbLineInfo.bDataBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Serial_::dtr() {
|
|
||||||
return _usbLineInfo.lineState & 0x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Serial_::rts() {
|
|
||||||
return _usbLineInfo.lineState & 0x2;
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial_ Serial(USBDevice);
|
Serial_ Serial(USBDevice);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // USE_TINYUSB
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef USE_TINYUSB
|
|
||||||
|
|
||||||
#include "USBAPI.h"
|
#include "USBAPI.h"
|
||||||
#include "USBDesc.h"
|
#include "USBDesc.h"
|
||||||
#include "USBCore.h"
|
#include "USBCore.h"
|
||||||
|
|
@ -115,6 +113,4 @@ PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // USE_TINYUSB
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
* Author: deanm
|
* Author: deanm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef USE_TINYUSB
|
|
||||||
|
|
||||||
#include "SAMD21_USBDevice.h"
|
#include "SAMD21_USBDevice.h"
|
||||||
|
|
||||||
|
|
@ -37,5 +36,3 @@ void USBDevice_SAMD21G18x::calibrate() {
|
||||||
usb.PADCAL.bit.TRANSP = pad_transp;
|
usb.PADCAL.bit.TRANSP = pad_transp;
|
||||||
usb.PADCAL.bit.TRIM = pad_trim;
|
usb.PADCAL.bit.TRIM = pad_trim;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // USE_TINYUSB
|
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ public:
|
||||||
release();
|
release();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~DoubleBufferedEPOutHandler() {
|
~DoubleBufferedEPOutHandler() {
|
||||||
free((void*)data0);
|
free((void*)data0);
|
||||||
free((void*)data1);
|
free((void*)data1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@ public:
|
||||||
|
|
||||||
// USB Device API
|
// USB Device API
|
||||||
void init();
|
void init();
|
||||||
bool end();
|
|
||||||
bool attach();
|
bool attach();
|
||||||
bool detach();
|
bool detach();
|
||||||
void setAddress(uint32_t addr);
|
void setAddress(uint32_t addr);
|
||||||
|
|
@ -85,7 +84,7 @@ public:
|
||||||
uint32_t sendControl(int /* ep */, const void *data, uint32_t len) { return sendControl(data, len); }
|
uint32_t sendControl(int /* ep */, const void *data, uint32_t len) { return sendControl(data, len); }
|
||||||
uint32_t recvControl(void *data, uint32_t len);
|
uint32_t recvControl(void *data, uint32_t len);
|
||||||
uint32_t sendConfiguration(uint32_t maxlen);
|
uint32_t sendConfiguration(uint32_t maxlen);
|
||||||
bool sendStringDescriptor(const uint8_t *string, uint32_t maxlen);
|
bool sendStringDescriptor(const uint8_t *string, uint8_t maxlen);
|
||||||
void initControl(int end);
|
void initControl(int end);
|
||||||
uint8_t SendInterfaces(uint32_t* total);
|
uint8_t SendInterfaces(uint32_t* total);
|
||||||
void packMessages(bool val);
|
void packMessages(bool val);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
#ifndef USE_TINYUSB
|
|
||||||
#if defined(USBCON)
|
#if defined(USBCON)
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
@ -110,12 +110,12 @@ static EPHandler *epHandlers[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
|
||||||
// Send a USB descriptor string. The string is stored as a
|
// Send a USB descriptor string. The string is stored as a
|
||||||
// plain ASCII string but is sent out as UTF-16 with the
|
// plain ASCII string but is sent out as UTF-16 with the
|
||||||
// correct 2-byte prefix
|
// correct 2-byte prefix
|
||||||
bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint32_t maxlen)
|
bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint8_t maxlen)
|
||||||
{
|
{
|
||||||
if (maxlen < 2)
|
if (maxlen < 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint8_t* buffer = (uint8_t*)malloc(maxlen);
|
uint8_t buffer[maxlen];
|
||||||
buffer[0] = strlen((const char*)string) * 2 + 2;
|
buffer[0] = strlen((const char*)string) * 2 + 2;
|
||||||
buffer[1] = 0x03;
|
buffer[1] = 0x03;
|
||||||
|
|
||||||
|
|
@ -126,9 +126,7 @@ bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint32_t maxlen
|
||||||
buffer[i] = 0;
|
buffer[i] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = USBDevice.sendControl(buffer, i);
|
return USBDevice.sendControl(buffer, i);
|
||||||
free(buffer);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _dry_run = false;
|
bool _dry_run = false;
|
||||||
|
|
@ -246,25 +244,26 @@ bool USBDeviceClass::sendDescriptor(USBSetup &setup)
|
||||||
}
|
}
|
||||||
else if (setup.wValueL == ISERIAL) {
|
else if (setup.wValueL == ISERIAL) {
|
||||||
#ifdef PLUGGABLE_USB_ENABLED
|
#ifdef PLUGGABLE_USB_ENABLED
|
||||||
#ifdef __SAMD51__
|
#if defined(__SAMD51__)
|
||||||
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x008061FC)
|
char name[ISERIAL_MAX_LEN];
|
||||||
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x00806010)
|
PluggableUSB().getShortName(name);
|
||||||
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x00806014)
|
return sendStringDescriptor((uint8_t*)name, setup.wLength);
|
||||||
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x00806018)
|
#else
|
||||||
#else // samd21
|
|
||||||
// from section 9.3.3 of the datasheet
|
// from section 9.3.3 of the datasheet
|
||||||
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x0080A00C)
|
#define SERIAL_NUMBER_WORD_0 *(volatile uint32_t*)(0x0080A00C)
|
||||||
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x0080A040)
|
#define SERIAL_NUMBER_WORD_1 *(volatile uint32_t*)(0x0080A040)
|
||||||
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x0080A044)
|
#define SERIAL_NUMBER_WORD_2 *(volatile uint32_t*)(0x0080A044)
|
||||||
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x0080A048)
|
#define SERIAL_NUMBER_WORD_3 *(volatile uint32_t*)(0x0080A048)
|
||||||
#endif
|
|
||||||
char name[ISERIAL_MAX_LEN];
|
char name[ISERIAL_MAX_LEN];
|
||||||
utox8(SERIAL_NUMBER_WORD_0, &name[0]);
|
utox8(SERIAL_NUMBER_WORD_0, &name[0]);
|
||||||
utox8(SERIAL_NUMBER_WORD_1, &name[8]);
|
utox8(SERIAL_NUMBER_WORD_1, &name[8]);
|
||||||
utox8(SERIAL_NUMBER_WORD_2, &name[16]);
|
utox8(SERIAL_NUMBER_WORD_2, &name[16]);
|
||||||
utox8(SERIAL_NUMBER_WORD_3, &name[24]);
|
utox8(SERIAL_NUMBER_WORD_3, &name[24]);
|
||||||
name[32] = '\0';
|
|
||||||
|
PluggableUSB().getShortName(&name[32]);
|
||||||
return sendStringDescriptor((uint8_t*)name, setup.wLength);
|
return sendStringDescriptor((uint8_t*)name, setup.wLength);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -435,13 +434,6 @@ bool USBDeviceClass::detach()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool USBDeviceClass::end() {
|
|
||||||
if (!initialized)
|
|
||||||
return false;
|
|
||||||
usbd.disable();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool USBDeviceClass::configured()
|
bool USBDeviceClass::configured()
|
||||||
{
|
{
|
||||||
return _usbConfiguration != 0;
|
return _usbConfiguration != 0;
|
||||||
|
|
@ -879,7 +871,6 @@ bool USBDeviceClass::handleStandardSetup(USBSetup &setup)
|
||||||
sendZlp(0);
|
sendZlp(0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
|
||||||
case SET_ADDRESS:
|
case SET_ADDRESS:
|
||||||
setAddress(setup.wValueL);
|
setAddress(setup.wValueL);
|
||||||
|
|
@ -1041,4 +1032,3 @@ void USBDeviceClass::ISRHandler()
|
||||||
USBDeviceClass USBDevice;
|
USBDeviceClass USBDevice;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif // USE_TINYUSB
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef USE_TINYUSB
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
@ -64,6 +63,7 @@ void UHD_Init(void)
|
||||||
uint32_t pad_transn;
|
uint32_t pad_transn;
|
||||||
uint32_t pad_transp;
|
uint32_t pad_transp;
|
||||||
uint32_t pad_trim;
|
uint32_t pad_trim;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
USB_SetHandler(&UHD_Handler);
|
USB_SetHandler(&UHD_Handler);
|
||||||
|
|
||||||
|
|
@ -172,7 +172,10 @@ void UHD_Init(void)
|
||||||
USB->HOST.DESCADD.reg = (uint32_t)(&usb_pipe_table[0]);
|
USB->HOST.DESCADD.reg = (uint32_t)(&usb_pipe_table[0]);
|
||||||
// For USB_SPEED_FULL
|
// For USB_SPEED_FULL
|
||||||
uhd_force_full_speed();
|
uhd_force_full_speed();
|
||||||
memset((void *)usb_pipe_table, 0, sizeof(usb_pipe_table));
|
for (i = 0; i < sizeof(usb_pipe_table); i++)
|
||||||
|
{
|
||||||
|
(*(uint32_t *)(&usb_pipe_table[0] + i)) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
uhd_state = UHD_STATE_NO_VBUS;
|
uhd_state = UHD_STATE_NO_VBUS;
|
||||||
|
|
||||||
|
|
@ -554,5 +557,3 @@ uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
#endif // HOST_DEFINED
|
#endif // HOST_DEFINED
|
||||||
|
|
||||||
#endif // USE_TINYUSB
|
|
||||||
|
|
|
||||||
|
|
@ -250,9 +250,8 @@ void detachInterrupt(uint32_t pin)
|
||||||
* External Interrupt Controller NVIC Interrupt Handler
|
* External Interrupt Controller NVIC Interrupt Handler
|
||||||
*/
|
*/
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
void InterruptHandler(uint32_t unused_i)
|
void InterruptHandler(uint32_t i)
|
||||||
{
|
{
|
||||||
(void)unused_i;
|
|
||||||
// Calling the routine directly from -here- takes about 1us
|
// Calling the routine directly from -here- takes about 1us
|
||||||
// Depending on where you are in the list it will take longer
|
// Depending on where you are in the list it will take longer
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ extern "C" {
|
||||||
#define FALLING 3
|
#define FALLING 3
|
||||||
#define RISING 4
|
#define RISING 4
|
||||||
|
|
||||||
//#define DEFAULT 1
|
#define DEFAULT 1
|
||||||
#define EXTERNAL 0
|
#define EXTERNAL 0
|
||||||
|
|
||||||
typedef void (*voidFuncPtr)(void);
|
typedef void (*voidFuncPtr)(void);
|
||||||
|
|
|
||||||
|
|
@ -693,21 +693,12 @@ void String::remove(unsigned int index){
|
||||||
}
|
}
|
||||||
|
|
||||||
void String::remove(unsigned int index, unsigned int count){
|
void String::remove(unsigned int index, unsigned int count){
|
||||||
// removes characters from the middle of a string.
|
if (index >= len) { return; }
|
||||||
if (count <= 0) { return; } // exit if nothing to remove
|
if (count <= 0) { return; }
|
||||||
if (index >= len) { return; } // ensure start is within string length; thus, ensures (len-index >= 1)
|
if (count > len - index) { count = len - index; }
|
||||||
if (count > len - index) { // ensure characters to remove is no larger than total length remaining
|
char *writeTo = buffer + index;
|
||||||
count = len - index;
|
|
||||||
}
|
|
||||||
char *writeTo = buffer + index;
|
|
||||||
char *copyFrom = buffer + index + count;
|
|
||||||
len = len - count;
|
len = len - count;
|
||||||
|
strncpy(writeTo, buffer + index + count,len - index);
|
||||||
// strncpy() cannot be used with overlapping buffers, so copy one char at a time
|
|
||||||
unsigned int charactersToMove = len - index; // yes, uses post-adjusted length
|
|
||||||
for (unsigned int i = 0; i < charactersToMove; i++, writeTo++, copyFrom++) {
|
|
||||||
*writeTo = *copyFrom;
|
|
||||||
}
|
|
||||||
buffer[len] = 0;
|
buffer[len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,6 @@ typedef enum _EAnalogChannel
|
||||||
ADC_Channel19=19,
|
ADC_Channel19=19,
|
||||||
DAC_Channel0,
|
DAC_Channel0,
|
||||||
DAC_Channel1,
|
DAC_Channel1,
|
||||||
ADC_Channel_Bandgap=0x1B,
|
|
||||||
ADC_Channel_PTAT=0x1C,
|
|
||||||
} EAnalogChannel ;
|
} EAnalogChannel ;
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
|
|
@ -90,7 +88,7 @@ typedef enum _ETCChannel
|
||||||
TC3_CH0 = (6<<8)|(0),
|
TC3_CH0 = (6<<8)|(0),
|
||||||
TC3_CH1 = (6<<8)|(1),
|
TC3_CH1 = (6<<8)|(1),
|
||||||
} ETCChannel ;
|
} ETCChannel ;
|
||||||
#elif defined(__SAMD51J19A__) || defined(__SAMD51J20A__) || defined(__SAME51J19A__)
|
#elif defined(__SAMD51J19A__) || defined(__SAMD51J20A__)
|
||||||
|
|
||||||
typedef enum _ETCChannel
|
typedef enum _ETCChannel
|
||||||
{
|
{
|
||||||
|
|
@ -101,16 +99,10 @@ typedef enum _ETCChannel
|
||||||
TCC0_CH3 = (0<<8)|(3),
|
TCC0_CH3 = (0<<8)|(3),
|
||||||
TCC0_CH4 = (0<<8)|(4),
|
TCC0_CH4 = (0<<8)|(4),
|
||||||
TCC0_CH5 = (0<<8)|(5),
|
TCC0_CH5 = (0<<8)|(5),
|
||||||
TCC0_CH6 = (0<<8)|(6),
|
|
||||||
TCC0_CH7 = (0<<8)|(7),
|
|
||||||
TCC1_CH0 = (1<<8)|(0),
|
TCC1_CH0 = (1<<8)|(0),
|
||||||
TCC1_CH1 = (1<<8)|(1),
|
TCC1_CH1 = (1<<8)|(1),
|
||||||
TCC1_CH2 = (1<<8)|(2),
|
TCC1_CH2 = (1<<8)|(2),
|
||||||
TCC1_CH3 = (1<<8)|(3),
|
TCC1_CH3 = (1<<8)|(3),
|
||||||
TCC1_CH4 = (1<<8)|(4),
|
|
||||||
TCC1_CH5 = (1<<8)|(5),
|
|
||||||
TCC1_CH6 = (1<<8)|(6),
|
|
||||||
TCC1_CH7 = (1<<8)|(7),
|
|
||||||
TCC2_CH0 = (2<<8)|(0),
|
TCC2_CH0 = (2<<8)|(0),
|
||||||
TCC2_CH1 = (2<<8)|(1),
|
TCC2_CH1 = (2<<8)|(1),
|
||||||
TCC2_CH2 = (2<<8)|(2),
|
TCC2_CH2 = (2<<8)|(2),
|
||||||
|
|
@ -130,13 +122,9 @@ typedef enum _ETCChannel
|
||||||
TC4_CH1 = (9<<8)|(1),
|
TC4_CH1 = (9<<8)|(1),
|
||||||
TC5_CH0 = (10<<8)|(0),
|
TC5_CH0 = (10<<8)|(0),
|
||||||
TC5_CH1 = (10<<8)|(1),
|
TC5_CH1 = (10<<8)|(1),
|
||||||
TC6_CH0 = (11<<8)|(0),
|
|
||||||
TC6_CH1 = (11<<8)|(1),
|
|
||||||
TC7_CH0 = (12<<8)|(0),
|
|
||||||
TC7_CH1 = (12<<8)|(1),
|
|
||||||
} ETCChannel ;
|
} ETCChannel ;
|
||||||
|
|
||||||
#elif defined(__SAME53N20A__) || defined(__SAME53N19A__) || defined(__SAME54P20A__) || defined(__SAME54P19A__) || defined(__SAME54N20A__) || defined(__SAME54N19A__) || defined(__SAMD51P20A__) || defined(__SAMD51P19A__) || defined(__SAMD51N20A__) || defined(__SAMD51N19A__) || defined(__SAME51N20A__) || defined(__SAME51N19A__)
|
#elif defined(__SAMD51P19A__) || defined(__SAMD51P20A__)
|
||||||
|
|
||||||
typedef enum _ETCChannel
|
typedef enum _ETCChannel
|
||||||
{
|
{
|
||||||
|
|
@ -210,12 +198,6 @@ typedef enum _ETCChannel
|
||||||
TC4_CH1 = (4<<8)|(1),
|
TC4_CH1 = (4<<8)|(1),
|
||||||
TC5_CH0 = (5<<8)|(0),
|
TC5_CH0 = (5<<8)|(0),
|
||||||
TC5_CH1 = (5<<8)|(1),
|
TC5_CH1 = (5<<8)|(1),
|
||||||
#if defined (__SAMD21J18A__)
|
|
||||||
TC6_CH0 = (6<<8)|(0),
|
|
||||||
TC6_CH1 = (6<<8)|(1),
|
|
||||||
TC7_CH0 = (7<<8)|(0),
|
|
||||||
TC7_CH1 = (7<<8)|(1),
|
|
||||||
#endif // __SAMD21J18A__
|
|
||||||
} ETCChannel ;
|
} ETCChannel ;
|
||||||
|
|
||||||
// Definitions for PWM channels
|
// Definitions for PWM channels
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,8 @@
|
||||||
#ifndef _IO_H_
|
#ifndef _IO_H_
|
||||||
#define _IO_H_
|
#define _IO_H_
|
||||||
|
|
||||||
#ifdef __SAMD51__
|
#define RAMSTART (HMCRAMC0_ADDR)
|
||||||
#define RAMSTART (HSRAM_ADDR)
|
#define RAMSIZE (HMCRAMC0_SIZE)
|
||||||
#define RAMSIZE (HSRAM_SIZE)
|
|
||||||
#else
|
|
||||||
#define RAMSTART (HMCRAMC0_ADDR)
|
|
||||||
#define RAMSIZE (HMCRAMC0_SIZE)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RAMEND (RAMSTART + RAMSIZE - 1)
|
#define RAMEND (RAMSTART + RAMSIZE - 1)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -127,13 +127,10 @@ void SERCOM7_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Han
|
||||||
void SERCOM7_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
void SERCOM7_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
||||||
void SERCOM7_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
void SERCOM7_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
||||||
void SERCOM7_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
void SERCOM7_3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
||||||
void CAN0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
|
||||||
void CAN1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
|
||||||
void USB_0_Handler ( void ) __attribute__ ((weak));
|
void USB_0_Handler ( void ) __attribute__ ((weak));
|
||||||
void USB_1_Handler ( void ) __attribute__ ((weak));
|
void USB_1_Handler ( void ) __attribute__ ((weak));
|
||||||
void USB_2_Handler ( void ) __attribute__ ((weak));
|
void USB_2_Handler ( void ) __attribute__ ((weak));
|
||||||
void USB_3_Handler ( void ) __attribute__ ((weak));
|
void USB_3_Handler ( void ) __attribute__ ((weak));
|
||||||
void GMAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
|
||||||
void TCC0_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
void TCC0_0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
||||||
void TCC0_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
void TCC0_1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
||||||
void TCC0_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
void TCC0_2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
|
||||||
|
|
@ -196,7 +193,6 @@ extern uint32_t __bss_end__;
|
||||||
extern uint32_t __StackTop;
|
extern uint32_t __StackTop;
|
||||||
|
|
||||||
/* Exception Table */
|
/* Exception Table */
|
||||||
__attribute__ ((used))
|
|
||||||
__attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table =
|
__attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table =
|
||||||
{
|
{
|
||||||
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
||||||
|
|
@ -298,13 +294,13 @@ __attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table =
|
||||||
(void*) SERCOM7_1_Handler, /* 75 Serial Communication Interface 7 IRQ 1 */
|
(void*) SERCOM7_1_Handler, /* 75 Serial Communication Interface 7 IRQ 1 */
|
||||||
(void*) SERCOM7_2_Handler, /* 76 Serial Communication Interface 7 IRQ 2 */
|
(void*) SERCOM7_2_Handler, /* 76 Serial Communication Interface 7 IRQ 2 */
|
||||||
(void*) SERCOM7_3_Handler, /* 77 Serial Communication Interface 7 IRQ 3 */
|
(void*) SERCOM7_3_Handler, /* 77 Serial Communication Interface 7 IRQ 3 */
|
||||||
(void*) CAN0_Handler, /* 78 Control Area Network 0 (SAM E5x) */
|
(void*) (0UL),
|
||||||
(void*) CAN1_Handler, /* 79 Control Area Network 0 (SAM E5x) */
|
(void*) (0UL),
|
||||||
(void*) USB_0_Handler, /* 80 Universal Serial Bus IRQ 0 */
|
(void*) USB_0_Handler, /* 80 Universal Serial Bus IRQ 0 */
|
||||||
(void*) USB_1_Handler, /* 81 Universal Serial Bus IRQ 1 */
|
(void*) USB_1_Handler, /* 81 Universal Serial Bus IRQ 1 */
|
||||||
(void*) USB_2_Handler, /* 82 Universal Serial Bus IRQ 2 */
|
(void*) USB_2_Handler, /* 82 Universal Serial Bus IRQ 2 */
|
||||||
(void*) USB_3_Handler, /* 83 Universal Serial Bus IRQ 3 */
|
(void*) USB_3_Handler, /* 83 Universal Serial Bus IRQ 3 */
|
||||||
(void*) GMAC_Handler, /* 84 Ethernet MAC */
|
(void*) (0UL),
|
||||||
(void*) TCC0_0_Handler, /* 85 Timer Counter Control 0 IRQ 0 */
|
(void*) TCC0_0_Handler, /* 85 Timer Counter Control 0 IRQ 0 */
|
||||||
(void*) TCC0_1_Handler, /* 86 Timer Counter Control 0 IRQ 1 */
|
(void*) TCC0_1_Handler, /* 86 Timer Counter Control 0 IRQ 1 */
|
||||||
(void*) TCC0_2_Handler, /* 87 Timer Counter Control 0 IRQ 2 */
|
(void*) TCC0_2_Handler, /* 87 Timer Counter Control 0 IRQ 2 */
|
||||||
|
|
@ -408,7 +404,6 @@ extern uint32_t __bss_end__;
|
||||||
extern uint32_t __StackTop;
|
extern uint32_t __StackTop;
|
||||||
|
|
||||||
/* Exception Table */
|
/* Exception Table */
|
||||||
__attribute__ ((used))
|
|
||||||
__attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table =
|
__attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table =
|
||||||
{
|
{
|
||||||
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
||||||
|
|
|
||||||
|
|
@ -61,51 +61,19 @@ unsigned long micros( void )
|
||||||
// a runtime multiplication and shift, saving a few cycles
|
// a runtime multiplication and shift, saving a few cycles
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __SAMD51__
|
|
||||||
/*
|
|
||||||
* On SAMD51, use the (32bit) cycle count maintained by the DWT unit,
|
|
||||||
* and count exact number of cycles elapsed, rather than guessing how
|
|
||||||
* many cycles a loop takes, which is dangerous in the presence of
|
|
||||||
* cache. The overhead of the call and internal code is "about" 20
|
|
||||||
* cycles. (at 120MHz, that's about 1/6 us)
|
|
||||||
*/
|
|
||||||
void delayMicroseconds(unsigned int us)
|
|
||||||
{
|
|
||||||
uint32_t start, elapsed;
|
|
||||||
uint32_t count;
|
|
||||||
|
|
||||||
if (us == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
count = us * (VARIANT_MCK / 1000000) - 20; // convert us to cycles.
|
|
||||||
start = DWT->CYCCNT; //CYCCNT is 32bits, takes 37s or so to wrap.
|
|
||||||
while (1) {
|
|
||||||
elapsed = DWT->CYCCNT - start;
|
|
||||||
if (elapsed >= count)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void delay( unsigned long ms )
|
void delay( unsigned long ms )
|
||||||
{
|
{
|
||||||
if (ms == 0)
|
if ( ms == 0 )
|
||||||
{
|
{
|
||||||
return;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t start = micros();
|
uint32_t start = _ulTickCount ;
|
||||||
|
|
||||||
while (ms > 0)
|
do
|
||||||
{
|
{
|
||||||
yield();
|
yield() ;
|
||||||
while (ms > 0 && (micros() - start) >= 1000)
|
} while ( _ulTickCount - start < ms ) ;
|
||||||
{
|
|
||||||
ms--;
|
|
||||||
start += 1000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Reset.h" // for tickReset()
|
#include "Reset.h" // for tickReset()
|
||||||
|
|
@ -117,17 +85,6 @@ void SysTick_DefaultHandler(void)
|
||||||
tickReset();
|
tickReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_TINYUSB)
|
|
||||||
|
|
||||||
// run TinyUSB background task when yield()
|
|
||||||
void yield(void)
|
|
||||||
{
|
|
||||||
TinyUSB_Device_Task();
|
|
||||||
TinyUSB_Device_FlushCDC();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,6 @@ extern void delay( unsigned long dwMs ) ;
|
||||||
*
|
*
|
||||||
* \param dwUs the number of microseconds to pause (uint32_t)
|
* \param dwUs the number of microseconds to pause (uint32_t)
|
||||||
*/
|
*/
|
||||||
#if defined(__SAMD51__)
|
|
||||||
extern void delayMicroseconds( unsigned int );
|
|
||||||
#else
|
|
||||||
static __inline__ void delayMicroseconds( unsigned int ) __attribute__((always_inline, unused)) ;
|
static __inline__ void delayMicroseconds( unsigned int ) __attribute__((always_inline, unused)) ;
|
||||||
static __inline__ void delayMicroseconds( unsigned int usec )
|
static __inline__ void delayMicroseconds( unsigned int usec )
|
||||||
{
|
{
|
||||||
|
|
@ -71,6 +68,21 @@ static __inline__ void delayMicroseconds( unsigned int usec )
|
||||||
{
|
{
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__SAMD51__)
|
||||||
|
uint32_t n = usec * (VARIANT_MCK / 1000000) / 12;
|
||||||
|
|
||||||
|
__asm__ __volatile__(
|
||||||
|
"1: \n"
|
||||||
|
" sub %0, #1 \n" // substract 1 from %0 (n)
|
||||||
|
" cmp %0, #0 \n" // compare to 0
|
||||||
|
" bne 1b \n" // if result is not 0 jump to 1
|
||||||
|
: "+r" (n) // '%0' is n variable with RW constraints
|
||||||
|
: // no input
|
||||||
|
: // no clobber
|
||||||
|
);
|
||||||
|
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* The following loop:
|
* The following loop:
|
||||||
*
|
*
|
||||||
|
|
@ -97,10 +109,10 @@ static __inline__ void delayMicroseconds( unsigned int usec )
|
||||||
: // no input
|
: // no input
|
||||||
: // no clobber
|
: // no clobber
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
|
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
|
||||||
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile
|
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@
|
||||||
static void __empty() {
|
static void __empty() {
|
||||||
// Empty
|
// Empty
|
||||||
}
|
}
|
||||||
|
|
||||||
void yield(void) __attribute__ ((weak, alias("__empty")));
|
void yield(void) __attribute__ ((weak, alias("__empty")));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,7 @@ int main( void )
|
||||||
initVariant();
|
initVariant();
|
||||||
|
|
||||||
delay(1);
|
delay(1);
|
||||||
|
#if defined(USBCON)
|
||||||
#if defined(USE_TINYUSB)
|
|
||||||
TinyUSB_Device_Init(0);
|
|
||||||
#elif defined(USBCON)
|
|
||||||
USBDevice.init();
|
USBDevice.init();
|
||||||
USBDevice.attach();
|
USBDevice.attach();
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -52,8 +49,6 @@ int main( void )
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
loop();
|
loop();
|
||||||
yield(); // yield run usb background task
|
|
||||||
|
|
||||||
if (serialEventRun) serialEventRun();
|
if (serialEventRun) serialEventRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -164,19 +164,18 @@ void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
|
||||||
uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
|
uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int32_t diff;
|
int32_t diff, diffCrnt = 0;
|
||||||
uint32_t diffCrnt = 0;
|
|
||||||
uint32_t maxDiff = 0;
|
uint32_t maxDiff = 0;
|
||||||
|
|
||||||
for (i = 0; i < numSamples; i++)
|
for (i = 0; i < numSamples; i++)
|
||||||
{
|
{
|
||||||
diff = pIn[i] - pOut[i];
|
diff = pIn[i] - pOut[i];
|
||||||
diffCrnt = (uint32_t)( (diff > 0) ? diff : -diff );
|
diffCrnt = (diff > 0) ? diff : -diff;
|
||||||
|
|
||||||
if(diffCrnt > maxDiff)
|
if(diffCrnt > maxDiff)
|
||||||
{
|
{
|
||||||
maxDiff = diffCrnt;
|
maxDiff = diffCrnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(maxDiff);
|
return(maxDiff);
|
||||||
|
|
@ -193,19 +192,18 @@ uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
|
||||||
uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
|
uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int32_t diff;
|
int32_t diff, diffCrnt = 0;
|
||||||
uint32_t diffCrnt = 0;
|
|
||||||
uint32_t maxDiff = 0;
|
uint32_t maxDiff = 0;
|
||||||
|
|
||||||
for (i = 0; i < numSamples; i++)
|
for (i = 0; i < numSamples; i++)
|
||||||
{
|
{
|
||||||
diff = pIn[i] - pOut[i];
|
diff = pIn[i] - pOut[i];
|
||||||
diffCrnt = (uint32_t)( (diff > 0) ? diff : -diff );
|
diffCrnt = (diff > 0) ? diff : -diff;
|
||||||
|
|
||||||
if(diffCrnt > maxDiff)
|
if(diffCrnt > maxDiff)
|
||||||
{
|
{
|
||||||
maxDiff = diffCrnt;
|
maxDiff = diffCrnt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(maxDiff);
|
return(maxDiff);
|
||||||
|
|
|
||||||
|
|
@ -34,36 +34,6 @@ uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout)
|
||||||
uint32_t bit = 1 << p.ulPin;
|
uint32_t bit = 1 << p.ulPin;
|
||||||
uint32_t stateMask = state ? bit : 0;
|
uint32_t stateMask = state ? bit : 0;
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
/*
|
|
||||||
* The SAMD51 is fast enough to use really obvious code (similar to
|
|
||||||
* what was used to produce pulse_asm.S, but using micros() for timing.
|
|
||||||
* No assembly required, no conversion of loop counts to times (which is
|
|
||||||
* worrisome in the presence of cache.)
|
|
||||||
*/
|
|
||||||
const volatile uint32_t *port = &(PORT->Group[p.ulPort].IN.reg);
|
|
||||||
uint32_t usCallStart; // microseconds at start of call, for timeout.
|
|
||||||
uint32_t usPulseStart; // microseconds at start of measured pulse.
|
|
||||||
usCallStart = usPulseStart = micros();
|
|
||||||
// wait for any previous pulse to end
|
|
||||||
while ((*port & bit) == stateMask) {
|
|
||||||
if (micros() - usCallStart > timeout)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// wait for the pulse to start
|
|
||||||
while ((*port & bit) != stateMask) {
|
|
||||||
usPulseStart = micros();
|
|
||||||
if (usPulseStart - usCallStart > timeout)
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// wait for the pulse to stop
|
|
||||||
while ((*port & bit) == stateMask) {
|
|
||||||
if (micros() - usCallStart > timeout)
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
return micros() - usPulseStart;
|
|
||||||
#else
|
|
||||||
// convert the timeout from microseconds to a number of times through
|
// convert the timeout from microseconds to a number of times through
|
||||||
// the initial loop; it takes (roughly) 13 clock cycles per iteration.
|
// the initial loop; it takes (roughly) 13 clock cycles per iteration.
|
||||||
uint32_t maxloops = microsecondsToClockCycles(timeout) / 13;
|
uint32_t maxloops = microsecondsToClockCycles(timeout) / 13;
|
||||||
|
|
@ -78,6 +48,5 @@ uint32_t pulseIn(uint32_t pin, uint32_t state, uint32_t timeout)
|
||||||
return clockCyclesToMicroseconds(width * 13 + 16);
|
return clockCyclesToMicroseconds(width * 13 + 16);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
#endif // SAMD51
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
//USE DPLL0 for 120MHZ
|
//USE DPLL0 for 120MHZ
|
||||||
#define MAIN_CLOCK_SOURCE GCLK_GENCTRL_SRC_DPLL0
|
#define MAIN_CLOCK_SOURCE GCLK_GENCTRL_SRC_DPLL0
|
||||||
|
|
||||||
#define GENERIC_CLOCK_GENERATOR_1M (5u)
|
#define GENERIC_CLOCK_GENERATOR_1M (7u)
|
||||||
//#define CRYSTALLESS
|
//#define CRYSTALLESS
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
@ -63,7 +63,7 @@ void SystemInit( void )
|
||||||
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
|
* 1) Enable XOSC32K clock (External on-board 32.768Hz oscillator)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_EN1K | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_CGM_XT | OSC32KCTRL_XOSC32K_XTALEN;
|
OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_CGM_XT | OSC32KCTRL_XOSC32K_XTALEN;
|
||||||
|
|
||||||
while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){
|
while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){
|
||||||
/* Wait for oscillator to be ready */
|
/* Wait for oscillator to be ready */
|
||||||
|
|
@ -97,7 +97,7 @@ void SystemInit( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------------------------
|
||||||
* 3) Put OSCULP32K as source for Generic Clock Generator 0
|
* 3) Put Generic Clock Generator 3 as source for Generic Clock Gen 0 (DFLL48M reference)
|
||||||
*/
|
*/
|
||||||
GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN;
|
GCLK->GENCTRL[0].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSCULP32K) | GCLK_GENCTRL_GENEN;
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ void SystemInit( void )
|
||||||
/* Wait for synchronization */
|
/* Wait for synchronization */
|
||||||
}
|
}
|
||||||
|
|
||||||
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_1M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(48u);
|
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_1M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_DIV(24u);
|
||||||
|
|
||||||
while ( GCLK->SYNCBUSY.bit.GENCTRL5 ){
|
while ( GCLK->SYNCBUSY.bit.GENCTRL5 ){
|
||||||
/* Wait for synchronization */
|
/* Wait for synchronization */
|
||||||
|
|
@ -158,10 +158,9 @@ void SystemInit( void )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//PLL0 is 120MHz
|
//PLL0 is 120MHz
|
||||||
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val);
|
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL0].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK7_Val);
|
||||||
|
|
||||||
// This rounds to nearest full-MHz increment; not currently using frac
|
OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(59); //120 Mhz
|
||||||
OSCCTRL->Dpll[0].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR((F_CPU - 500000) / 1000000);
|
|
||||||
|
|
||||||
while(OSCCTRL->Dpll[0].DPLLSYNCBUSY.bit.DPLLRATIO);
|
while(OSCCTRL->Dpll[0].DPLLSYNCBUSY.bit.DPLLRATIO);
|
||||||
|
|
||||||
|
|
@ -173,9 +172,9 @@ void SystemInit( void )
|
||||||
while( OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK == 0 );
|
while( OSCCTRL->Dpll[0].DPLLSTATUS.bit.CLKRDY == 0 || OSCCTRL->Dpll[0].DPLLSTATUS.bit.LOCK == 0 );
|
||||||
|
|
||||||
//PLL1 is 100MHz
|
//PLL1 is 100MHz
|
||||||
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK5_Val);
|
GCLK->PCHCTRL[OSCCTRL_GCLK_ID_FDPLL1].reg = (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(GCLK_PCHCTRL_GEN_GCLK7_Val);
|
||||||
|
|
||||||
OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(99); //100 Mhz
|
OSCCTRL->Dpll[1].DPLLRATIO.reg = OSCCTRL_DPLLRATIO_LDRFRAC(0x00) | OSCCTRL_DPLLRATIO_LDR(49); //100 Mhz
|
||||||
|
|
||||||
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.DPLLRATIO);
|
while(OSCCTRL->Dpll[1].DPLLSYNCBUSY.bit.DPLLRATIO);
|
||||||
|
|
||||||
|
|
@ -217,7 +216,7 @@ void SystemInit( void )
|
||||||
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_12M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) |
|
GCLK->GENCTRL[GENERIC_CLOCK_GENERATOR_12M].reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_DFLL_Val) |
|
||||||
GCLK_GENCTRL_IDC |
|
GCLK_GENCTRL_IDC |
|
||||||
GCLK_GENCTRL_DIV(4) |
|
GCLK_GENCTRL_DIV(4) |
|
||||||
//GCLK_GENCTRL_DIVSEL |
|
GCLK_GENCTRL_DIVSEL |
|
||||||
//GCLK_GENCTRL_OE |
|
//GCLK_GENCTRL_OE |
|
||||||
GCLK_GENCTRL_GENEN;
|
GCLK_GENCTRL_GENEN;
|
||||||
|
|
||||||
|
|
@ -253,55 +252,7 @@ void SystemInit( void )
|
||||||
CMCC->CTRL.reg = 1;
|
CMCC->CTRL.reg = 1;
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*---------------------------------------------------------------------
|
|
||||||
* Start up the "Debug Watchpoint and Trace" unit, so that we can use
|
|
||||||
* it's 32bit cycle counter for timing.
|
|
||||||
*/
|
|
||||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
|
||||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------------------------
|
|
||||||
* 5) Load AC factory calibration values
|
|
||||||
*/
|
|
||||||
|
|
||||||
uint32_t bias0 = (*((uint32_t *)AC_FUSES_BIAS0_ADDR) & AC_FUSES_BIAS0_Msk) >> AC_FUSES_BIAS0_Pos;
|
|
||||||
AC->CALIB.reg = AC_CALIB_BIAS0(bias0);
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------------------------
|
|
||||||
* 6) Load ADC factory calibration values
|
|
||||||
*/
|
|
||||||
|
|
||||||
// ADC0 Bias Calibration
|
|
||||||
uint32_t biascomp = (*((uint32_t *)ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
|
|
||||||
uint32_t biasr2r = (*((uint32_t *)ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
|
|
||||||
uint32_t biasref = (*((uint32_t *)ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
|
|
||||||
|
|
||||||
ADC0->CALIB.reg = ADC_CALIB_BIASREFBUF(biasref)
|
|
||||||
| ADC_CALIB_BIASR2R(biasr2r)
|
|
||||||
| ADC_CALIB_BIASCOMP(biascomp);
|
|
||||||
|
|
||||||
// ADC1 Bias Calibration
|
|
||||||
biascomp = (*((uint32_t *)ADC1_FUSES_BIASCOMP_ADDR) & ADC1_FUSES_BIASCOMP_Msk) >> ADC1_FUSES_BIASCOMP_Pos;
|
|
||||||
biasr2r = (*((uint32_t *)ADC1_FUSES_BIASR2R_ADDR) & ADC1_FUSES_BIASR2R_Msk) >> ADC1_FUSES_BIASR2R_Pos;
|
|
||||||
biasref = (*((uint32_t *)ADC1_FUSES_BIASREFBUF_ADDR) & ADC1_FUSES_BIASREFBUF_Msk) >> ADC1_FUSES_BIASREFBUF_Pos;
|
|
||||||
|
|
||||||
ADC1->CALIB.reg = ADC_CALIB_BIASREFBUF(biasref)
|
|
||||||
| ADC_CALIB_BIASR2R(biasr2r)
|
|
||||||
| ADC_CALIB_BIASCOMP(biascomp);
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------------------------
|
|
||||||
* 7) Load USB factory calibration values
|
|
||||||
*/
|
|
||||||
|
|
||||||
//USB Calibration
|
|
||||||
uint32_t usbtransn = (*((uint32_t *)USB_FUSES_TRANSN_ADDR) & USB_FUSES_TRANSN_Msk) >> USB_FUSES_TRANSN_Pos;
|
|
||||||
uint32_t usbtransp = (*((uint32_t *)USB_FUSES_TRANSP_ADDR) & USB_FUSES_TRANSP_Msk) >> USB_FUSES_TRANSP_Pos;
|
|
||||||
uint32_t usbtrim = (*((uint32_t *)USB_FUSES_TRIM_ADDR) & USB_FUSES_TRIM_Msk) >> USB_FUSES_TRIM_Pos;
|
|
||||||
USB->DEVICE.PADCAL.reg = USB_PADCAL_TRIM(usbtrim)
|
|
||||||
| USB_PADCAL_TRANSN(usbtransn)
|
|
||||||
| USB_PADCAL_TRANSP(usbtransp);
|
|
||||||
|
|
||||||
//*************** END SAMD51 *************************//
|
//*************** END SAMD51 *************************//
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
@ -577,3 +528,4 @@ void SystemInit( void )
|
||||||
NVMCTRL->CTRLB.bit.MANW = 1;
|
NVMCTRL->CTRLB.bit.MANW = 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ extern "C" {
|
||||||
|
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
uint32_t SystemCoreClock=F_CPU;
|
//CHANGE THIS IF YOU CHANGE THE CLOCK SPEED
|
||||||
|
uint32_t SystemCoreClock=120000000ul ;
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
* System Core Clock is at 1MHz (8MHz/8) at Reset.
|
* System Core Clock is at 1MHz (8MHz/8) at Reset.
|
||||||
|
|
@ -92,7 +93,7 @@ void init( void )
|
||||||
PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 | PM_APBCMASK_SERCOM1 | PM_APBCMASK_SERCOM2 | PM_APBCMASK_SERCOM3 | PM_APBCMASK_SERCOM4 | PM_APBCMASK_SERCOM5 ;
|
PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0 | PM_APBCMASK_SERCOM1 | PM_APBCMASK_SERCOM2 | PM_APBCMASK_SERCOM3 | PM_APBCMASK_SERCOM4 | PM_APBCMASK_SERCOM5 ;
|
||||||
|
|
||||||
// Clock TC/TCC for Pulse and Analog
|
// Clock TC/TCC for Pulse and Analog
|
||||||
PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 | PM_APBCMASK_TC6 | PM_APBCMASK_TC7;
|
PM->APBCMASK.reg |= PM_APBCMASK_TCC0 | PM_APBCMASK_TCC1 | PM_APBCMASK_TCC2 | PM_APBCMASK_TC3 | PM_APBCMASK_TC4 | PM_APBCMASK_TC5 ;
|
||||||
|
|
||||||
// ATSAMR, for example, doesn't have a DAC
|
// ATSAMR, for example, doesn't have a DAC
|
||||||
#ifdef PM_APBCMASK_DAC
|
#ifdef PM_APBCMASK_DAC
|
||||||
|
|
@ -101,16 +102,11 @@ void init( void )
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
Commented out to leave pins in default tri-state. This is
|
|
||||||
aimed at avoiding power consumption in DeepSleep.
|
|
||||||
|
|
||||||
// Setup all pins (digital and analog) in INPUT mode (default is nothing)
|
// Setup all pins (digital and analog) in INPUT mode (default is nothing)
|
||||||
for (uint32_t ul = 0 ; ul < NUM_DIGITAL_PINS ; ul++ )
|
for (uint32_t ul = 0 ; ul < NUM_DIGITAL_PINS ; ul++ )
|
||||||
{
|
{
|
||||||
pinMode( ul, INPUT ) ;
|
pinMode( ul, INPUT ) ;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Initialize Analog Controller
|
// Initialize Analog Controller
|
||||||
// Setting clock
|
// Setting clock
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ static int _writeResolution = 12;
|
||||||
static int _dacResolution = 12;
|
static int _dacResolution = 12;
|
||||||
#else
|
#else
|
||||||
static int _writeResolution = 8;
|
static int _writeResolution = 8;
|
||||||
//static int _dacResolution = 10;
|
static int _dacResolution = 10;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -140,87 +140,38 @@ void analogReference(eAnalogReference mode)
|
||||||
//TODO: fix gains
|
//TODO: fix gains
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case AR_INTERNAL1V0:
|
case AR_INTERNAL:
|
||||||
|
case AR_INTERNAL2V23:
|
||||||
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
||||||
SUPC->VREF.bit.SEL = SUPC_VREF_SEL_1V0_Val; // select 1.0V
|
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
|
||||||
SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC
|
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF
|
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; //
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AR_INTERNAL1V1:
|
|
||||||
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
|
||||||
SUPC->VREF.bit.SEL = SUPC_VREF_SEL_1V1_Val; // select 1.1V
|
|
||||||
SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC
|
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF
|
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; //
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AR_INTERNAL1V2:
|
|
||||||
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
|
||||||
SUPC->VREF.bit.SEL = SUPC_VREF_SEL_1V2_Val; // select 1V2
|
|
||||||
SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC
|
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF
|
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; //
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AR_INTERNAL1V25:
|
|
||||||
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
|
||||||
SUPC->VREF.bit.SEL = SUPC_VREF_SEL_1V25_Val; // select 1.25V
|
|
||||||
SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC
|
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF
|
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; //
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AR_INTERNAL2V0:
|
|
||||||
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
|
||||||
SUPC->VREF.bit.SEL = SUPC_VREF_SEL_2V0_Val; // select 2.0V
|
|
||||||
SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC
|
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF
|
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; //
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AR_INTERNAL2V2:
|
|
||||||
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
|
||||||
SUPC->VREF.bit.SEL = SUPC_VREF_SEL_2V2_Val; // select 2.2V
|
|
||||||
SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC
|
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF
|
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; //
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AR_INTERNAL2V4:
|
|
||||||
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
|
||||||
SUPC->VREF.bit.SEL = SUPC_VREF_SEL_2V4_Val; // select 2.4V
|
|
||||||
SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC
|
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF
|
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; //
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AR_INTERNAL2V5:
|
|
||||||
//ADC0->GAINCORR.reg = ADC_GAINCORR_GAINCORR(); // Gain Factor Selection
|
|
||||||
SUPC->VREF.bit.SEL = SUPC_VREF_SEL_2V5_Val; // select 2.5V
|
|
||||||
SUPC->VREF.bit.VREFOE = 1; // Turn on for use with ADC
|
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; // Use SUPC.VREF
|
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTREF_Val; //
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AR_EXTERNAL:
|
case AR_EXTERNAL:
|
||||||
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
|
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val; // AREF is jumpered to VCC, so 3.3V
|
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
|
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AR_INTERNAL1V65:
|
/* Don't think this works on SAMD51
|
||||||
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
|
case AR_INTERNAL1V0:
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/2 VDDANA = 1.65
|
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; //
|
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val; // 1.0V voltage reference
|
||||||
break;
|
break;
|
||||||
|
*/
|
||||||
|
|
||||||
|
case AR_INTERNAL1V65:
|
||||||
|
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
|
||||||
|
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
|
||||||
|
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
|
||||||
|
break;
|
||||||
|
|
||||||
case AR_DEFAULT:
|
case AR_DEFAULT:
|
||||||
default:
|
default:
|
||||||
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
|
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
|
||||||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // VDDANA = 3V3
|
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
|
||||||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; //
|
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,6 +179,7 @@ void analogReference(eAnalogReference mode)
|
||||||
syncADC();
|
syncADC();
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
|
case AR_INTERNAL:
|
||||||
case AR_INTERNAL2V23:
|
case AR_INTERNAL2V23:
|
||||||
ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
|
ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
|
||||||
ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
|
ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
|
||||||
|
|
@ -280,8 +232,8 @@ uint32_t analogRead(uint32_t pin)
|
||||||
#ifdef DAC
|
#ifdef DAC
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
if (pin == PIN_DAC0 || pin == PIN_DAC1) { // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
|
if (pin == A0 || pin == A1) { // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
|
||||||
uint8_t channel = (pin == PIN_DAC0 ? 0 : 1);
|
uint8_t channel = (pin == PIN_A0 ? 0 : 1);
|
||||||
|
|
||||||
if(dacEnabled[channel]){
|
if(dacEnabled[channel]){
|
||||||
dacEnabled[channel] = false;
|
dacEnabled[channel] = false;
|
||||||
|
|
@ -298,7 +250,7 @@ uint32_t analogRead(uint32_t pin)
|
||||||
|
|
||||||
while (DAC->SYNCBUSY.bit.ENABLE);
|
while (DAC->SYNCBUSY.bit.ENABLE);
|
||||||
#else
|
#else
|
||||||
if (pin == PIN_DAC0) { // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
|
if (pin == A0) { // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled
|
||||||
syncDAC();
|
syncDAC();
|
||||||
|
|
||||||
DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC
|
DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC
|
||||||
|
|
@ -375,9 +327,6 @@ uint32_t analogRead(uint32_t pin)
|
||||||
syncADC();
|
syncADC();
|
||||||
ADC->SWTRIG.bit.START = 1;
|
ADC->SWTRIG.bit.START = 1;
|
||||||
|
|
||||||
// Waiting for the 1st conversion to complete
|
|
||||||
while (ADC->INTFLAG.bit.RESRDY == 0);
|
|
||||||
|
|
||||||
// Clear the Data Ready flag
|
// Clear the Data Ready flag
|
||||||
ADC->INTFLAG.reg = ADC_INTFLAG_RESRDY;
|
ADC->INTFLAG.reg = ADC_INTFLAG_RESRDY;
|
||||||
|
|
||||||
|
|
@ -409,21 +358,21 @@ void analogWrite(uint32_t pin, uint32_t value)
|
||||||
|
|
||||||
// ATSAMR, for example, doesn't have a DAC
|
// ATSAMR, for example, doesn't have a DAC
|
||||||
#ifdef DAC
|
#ifdef DAC
|
||||||
|
|
||||||
if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG)
|
if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG)
|
||||||
{
|
{
|
||||||
// DAC handling code
|
// DAC handling code
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
if (pin == PIN_DAC0 || pin == PIN_DAC1) { // 2 DACs on A0 (PA02) and A1 (PA05)
|
if (pin == PIN_A0 || pin == PIN_A1) { // 2 DACs on A0 (PA02) and A1 (PA05)
|
||||||
#else
|
#else
|
||||||
if (pin == PIN_DAC0) { // Only 1 DAC on A0 (PA02)
|
if (pin == PIN_A0) { // Only 1 DAC on A0 (PA02)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
value = mapResolution(value, _writeResolution, _dacResolution);
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(__SAMD51__)
|
||||||
|
|
||||||
value = mapResolution(value, _writeResolution, _dacResolution);
|
uint8_t channel = (pin == PIN_A0 ? 0 : 1);
|
||||||
|
|
||||||
|
|
||||||
uint8_t channel = (pin == PIN_DAC0 ? 0 : 1);
|
|
||||||
|
|
||||||
pinPeripheral(pin, PIO_ANALOG);
|
pinPeripheral(pin, PIO_ANALOG);
|
||||||
|
|
||||||
|
|
@ -608,6 +557,7 @@ void analogWrite(uint32_t pin, uint32_t value)
|
||||||
|
|
||||||
if (!tcEnabled[tcNum]) {
|
if (!tcEnabled[tcNum]) {
|
||||||
tcEnabled[tcNum] = true;
|
tcEnabled[tcNum] = true;
|
||||||
|
value = mapResolution(value, _writeResolution, 16);
|
||||||
uint16_t GCLK_CLKCTRL_IDs[] = {
|
uint16_t GCLK_CLKCTRL_IDs[] = {
|
||||||
GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC0
|
GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC0
|
||||||
GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC1
|
GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC1
|
||||||
|
|
|
||||||
|
|
@ -27,21 +27,14 @@ extern "C" {
|
||||||
/*
|
/*
|
||||||
* \brief SAMD products have only one reference for ADC
|
* \brief SAMD products have only one reference for ADC
|
||||||
*/
|
*/
|
||||||
// add internal voltages for ATSAMD51 SUPC VREF register
|
|
||||||
typedef enum _eAnalogReference
|
typedef enum _eAnalogReference
|
||||||
{
|
{
|
||||||
AR_DEFAULT,
|
AR_DEFAULT,
|
||||||
|
AR_INTERNAL,
|
||||||
|
AR_EXTERNAL,
|
||||||
AR_INTERNAL1V0,
|
AR_INTERNAL1V0,
|
||||||
AR_INTERNAL1V1,
|
|
||||||
AR_INTERNAL1V2,
|
|
||||||
AR_INTERNAL1V25,
|
|
||||||
AR_INTERNAL2V0,
|
|
||||||
AR_INTERNAL2V2,
|
|
||||||
AR_INTERNAL2V23,
|
|
||||||
AR_INTERNAL2V4,
|
|
||||||
AR_INTERNAL2V5,
|
|
||||||
AR_INTERNAL1V65,
|
AR_INTERNAL1V65,
|
||||||
AR_EXTERNAL
|
AR_INTERNAL2V23
|
||||||
} eAnalogReference ;
|
} eAnalogReference ;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,48 +30,44 @@ void pinMode( uint32_t ulPin, uint32_t ulMode )
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
EPortType port = g_APinDescription[ulPin].ulPort;
|
|
||||||
uint32_t pin = g_APinDescription[ulPin].ulPin;
|
|
||||||
uint32_t pinMask = (1ul << pin);
|
|
||||||
|
|
||||||
// Set pin mode according to chapter '22.6.3 I/O Pin Configuration'
|
// Set pin mode according to chapter '22.6.3 I/O Pin Configuration'
|
||||||
switch ( ulMode )
|
switch ( ulMode )
|
||||||
{
|
{
|
||||||
case INPUT:
|
case INPUT:
|
||||||
// Set pin to input mode
|
// Set pin to input mode
|
||||||
PORT->Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN);
|
PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN) ;
|
||||||
PORT->Group[port].DIRCLR.reg = pinMask;
|
PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
|
||||||
break;
|
break ;
|
||||||
|
|
||||||
case INPUT_PULLUP:
|
case INPUT_PULLUP:
|
||||||
// Set pin to input mode with pull-up resistor enabled
|
// Set pin to input mode with pull-up resistor enabled
|
||||||
PORT->Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN);
|
PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ;
|
||||||
PORT->Group[port].DIRCLR.reg = pinMask;
|
PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
|
||||||
|
|
||||||
// Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.7 Data Output Value Set')
|
// Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.7 Data Output Value Set')
|
||||||
PORT->Group[port].OUTSET.reg = pinMask;
|
PORT->Group[g_APinDescription[ulPin].ulPort].OUTSET.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
|
||||||
break;
|
break ;
|
||||||
|
|
||||||
case INPUT_PULLDOWN:
|
case INPUT_PULLDOWN:
|
||||||
// Set pin to input mode with pull-down resistor enabled
|
// Set pin to input mode with pull-down resistor enabled
|
||||||
PORT->Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN);
|
PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN|PORT_PINCFG_PULLEN) ;
|
||||||
PORT->Group[port].DIRCLR.reg = pinMask;
|
PORT->Group[g_APinDescription[ulPin].ulPort].DIRCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
|
||||||
|
|
||||||
// Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.6 Data Output Value Clear')
|
// Enable pull level (cf '22.6.3.2 Input Configuration' and '22.8.6 Data Output Value Clear')
|
||||||
PORT->Group[port].OUTCLR.reg = pinMask;
|
PORT->Group[g_APinDescription[ulPin].ulPort].OUTCLR.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
|
||||||
break;
|
break ;
|
||||||
|
|
||||||
case OUTPUT:
|
case OUTPUT:
|
||||||
// enable input, to support reading back values, with pullups disabled
|
// enable input, to support reading back values, with pullups disabled
|
||||||
PORT->Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_DRVSTR);
|
PORT->Group[g_APinDescription[ulPin].ulPort].PINCFG[g_APinDescription[ulPin].ulPin].reg=(uint8_t)(PORT_PINCFG_INEN) ;
|
||||||
|
|
||||||
// Set pin to output mode
|
// Set pin to output mode
|
||||||
PORT->Group[port].DIRSET.reg = pinMask;
|
PORT->Group[g_APinDescription[ulPin].ulPort].DIRSET.reg = (uint32_t)(1<<g_APinDescription[ulPin].ulPin) ;
|
||||||
break;
|
break ;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// do nothing
|
// do nothing
|
||||||
break;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
#include "WVariant.h"
|
#include "WVariant.h"
|
||||||
|
|
||||||
typedef int PinStatus;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Configures the specified pin to behave either as an input or an output. See the description of digital pins for details.
|
* \brief Configures the specified pin to behave either as an input or an output. See the description of digital pins for details.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -46,14 +46,6 @@ StartType=3
|
||||||
ErrorControl=1
|
ErrorControl=1
|
||||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||||
|
|
||||||
[NullInstall.nt]
|
|
||||||
; nothing to do for a null driver
|
|
||||||
|
|
||||||
[NullInstall.nt.Services]
|
|
||||||
; null driver has no service and no service name
|
|
||||||
AddService=, 0x00000002
|
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
; Vista-64bit Sections
|
; Vista-64bit Sections
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
|
|
@ -81,13 +73,6 @@ StartType=3
|
||||||
ErrorControl=1
|
ErrorControl=1
|
||||||
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
ServiceBinary=%12%\%DRIVERFILENAME%.sys
|
||||||
|
|
||||||
[NullInstall.NTamd64]
|
|
||||||
; nothing to do for a null driver
|
|
||||||
|
|
||||||
[NullInstall.NTamd64.Services]
|
|
||||||
; null driver has no service and no service name
|
|
||||||
AddService=, 0x00000002
|
|
||||||
|
|
||||||
|
|
||||||
;------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------
|
||||||
; Vendor and Product ID Definitions
|
; Vendor and Product ID Definitions
|
||||||
|
|
@ -102,14 +87,14 @@ AddService=, 0x00000002
|
||||||
[SourceDisksNames]
|
[SourceDisksNames]
|
||||||
[DeviceList]
|
[DeviceList]
|
||||||
"%DESCRIPTION% UF2 Bootloader (0018:00) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00
|
"%DESCRIPTION% UF2 Bootloader (0018:00) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00
|
||||||
"%DESCRIPTION% UF2 WebUSB dummy (0018:04) BSP"=NullInstall, USB\VID_239A&PID_0018&MI_04
|
"%DESCRIPTION% UF2 WebUSB dummy (0018:04) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00
|
||||||
"%DESCRIPTION% (0019:00) BSP"=DriverInstall, USB\VID_239A&PID_0019&MI_00
|
"%DESCRIPTION% (0019:00) BSP"=DriverInstall, USB\VID_239A&PID_0019&MI_00
|
||||||
"%DESCRIPTION% Arduino (8018:00) BSP"=DriverInstall, USB\VID_239A&PID_8018&MI_00
|
"%DESCRIPTION% Arduino (8018:00) BSP"=DriverInstall, USB\VID_239A&PID_8018&MI_00
|
||||||
"%DESCRIPTION% CircuitPython (8019:00) BSP"=DriverInstall, USB\VID_239A&PID_8019&MI_00
|
"%DESCRIPTION% CircuitPython (8019:00) BSP"=DriverInstall, USB\VID_239A&PID_8019&MI_00
|
||||||
|
|
||||||
[DeviceList.NTamd64]
|
[DeviceList.NTamd64]
|
||||||
"%DESCRIPTION% UF2 Bootloader (0018:00) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00
|
"%DESCRIPTION% UF2 Bootloader (0018:00) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00
|
||||||
"%DESCRIPTION% UF2 WebUSB dummy (0018:04) BSP"=NullInstall, USB\VID_239A&PID_0018&MI_04
|
"%DESCRIPTION% UF2 WebUSB dummy (0018:04) BSP"=DriverInstall, USB\VID_239A&PID_0018&MI_00
|
||||||
"%DESCRIPTION% (0019:00) BSP"=DriverInstall, USB\VID_239A&PID_0019&MI_00
|
"%DESCRIPTION% (0019:00) BSP"=DriverInstall, USB\VID_239A&PID_0019&MI_00
|
||||||
"%DESCRIPTION% Arduino (8018:00) BSP"=DriverInstall, USB\VID_239A&PID_8018&MI_00
|
"%DESCRIPTION% Arduino (8018:00) BSP"=DriverInstall, USB\VID_239A&PID_8018&MI_00
|
||||||
"%DESCRIPTION% CircuitPython (8019:00) BSP"=DriverInstall, USB\VID_239A&PID_8019&MI_00
|
"%DESCRIPTION% CircuitPython (8019:00) BSP"=DriverInstall, USB\VID_239A&PID_8019&MI_00
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,2 @@
|
||||||
SerialGSM KEYWORD1
|
SerialGSM KEYWORD1
|
||||||
SerialSARA KEYWORD1
|
|
||||||
INPUT_PULLDOWN LITERAL1 Constants RESERVED_WORD_2
|
INPUT_PULLDOWN LITERAL1 Constants RESERVED_WORD_2
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit c953968c468218d8968138b5ed8482fa565373df
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit acc5dadb458b2c329757a61dc4f18dda945a0c36
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
// fake empty header file to make Arduino IDE happy
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
#include <arm_math.h>
|
|
||||||
|
|
||||||
arm_rfft_fast_instance_f32 plan;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
arm_rfft_fast_init_f32(&plan, 256);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
float in[256] = { 0 }, out[256] = { 0 };
|
|
||||||
arm_rfft_fast_f32(&plan, in, out, 0);
|
|
||||||
}
|
|
||||||
|
|
@ -37,12 +37,6 @@ static I2SDevice_SAMD21G18x i2sd(*I2S);
|
||||||
|
|
||||||
#include "I2S.h"
|
#include "I2S.h"
|
||||||
|
|
||||||
#ifdef USE_TINYUSB
|
|
||||||
// For Serial when selecting TinyUSB
|
|
||||||
#include <Adafruit_TinyUSB.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
int I2SClass::_beginCount = 0;
|
int I2SClass::_beginCount = 0;
|
||||||
|
|
||||||
I2SClass::I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, uint8_t sckPin, uint8_t fsPin) :
|
I2SClass::I2SClass(uint8_t deviceIndex, uint8_t clockGenerator, uint8_t sdPin, uint8_t sckPin, uint8_t fsPin) :
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,6 @@
|
||||||
|
|
||||||
#include "SAMD_AnalogCorrection.h"
|
#include "SAMD_AnalogCorrection.h"
|
||||||
|
|
||||||
#ifdef USE_TINYUSB
|
|
||||||
// For Serial when selecting TinyUSB
|
|
||||||
#include <Adafruit_TinyUSB.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void analogReadCorrection (int offset, uint16_t gain)
|
void analogReadCorrection (int offset, uint16_t gain)
|
||||||
{
|
{
|
||||||
Adc *adc;
|
Adc *adc;
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,4 @@ buildSDUBootSketch "arduino:samd:mkrfox1200" "$OUTPUT_PATH/mkrfox1200.h"
|
||||||
buildSDUBootSketch "arduino:samd:mkrgsm1400" "$OUTPUT_PATH/mkrgsm1400.h"
|
buildSDUBootSketch "arduino:samd:mkrgsm1400" "$OUTPUT_PATH/mkrgsm1400.h"
|
||||||
buildSDUBootSketch "arduino:samd:mkrwan1300" "$OUTPUT_PATH/mkrwan1300.h"
|
buildSDUBootSketch "arduino:samd:mkrwan1300" "$OUTPUT_PATH/mkrwan1300.h"
|
||||||
buildSDUBootSketch "arduino:samd:mkrwifi1010" "$OUTPUT_PATH/mkrwifi1010.h"
|
buildSDUBootSketch "arduino:samd:mkrwifi1010" "$OUTPUT_PATH/mkrwifi1010.h"
|
||||||
buildSDUBootSketch "arduino:samd:mkrnb1500" "$OUTPUT_PATH/mkrnb1500.h"
|
|
||||||
buildSDUBootSketch "arduino:samd:mzero_bl" "$OUTPUT_PATH/mzero.h"
|
buildSDUBootSketch "arduino:samd:mzero_bl" "$OUTPUT_PATH/mzero.h"
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,6 @@ unsigned char sduBoot[0x4000] = {
|
||||||
#include "boot/mkrwan1300.h"
|
#include "boot/mkrwan1300.h"
|
||||||
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
|
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
|
||||||
#include "boot/mkrwifi1010.h"
|
#include "boot/mkrwifi1010.h"
|
||||||
#elif defined(ARDUINO_SAMD_MKRNB1500)
|
|
||||||
#include "boot/mkrnb1500.h"
|
|
||||||
#elif defined(ARDUINO_SAM_ZERO)
|
#elif defined(ARDUINO_SAM_ZERO)
|
||||||
#include "boot/mzero.h"
|
#include "boot/mzero.h"
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -22,11 +22,6 @@
|
||||||
#include <wiring_private.h>
|
#include <wiring_private.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef USE_TINYUSB
|
|
||||||
// For Serial when selecting TinyUSB
|
|
||||||
#include <Adafruit_TinyUSB.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SPI_IMODE_NONE 0
|
#define SPI_IMODE_NONE 0
|
||||||
#define SPI_IMODE_EXTINT 1
|
#define SPI_IMODE_EXTINT 1
|
||||||
#define SPI_IMODE_GLOBAL 2
|
#define SPI_IMODE_GLOBAL 2
|
||||||
|
|
@ -51,16 +46,7 @@ SPIClass::SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint
|
||||||
|
|
||||||
void SPIClass::begin()
|
void SPIClass::begin()
|
||||||
{
|
{
|
||||||
if(!initialized) {
|
init();
|
||||||
interruptMode = SPI_IMODE_NONE;
|
|
||||||
interruptSave = 0;
|
|
||||||
interruptMask = 0;
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!use_dma) {
|
|
||||||
dmaAllocate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// PIO init
|
// PIO init
|
||||||
pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType);
|
pinPeripheral(_uc_pinMiso, g_APinDescription[_uc_pinMiso].ulPinType);
|
||||||
|
|
@ -70,6 +56,16 @@ void SPIClass::begin()
|
||||||
config(DEFAULT_SPI_SETTINGS);
|
config(DEFAULT_SPI_SETTINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SPIClass::init()
|
||||||
|
{
|
||||||
|
if (initialized)
|
||||||
|
return;
|
||||||
|
interruptMode = SPI_IMODE_NONE;
|
||||||
|
interruptSave = 0;
|
||||||
|
interruptMask = 0;
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
void SPIClass::config(SPISettings settings)
|
void SPIClass::config(SPISettings settings)
|
||||||
{
|
{
|
||||||
_p_sercom->disableSPI();
|
_p_sercom->disableSPI();
|
||||||
|
|
@ -84,7 +80,6 @@ void SPIClass::end()
|
||||||
{
|
{
|
||||||
_p_sercom->resetSPI();
|
_p_sercom->resetSPI();
|
||||||
initialized = false;
|
initialized = false;
|
||||||
// Add DMA deallocation here
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef interruptsStatus
|
#ifndef interruptsStatus
|
||||||
|
|
@ -203,7 +198,7 @@ void SPIClass::setDataMode(uint8_t mode)
|
||||||
|
|
||||||
void SPIClass::setClockDivider(uint8_t div)
|
void SPIClass::setClockDivider(uint8_t div)
|
||||||
{
|
{
|
||||||
if(div < SPI_MIN_CLOCK_DIVIDER) {
|
if (div < SPI_MIN_CLOCK_DIVIDER) {
|
||||||
_p_sercom->setBaudrateSPI(SPI_MIN_CLOCK_DIVIDER);
|
_p_sercom->setBaudrateSPI(SPI_MIN_CLOCK_DIVIDER);
|
||||||
} else {
|
} else {
|
||||||
_p_sercom->setBaudrateSPI(div);
|
_p_sercom->setBaudrateSPI(div);
|
||||||
|
|
@ -240,239 +235,6 @@ void SPIClass::transfer(void *buf, size_t count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DMA-based SPI transfer() function ---------------------------------------
|
|
||||||
|
|
||||||
// IMPORTANT: references to 65535 throughout the DMA code are INTENTIONAL.
|
|
||||||
// DO NOT try to 'fix' by changing to 65536, or large transfers will fail!
|
|
||||||
// The BTCNT value of a DMA descriptor is an unsigned 16-bit value with a
|
|
||||||
// max of 65535. Larger transfers are handled by linked descriptors.
|
|
||||||
|
|
||||||
// Pointer to SPIClass object, one per DMA channel. This allows the
|
|
||||||
// DMA callback (which has to exist outside the class context) to have
|
|
||||||
// a reference back to the originating SPIClass object.
|
|
||||||
static SPIClass *spiPtr[DMAC_CH_NUM] = { 0 }; // Legit inits list to NULL
|
|
||||||
|
|
||||||
void SPIClass::dmaCallback(Adafruit_ZeroDMA *dma) {
|
|
||||||
// dmaCallback() receives an Adafruit_ZeroDMA object. From this we can get
|
|
||||||
// a channel number (0 to DMAC_CH_NUM-1, always unique per ZeroDMA object),
|
|
||||||
// then locate the originating SPIClass object using array lookup, setting
|
|
||||||
// the dma_busy element 'false' to indicate end of transfer. Doesn't matter
|
|
||||||
// if it's a read or write transfer...both channels get pointers to it.
|
|
||||||
spiPtr[dma->getChannel()]->dma_busy = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For read-only and read+write transfers, a callback is assigned only
|
|
||||||
// to the read channel to indicate end-of-transfer, and the write channel's
|
|
||||||
// callback is assigned to this nonsense function (for reasons I'm not
|
|
||||||
// entirely sure of, setting the callback to NULL doesn't work).
|
|
||||||
static void dmaDoNothingCallback(Adafruit_ZeroDMA *dma) { (void)dma; }
|
|
||||||
|
|
||||||
// This could've gone in begin(), but for the sake of organization...
|
|
||||||
void SPIClass::dmaAllocate(void) {
|
|
||||||
// In order to support fully non-blocking SPI transfers, DMA descriptor
|
|
||||||
// lists must be created for the input and/or output data. Rather than
|
|
||||||
// do this dynamically with every transfer, the lists are allocated once
|
|
||||||
// on SPI init. Maximum list size is finite and knowable -- transfers to
|
|
||||||
// or from RAM or from flash memory will never exceed the corresponding
|
|
||||||
// memory size (if they do, you have bigger problems). Descriptors
|
|
||||||
// aren't large and there's usually only a handful to a dozen, so this
|
|
||||||
// isn't an excessive burden in exchange for big non-blocking transfers.
|
|
||||||
uint32_t maxWriteBytes = FLASH_SIZE; // Writes can't exceed all of flash
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
uint32_t maxReadBytes = HSRAM_SIZE; // Reads can't exceed all of RAM
|
|
||||||
#else
|
|
||||||
uint32_t maxReadBytes = HMCRAMC0_SIZE;
|
|
||||||
#endif
|
|
||||||
if(maxReadBytes > maxWriteBytes) { // I don't think any SAMD devices
|
|
||||||
maxWriteBytes = maxReadBytes; // have RAM > flash, but just in case
|
|
||||||
}
|
|
||||||
|
|
||||||
// VITAL to alloc read channel first, assigns it a higher DMA priority!
|
|
||||||
if(readChannel.allocate() == DMA_STATUS_OK) {
|
|
||||||
if(writeChannel.allocate() == DMA_STATUS_OK) {
|
|
||||||
|
|
||||||
// Both DMA channels (read and write) allocated successfully,
|
|
||||||
// set up transfer triggers and other basics...
|
|
||||||
|
|
||||||
// readChannel callback only needs to be set up once.
|
|
||||||
// Unlike the write callback which may get switched on or off,
|
|
||||||
// read callback stays put. In certain cases the read DMA job
|
|
||||||
// just isn't started and the callback is a non-issue then.
|
|
||||||
readChannel.setTrigger(getDMAC_ID_RX());
|
|
||||||
readChannel.setAction(DMA_TRIGGER_ACTON_BEAT);
|
|
||||||
readChannel.setCallback(dmaCallback);
|
|
||||||
spiPtr[readChannel.getChannel()] = this;
|
|
||||||
|
|
||||||
writeChannel.setTrigger(getDMAC_ID_TX());
|
|
||||||
writeChannel.setAction(DMA_TRIGGER_ACTON_BEAT);
|
|
||||||
spiPtr[writeChannel.getChannel()] = this;
|
|
||||||
|
|
||||||
// One descriptor per channel has already been allocated
|
|
||||||
// in Adafruit_ZeroDMA, this just gets pointers to them...
|
|
||||||
firstReadDescriptor = readChannel.addDescriptor(
|
|
||||||
(void *)getDataRegister(), // Source address (SPI data reg)
|
|
||||||
NULL, // Dest address (set later)
|
|
||||||
0, // Count (set later)
|
|
||||||
DMA_BEAT_SIZE_BYTE, // Bytes/hwords/words
|
|
||||||
false, // Don't increment source address
|
|
||||||
true); // Increment dest address
|
|
||||||
firstWriteDescriptor = writeChannel.addDescriptor(
|
|
||||||
NULL, // Source address (set later)
|
|
||||||
(void *)getDataRegister(), // Dest (SPI data register)
|
|
||||||
0, // Count (set later)
|
|
||||||
DMA_BEAT_SIZE_BYTE, // Bytes/hwords/words
|
|
||||||
true, // Increment source address
|
|
||||||
false); // Don't increment dest address
|
|
||||||
// This is the number of EXTRA descriptors beyond the first.
|
|
||||||
int numReadDescriptors = ((maxReadBytes + 65534) / 65535) - 1;
|
|
||||||
int numWriteDescriptors = ((maxWriteBytes + 65534) / 65535) - 1;
|
|
||||||
int totalDescriptors = numReadDescriptors + numWriteDescriptors;
|
|
||||||
|
|
||||||
if(totalDescriptors <= 0) { // Don't need extra descriptors,
|
|
||||||
use_dma = true; // channels are allocated, we're good.
|
|
||||||
} else { // Else allocate extra descriptor lists...
|
|
||||||
// Although DMA descriptors are technically a linked list, we just
|
|
||||||
// allocate a chunk all at once, and finesse the pointers later.
|
|
||||||
if((extraReadDescriptors = (DmacDescriptor *)malloc(
|
|
||||||
totalDescriptors * sizeof(DmacDescriptor)))) {
|
|
||||||
use_dma = true; // Everything allocated successfully
|
|
||||||
extraWriteDescriptors = &extraReadDescriptors[numReadDescriptors];
|
|
||||||
|
|
||||||
// Initialize descriptors (copy from first ones)
|
|
||||||
// cast to void* to suppress warning: with no trivial copy-assignment [-Wclass-memaccess]
|
|
||||||
for(int i=0; i<numReadDescriptors; i++) {
|
|
||||||
memcpy((void*) &extraReadDescriptors[i], firstReadDescriptor,
|
|
||||||
sizeof(DmacDescriptor));
|
|
||||||
}
|
|
||||||
for(int i=0; i<numWriteDescriptors; i++) {
|
|
||||||
memcpy((void*) &extraWriteDescriptors[i], firstWriteDescriptor,
|
|
||||||
sizeof(DmacDescriptor));
|
|
||||||
}
|
|
||||||
} // end malloc
|
|
||||||
} // end extra descriptor check
|
|
||||||
|
|
||||||
if(use_dma) { // If everything allocated successfully,
|
|
||||||
return; // then we're done here.
|
|
||||||
} // Otherwise clean up interim allocations...
|
|
||||||
writeChannel.free();
|
|
||||||
} // end writeChannel alloc
|
|
||||||
readChannel.free();
|
|
||||||
} // end readChannel alloc
|
|
||||||
|
|
||||||
// NOT FATAL if channel or descriptor allocation fails.
|
|
||||||
// transfer() function will fall back on a manual byte-by-byte loop.
|
|
||||||
}
|
|
||||||
|
|
||||||
void SPIClass::transfer(const void *txbuf, void *rxbuf, size_t count,
|
|
||||||
bool block) {
|
|
||||||
|
|
||||||
if((!txbuf && !rxbuf) || !count) { // Validate inputs
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// OK to assume now that txbuf and/or rxbuf are non-NULL, an if/else is
|
|
||||||
// often sufficient, don't need else-ifs for everything buffer related.
|
|
||||||
|
|
||||||
uint8_t *txbuf8 = (uint8_t *)txbuf; // Must cast to byte size
|
|
||||||
uint8_t *rxbuf8 = (uint8_t *)rxbuf; // for pointer math
|
|
||||||
|
|
||||||
if(use_dma) { // DMA-BASED TRANSFER YAY ----------------------------------
|
|
||||||
|
|
||||||
static const uint8_t dum = 0xFF; // Dummy byte for read-only xfers
|
|
||||||
|
|
||||||
// Set up DMA descriptor lists -----------------------------------------
|
|
||||||
|
|
||||||
DmacDescriptor *rDesc = firstReadDescriptor;
|
|
||||||
DmacDescriptor *wDesc = firstWriteDescriptor;
|
|
||||||
int descIdx = 0; // Index into extra descriptor lists
|
|
||||||
|
|
||||||
while(count) { // Counts down to end of transfer
|
|
||||||
uint32_t bytesThisDescriptor = count;
|
|
||||||
if(bytesThisDescriptor > 65535) { // Limit each descriptor
|
|
||||||
bytesThisDescriptor = 65535; // to 65535 (not 65536) bytes
|
|
||||||
}
|
|
||||||
rDesc->BTCNT.reg = wDesc->BTCNT.reg = bytesThisDescriptor;
|
|
||||||
if(rxbuf) { // Read-only or read+write
|
|
||||||
// Auto-inc addresses in DMA descriptors must point to END of data.
|
|
||||||
// Buf pointers would advance at end of loop anyway, do it now...
|
|
||||||
rxbuf8 += bytesThisDescriptor;
|
|
||||||
rDesc->DSTADDR.reg = (uint32_t)rxbuf8;
|
|
||||||
}
|
|
||||||
if(txbuf) { // Write-only or read+write
|
|
||||||
txbuf8 += bytesThisDescriptor; // Same as above
|
|
||||||
wDesc->SRCADDR.reg = (uint32_t)txbuf8;
|
|
||||||
wDesc->BTCTRL.bit.SRCINC = 1; // Increment source pointer
|
|
||||||
} else { // Read-only requires dummy write
|
|
||||||
wDesc->SRCADDR.reg = (uint32_t)&dum;
|
|
||||||
wDesc->BTCTRL.bit.SRCINC = 0; // Don't increment source pointer
|
|
||||||
}
|
|
||||||
count -= bytesThisDescriptor;
|
|
||||||
if(count) { // Still more data?
|
|
||||||
// Link to next descriptors. Extra descriptors are IN ADDITION
|
|
||||||
// to first, so it's safe and correct that descIdx starts at 0.
|
|
||||||
rDesc->DESCADDR.reg = (uint32_t)&extraReadDescriptors[descIdx];
|
|
||||||
wDesc->DESCADDR.reg = (uint32_t)&extraWriteDescriptors[descIdx];
|
|
||||||
rDesc = &extraReadDescriptors[descIdx]; // Update pointers to
|
|
||||||
wDesc = &extraWriteDescriptors[descIdx]; // next descriptors
|
|
||||||
descIdx++;
|
|
||||||
// A write-only transfer doesn't use the read descriptor list, but
|
|
||||||
// it's quicker to build it (full of nonsense) anyway than to check.
|
|
||||||
} else { // No more data, end descriptor linked lists
|
|
||||||
rDesc->DESCADDR.reg = wDesc->DESCADDR.reg = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up DMA transfer job(s) ------------------------------------------
|
|
||||||
|
|
||||||
if(rxbuf) { // Read+write or read-only
|
|
||||||
// End-of-read callback is already set up, disable write CB, start job
|
|
||||||
writeChannel.setCallback(dmaDoNothingCallback);
|
|
||||||
readChannel.startJob();
|
|
||||||
} else { // Write-only, use end-of-write callback
|
|
||||||
writeChannel.setCallback(dmaCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run DMA jobs, blocking if requested ---------------------------------
|
|
||||||
|
|
||||||
dma_busy = true;
|
|
||||||
writeChannel.startJob(); // All xfers, even read-only, need write job.
|
|
||||||
if(block) { // If blocking transfer requested,
|
|
||||||
while(dma_busy); // wait for job to finish
|
|
||||||
}
|
|
||||||
|
|
||||||
} else { // NON-DMA FALLBACK ---------------------------------------------
|
|
||||||
|
|
||||||
if(txbuf8) {
|
|
||||||
if(rxbuf8) { // Write + read simultaneously
|
|
||||||
while(count--) {
|
|
||||||
*rxbuf8++ = _p_sercom->transferDataSPI(*txbuf8++);
|
|
||||||
}
|
|
||||||
} else { // Write only
|
|
||||||
while(count--) {
|
|
||||||
(void)_p_sercom->transferDataSPI(*txbuf8++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // Read only
|
|
||||||
while(count--) {
|
|
||||||
*rxbuf8++ = _p_sercom->transferDataSPI(0xFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end non-DMA
|
|
||||||
}
|
|
||||||
|
|
||||||
// Waits for a prior in-background DMA transfer to complete.
|
|
||||||
void SPIClass::waitForTransfer(void) {
|
|
||||||
while(dma_busy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns the current DMA transfer status to allow non-blocking polling */
|
|
||||||
bool SPIClass::isBusy(void) {
|
|
||||||
return dma_busy;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// End DMA-based SPI transfer() code ---------------------------------------
|
|
||||||
|
|
||||||
void SPIClass::attachInterrupt() {
|
void SPIClass::attachInterrupt() {
|
||||||
// Should be enableInterrupt()
|
// Should be enableInterrupt()
|
||||||
}
|
}
|
||||||
|
|
@ -481,61 +243,6 @@ void SPIClass::detachInterrupt() {
|
||||||
// Should be disableInterrupt()
|
// Should be disableInterrupt()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SPI DMA lookup works on both SAMD21 and SAMD51
|
|
||||||
|
|
||||||
static const struct {
|
|
||||||
volatile uint32_t *data_reg;
|
|
||||||
int dmac_id_tx;
|
|
||||||
int dmac_id_rx;
|
|
||||||
} sercomData[] = {
|
|
||||||
{ &SERCOM0->SPI.DATA.reg, SERCOM0_DMAC_ID_TX, SERCOM0_DMAC_ID_RX },
|
|
||||||
{ &SERCOM1->SPI.DATA.reg, SERCOM1_DMAC_ID_TX, SERCOM1_DMAC_ID_RX },
|
|
||||||
{ &SERCOM2->SPI.DATA.reg, SERCOM2_DMAC_ID_TX, SERCOM2_DMAC_ID_RX },
|
|
||||||
{ &SERCOM3->SPI.DATA.reg, SERCOM3_DMAC_ID_TX, SERCOM3_DMAC_ID_RX },
|
|
||||||
#if defined(SERCOM4)
|
|
||||||
{ &SERCOM4->SPI.DATA.reg, SERCOM4_DMAC_ID_TX, SERCOM4_DMAC_ID_RX },
|
|
||||||
#endif
|
|
||||||
#if defined(SERCOM5)
|
|
||||||
{ &SERCOM5->SPI.DATA.reg, SERCOM5_DMAC_ID_TX, SERCOM5_DMAC_ID_RX },
|
|
||||||
#endif
|
|
||||||
#if defined(SERCOM6)
|
|
||||||
{ &SERCOM6->SPI.DATA.reg, SERCOM6_DMAC_ID_TX, SERCOM6_DMAC_ID_RX },
|
|
||||||
#endif
|
|
||||||
#if defined(SERCOM7)
|
|
||||||
{ &SERCOM7->SPI.DATA.reg, SERCOM7_DMAC_ID_TX, SERCOM7_DMAC_ID_RX },
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
volatile uint32_t *SPIClass::getDataRegister(void) {
|
|
||||||
int8_t idx = _p_sercom->getSercomIndex();
|
|
||||||
return (idx >= 0) ? sercomData[idx].data_reg: NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SPIClass::getDMAC_ID_TX(void) {
|
|
||||||
int8_t idx = _p_sercom->getSercomIndex();
|
|
||||||
return (idx >= 0) ? sercomData[idx].dmac_id_tx : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SPIClass::getDMAC_ID_RX(void) {
|
|
||||||
int8_t idx = _p_sercom->getSercomIndex();
|
|
||||||
return (idx >= 0) ? sercomData[idx].dmac_id_rx : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
|
|
||||||
// Set the SPI device's SERCOM clock CORE and SLOW clock sources.
|
|
||||||
// SercomClockSource values are an enumeration in SERCOM.h.
|
|
||||||
// This works on SAMD51 only. On SAMD21, a dummy function is declared
|
|
||||||
// in SPI.h which compiles to nothing, so user code doesn't need to check
|
|
||||||
// and conditionally compile lines for different architectures.
|
|
||||||
void SPIClass::setClockSource(SercomClockSource clk) {
|
|
||||||
int8_t idx = _p_sercom->getSercomIndex();
|
|
||||||
_p_sercom->setClockSource(idx, clk, true); // true = set core clock
|
|
||||||
_p_sercom->setClockSource(idx, clk, false); // false = set slow clock
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // end __SAMD51__
|
|
||||||
|
|
||||||
#if SPI_INTERFACES_COUNT > 0
|
#if SPI_INTERFACES_COUNT > 0
|
||||||
/* In case new variant doesn't define these macros,
|
/* In case new variant doesn't define these macros,
|
||||||
* we put here the ones for Arduino Zero.
|
* we put here the ones for Arduino Zero.
|
||||||
|
|
@ -568,3 +275,4 @@ void SPIClass::setClockSource(SercomClockSource clk) {
|
||||||
#if SPI_INTERFACES_COUNT > 5
|
#if SPI_INTERFACES_COUNT > 5
|
||||||
SPIClass SPI5(&PERIPH_SPI5, PIN_SPI5_MISO, PIN_SPI5_SCK, PIN_SPI5_MOSI, PAD_SPI5_TX, PAD_SPI5_RX);
|
SPIClass SPI5(&PERIPH_SPI5, PIN_SPI5_MISO, PIN_SPI5_SCK, PIN_SPI5_MOSI, PAD_SPI5_TX, PAD_SPI5_RX);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
#define _SPI_H_INCLUDED
|
#define _SPI_H_INCLUDED
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <Adafruit_ZeroDMA.h>
|
|
||||||
|
|
||||||
// SPI_HAS_TRANSACTION means SPI has
|
// SPI_HAS_TRANSACTION means SPI has
|
||||||
// - beginTransaction()
|
// - beginTransaction()
|
||||||
|
|
@ -38,27 +37,12 @@
|
||||||
#define SPI_MODE2 0x03
|
#define SPI_MODE2 0x03
|
||||||
#define SPI_MODE3 0x01
|
#define SPI_MODE3 0x01
|
||||||
|
|
||||||
#if defined(__SAMD51__)
|
#if defined(ARDUINO_ARCH_SAMD)
|
||||||
// SAMD51 has configurable MAX_SPI, else use peripheral clock default.
|
|
||||||
// Update: changing MAX_SPI via compiler flags is DEPRECATED, because
|
|
||||||
// this affects ALL SPI peripherals including some that should NOT be
|
|
||||||
// changed (e.g. anything using SD card). Use the setClockSource()
|
|
||||||
// function instead. This is left here for compatibility with interim code.
|
|
||||||
#if !defined(MAX_SPI)
|
|
||||||
#define MAX_SPI 24000000
|
|
||||||
#endif
|
|
||||||
#define SPI_MIN_CLOCK_DIVIDER 1
|
|
||||||
#else
|
|
||||||
// The datasheet specifies a typical SPI SCK period (tSCK) of 42 ns,
|
// The datasheet specifies a typical SPI SCK period (tSCK) of 42 ns,
|
||||||
// see "Table 36-48. SPI Timing Characteristics and Requirements",
|
// see "Table 36-48. SPI Timing Characteristics and Requirements",
|
||||||
// which translates into a maximum SPI clock of 23.8 MHz.
|
// which translates into a maximum SPI clock of 23.8 MHz.
|
||||||
// We'll permit use of 24 MHz SPI even though this is slightly out
|
// Conservatively, the divider is set for a 12 MHz maximum SPI clock.
|
||||||
// of spec. Given how clock dividers work, the next "sensible"
|
#define SPI_MIN_CLOCK_DIVIDER (uint8_t)(1 + ((F_CPU - 1) / 12000000))
|
||||||
// threshold would be a substantial drop down to 12 MHz.
|
|
||||||
#if !defined(MAX_SPI)
|
|
||||||
#define MAX_SPI 24000000
|
|
||||||
#endif
|
|
||||||
#define SPI_MIN_CLOCK_DIVIDER (uint8_t)(1 + ((F_CPU - 1) / MAX_SPI))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class SPISettings {
|
class SPISettings {
|
||||||
|
|
@ -80,11 +64,7 @@ class SPISettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
|
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
|
||||||
#if defined(__SAMD51__)
|
this->clockFreq = (clock >= (F_CPU / SPI_MIN_CLOCK_DIVIDER) ? F_CPU / SPI_MIN_CLOCK_DIVIDER : clock);
|
||||||
this->clockFreq = clock; // Clipping handled in SERCOM.cpp
|
|
||||||
#else
|
|
||||||
this->clockFreq = clock >= MAX_SPI ? MAX_SPI : clock;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
this->bitOrder = (bitOrder == MSBFIRST ? MSB_FIRST : LSB_FIRST);
|
this->bitOrder = (bitOrder == MSBFIRST ? MSB_FIRST : LSB_FIRST);
|
||||||
|
|
||||||
|
|
@ -114,13 +94,10 @@ class SPIClass {
|
||||||
public:
|
public:
|
||||||
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad);
|
SPIClass(SERCOM *p_sercom, uint8_t uc_pinMISO, uint8_t uc_pinSCK, uint8_t uc_pinMOSI, SercomSpiTXPad, SercomRXPad);
|
||||||
|
|
||||||
|
|
||||||
byte transfer(uint8_t data);
|
byte transfer(uint8_t data);
|
||||||
uint16_t transfer16(uint16_t data);
|
uint16_t transfer16(uint16_t data);
|
||||||
void transfer(void *buf, size_t count);
|
void transfer(void *buf, size_t count);
|
||||||
void transfer(const void* txbuf, void* rxbuf, size_t count,
|
|
||||||
bool block = true);
|
|
||||||
void waitForTransfer(void);
|
|
||||||
bool isBusy(void);
|
|
||||||
|
|
||||||
// Transaction Functions
|
// Transaction Functions
|
||||||
void usingInterrupt(int interruptNumber);
|
void usingInterrupt(int interruptNumber);
|
||||||
|
|
@ -139,21 +116,8 @@ class SPIClass {
|
||||||
void setDataMode(uint8_t uc_mode);
|
void setDataMode(uint8_t uc_mode);
|
||||||
void setClockDivider(uint8_t uc_div);
|
void setClockDivider(uint8_t uc_div);
|
||||||
|
|
||||||
// SERCOM lookup functions are available on both SAMD51 and 21.
|
|
||||||
volatile uint32_t *getDataRegister(void);
|
|
||||||
int getDMAC_ID_TX(void);
|
|
||||||
int getDMAC_ID_RX(void);
|
|
||||||
uint8_t getSercomIndex(void) { return _p_sercom->getSercomIndex(); };
|
|
||||||
#if defined(__SAMD51__)
|
|
||||||
// SERCOM clock source override is available only on SAMD51.
|
|
||||||
void setClockSource(SercomClockSource clk);
|
|
||||||
#else
|
|
||||||
// On SAMD21, this compiles to nothing, so user code doesn't need to
|
|
||||||
// check and conditionally compile lines for different architectures.
|
|
||||||
void setClockSource(SercomClockSource clk) { (void)clk; };
|
|
||||||
#endif // end __SAMD51__
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void init();
|
||||||
void config(SPISettings settings);
|
void config(SPISettings settings);
|
||||||
|
|
||||||
SERCOM *_p_sercom;
|
SERCOM *_p_sercom;
|
||||||
|
|
@ -168,18 +132,6 @@ class SPIClass {
|
||||||
uint8_t interruptMode;
|
uint8_t interruptMode;
|
||||||
char interruptSave;
|
char interruptSave;
|
||||||
uint32_t interruptMask;
|
uint32_t interruptMask;
|
||||||
|
|
||||||
// transfer(txbuf, rxbuf, count, block) uses DMA when possible
|
|
||||||
Adafruit_ZeroDMA readChannel;
|
|
||||||
Adafruit_ZeroDMA writeChannel;
|
|
||||||
DmacDescriptor *firstReadDescriptor = NULL; // List entry point
|
|
||||||
DmacDescriptor *firstWriteDescriptor = NULL;
|
|
||||||
DmacDescriptor *extraReadDescriptors = NULL; // Add'l descriptors
|
|
||||||
DmacDescriptor *extraWriteDescriptors = NULL;
|
|
||||||
bool use_dma = false; // true on successful alloc
|
|
||||||
volatile bool dma_busy = false;
|
|
||||||
void dmaAllocate(void);
|
|
||||||
static void dmaCallback(Adafruit_ZeroDMA *dma);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if SPI_INTERFACES_COUNT > 0
|
#if SPI_INTERFACES_COUNT > 0
|
||||||
|
|
@ -203,12 +155,14 @@ class SPIClass {
|
||||||
|
|
||||||
// For compatibility with sketches designed for AVR @ 16 MHz
|
// For compatibility with sketches designed for AVR @ 16 MHz
|
||||||
// New programs should use SPI.beginTransaction to set the SPI clock
|
// New programs should use SPI.beginTransaction to set the SPI clock
|
||||||
#define SPI_CLOCK_DIV2 (MAX_SPI * 2 / 8000000)
|
#if F_CPU == 48000000
|
||||||
#define SPI_CLOCK_DIV4 (MAX_SPI * 2 / 4000000)
|
#define SPI_CLOCK_DIV2 6
|
||||||
#define SPI_CLOCK_DIV8 (MAX_SPI * 2 / 2000000)
|
#define SPI_CLOCK_DIV4 12
|
||||||
#define SPI_CLOCK_DIV16 (MAX_SPI * 2 / 1000000)
|
#define SPI_CLOCK_DIV8 24
|
||||||
#define SPI_CLOCK_DIV32 (MAX_SPI * 2 / 500000)
|
#define SPI_CLOCK_DIV16 48
|
||||||
#define SPI_CLOCK_DIV64 (MAX_SPI * 2 / 250000)
|
#define SPI_CLOCK_DIV32 96
|
||||||
#define SPI_CLOCK_DIV128 (MAX_SPI * 2 / 125000)
|
#define SPI_CLOCK_DIV64 192
|
||||||
|
#define SPI_CLOCK_DIV128 255
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue