Compare commits

..

9 commits

Author SHA1 Message Date
deanm1278
251f76ad66
Merge branch 'master' into dm-gc 2018-11-20 16:44:26 -05:00
dean
c4bb46002a DM: update grandcentral pin numbering 2018-11-20 16:31:05 -05:00
dean
6ec89e5911 DM: remove unnecessary debug scripts for m4 boards 2018-11-20 10:51:23 -05:00
dean
f6a4451e66 DM: remove openocd for samd51, fix include guards 2018-11-20 10:49:04 -05:00
dean
ecf801eb9d DM: fix grandcentral boards.txt naming 2018-11-19 18:19:14 -05:00
dean
5a27c5dc44 DM: fixes for mega m4 pcc 2018-11-19 18:06:40 -05:00
dean
fee7b4cf35 DM: metro mega updates 2018-11-19 14:08:22 -05:00
dean
45013af3a3 DM: updates for m4 mega 2018-11-19 13:38:51 -05:00
dean
f4cedd7e48 DM: grandcentral variant 2018-11-19 12:31:34 -05:00
349 changed files with 1228 additions and 30203 deletions

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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 }}

1
.gitignore vendored
View file

@ -3,4 +3,3 @@
bootloaders/*/build/ bootloaders/*/build/
*~ *~
/libraries/**/build/

6
.gitmodules vendored
View file

@ -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

View file

@ -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)

View file

@ -1,7 +1,5 @@
# Arduino Core for SAMD21 and SAMD51 CPU # Arduino Core for SAMD21 and SAMD51 CPU
[![Build Status](https://github.com/adafruit/ArduinoCore-samd/workflows/Build/badge.svg)](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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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)
#error "Little Endian is already defined, but to different value than expected?!"
#else
#define LITTLE_ENDIAN 1 #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 */

View file

@ -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.

View file

@ -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_

View file

@ -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!

View file

@ -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
// Needed for declaring Serial
#include "Adafruit_USBD_CDC.h"
#else
#include "USB/USBDesc.h" #include "USB/USBDesc.h"
#include "USB/USBCore.h" #include "USB/USBCore.h"
#include "USB/USBAPI.h" #include "USB/USBAPI.h"
#include "USB/USB_host.h" #include "USB/USB_host.h"
#endif
#endif // Arduino_h #endif // Arduino_h

View file

@ -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;

View file

@ -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;
} }

View file

@ -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,14 +82,10 @@ 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 */ }
}; };

View file

@ -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

View file

@ -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

View file

@ -30,24 +30,6 @@
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__
} }
/* ========================= /* =========================
@ -93,15 +75,13 @@ 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)
@ -248,6 +228,7 @@ void SERCOM::initSPI(SercomSpiTXPad mosi, SercomRXPad miso, SercomSpiCharSize ch
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)
@ -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
} }
@ -386,14 +371,9 @@ bool SERCOM::isDataRegisterEmptySPI()
// 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;
} }
@ -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 )
// Wait transmission complete {
// If the slave NACKS the address, the MB bit will be set. // 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. // In that case, send a stop condition and return false.
if (sercom->I2CM.INTFLAG.bit.MB || sercom->I2CM.INTFLAG.bit.ERROR) { if (sercom->I2CM.INTFLAG.bit.MB) {
sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
return false; return false;
} }
// Wait transmission complete
} }
// 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;
for(uint8_t i=0; i<4; i++) { if(sercom == SERCOM0)
NVIC_ClearPendingIRQ(sercomData[idx].irq[i]); {
NVIC_SetPriority(sercomData[idx].irq[i], SERCOM_NVIC_PRIORITY); clk_core = SERCOM0_GCLK_ID_CORE;
NVIC_EnableIRQ(sercomData[idx].irq[i]); clk_slow = SERCOM0_GCLK_ID_SLOW;
NVIC_ClearPendingIRQ(SERCOM0_0_IRQn);
NVIC_ClearPendingIRQ(SERCOM0_1_IRQn);
NVIC_ClearPendingIRQ(SERCOM0_2_IRQn);
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;
// SPI DMA speed is dictated by the "slow clock" (I think...maybe) so NVIC_ClearPendingIRQ(SERCOM1_0_IRQn);
// BOTH are set to the same clock source (clk_slow isn't sourced from NVIC_ClearPendingIRQ(SERCOM1_1_IRQn);
// XOSC32K as in prior versions of SAMD core). NVIC_ClearPendingIRQ(SERCOM1_2_IRQn);
// This might have power implications for sleep code. NVIC_ClearPendingIRQ(SERCOM1_3_IRQn);
setClockSource(idx, clockSource, true); // true = core clock NVIC_SetPriority (SERCOM1_0_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority */
setClockSource(idx, clockSource, false); // false = slow clock 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);
#else // end if SAMD51 (prob SAMD21) 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;
uint8_t clockId = sercomData[idx].clock; NVIC_ClearPendingIRQ(SERCOM2_0_IRQn);
IRQn_Type IdNvic = sercomData[idx].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
if ( IdNvic == PendSV_IRQn )
{
// We got a problem here
return ;
}
#endif
#if defined(__SAMD51__)
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
// Setting NVIC // 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
} }

View file

@ -21,17 +21,6 @@
#include "sam.h" #include "sam.h"
// SAMD51 has configurable MAX_SPI, else use peripheral clock default.
// Update: changing MAX_SPI via compiler flags is DEPRECATED, because
// this affects ALL SPI peripherals including some that should NOT be
// changed (e.g. anything using SD card). Instead, use setClockSource().
// This is left here for compatibility w/interim MAX_SPI-dependent code:
#if defined(MAX_SPI)
#define SERCOM_SPI_FREQ_REF (MAX_SPI * 2)
#else
#define SERCOM_SPI_FREQ_REF 48000000ul
#endif
// Other SERCOM peripherals always use the 48 MHz clock
#define SERCOM_FREQ_REF 48000000ul #define SERCOM_FREQ_REF 48000000ul
#define SERCOM_NVIC_PRIORITY ((1<<__NVIC_PRIO_BITS) - 1) #define SERCOM_NVIC_PRIORITY ((1<<__NVIC_PRIO_BITS) - 1)
@ -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,29 +210,9 @@ 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__)
SercomClockSource clockSource;
uint32_t freqRef; // Frequency corresponding to clockSource
#endif
uint8_t calculateBaudrateSynchronous(uint32_t baudrate) ; 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 ) ;

View file

@ -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
} }

View file

@ -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,7 +80,7 @@ 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);
@ -95,6 +91,9 @@ void tone (uint32_t outputPin, uint32_t frequency, uint32_t duration)
#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);
@ -179,21 +178,11 @@ 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
* the timers used for the tone-functionality. If 'noTone' is called
* without ever calling 'tone' before then 'WAIT_TC16_REGS_SYNC(TCx)'
* will wait infinitely. The variable 'firstTimeRunning' is set the
* 1st time 'tone' is set so it can be used to detect wether or not
* 'tone' has been called before.
*/
if(firstTimeRunning)
{ {
resetTC(TONE_TC); resetTC(TONE_TC);
digitalWrite(outputPin, LOW); digitalWrite(outputPin, LOW);
toneIsActive = false; toneIsActive = false;
} }
}
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View file

@ -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

View file

@ -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"
@ -116,5 +114,3 @@ PluggableUSB_::PluggableUSB_() : lastIf(CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT)
#endif #endif
#endif #endif
#endif // USE_TINYUSB

View file

@ -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

View file

@ -237,7 +237,7 @@ public:
release(); release();
} }
virtual ~DoubleBufferedEPOutHandler() { ~DoubleBufferedEPOutHandler() {
free((void*)data0); free((void*)data0);
free((void*)data1); free((void*)data1);
} }

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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
count = len - index;
}
char *writeTo = buffer + 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;
} }

View file

@ -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

View file

@ -25,14 +25,8 @@
#ifndef _IO_H_ #ifndef _IO_H_
#define _IO_H_ #define _IO_H_
#ifdef __SAMD51__
#define RAMSTART (HSRAM_ADDR)
#define RAMSIZE (HSRAM_SIZE)
#else
#define RAMSTART (HMCRAMC0_ADDR) #define RAMSTART (HMCRAMC0_ADDR)
#define RAMSIZE (HMCRAMC0_SIZE) #define RAMSIZE (HMCRAMC0_SIZE)
#endif
#define RAMEND (RAMSTART + RAMSIZE - 1) #define RAMEND (RAMSTART + RAMSIZE - 1)
#endif #endif

View file

@ -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 */

View file

@ -61,33 +61,6 @@ 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 )
@ -95,17 +68,12 @@ void delay( unsigned long ms )
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

View file

@ -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
} }

View file

@ -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")));
/** /**

View file

@ -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();
} }

View file

@ -164,14 +164,13 @@ 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)
{ {
@ -193,14 +192,13 @@ 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)
{ {

View file

@ -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
} }

View file

@ -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;
@ -254,54 +253,6 @@ void SystemInit( void )
__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
} }

View file

@ -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

View file

@ -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;
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; 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;
/* Don't think this works on SAMD51
case AR_INTERNAL1V0:
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val; // 1.0V voltage reference
break;
*/
case AR_INTERNAL1V65: case AR_INTERNAL1V65:
//ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val; //ADC0->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val; // Gain Factor Selection
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/2 VDDANA = 1.65 ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
break; 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
#if defined(__SAMD51__)
value = mapResolution(value, _writeResolution, _dacResolution); value = mapResolution(value, _writeResolution, _dacResolution);
#if defined(__SAMD51__)
uint8_t channel = (pin == PIN_DAC0 ? 0 : 1); uint8_t channel = (pin == PIN_A0 ? 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

View file

@ -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 ;

View file

@ -30,43 +30,39 @@ 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:

View file

@ -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.
* *

View file

@ -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

View file

@ -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

View file

@ -1 +0,0 @@
// fake empty header file to make Arduino IDE happy

View file

@ -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);
}

View file

@ -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) :

View file

@ -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;

View file

@ -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"

View file

@ -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

View file

@ -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
@ -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

View file

@ -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