Compare commits

...

142 commits

Author SHA1 Message Date
Ha Thach
05e83bcb71
Merge pull request #373 from adafruit/add-issue-template
add issue template
2025-08-07 17:09:11 +07:00
hathach
0a48a55866
add issue template 2025-08-07 15:33:58 +07:00
Ha Thach
6653744ce4
Merge pull request #370 from adafruit/fix-TRRS-Trinkey-variant-name
fix variant folder name case for trrstrinkey_m0
2024-12-25 16:10:07 +07:00
hathach
592ec7707d
fix variant folder name case for trrstrinkey_m0 2024-12-25 15:06:00 +07:00
Mikey Sklar
bb552819ba
Pixel Trinkey Analog JST pin (#369)
Adding analog support to the 3-pin JST A6.
2024-09-18 13:54:26 -04:00
Ha Thach
8859387343
Merge pull request #367 from DennisErnst/master
Fix hangs when transfer errors occur
2024-09-05 19:00:38 +07:00
hathach
c8287a11c6
clean up format 2024-09-05 18:47:37 +07:00
Dennis Ernst
6e5580d9b2
Add files via upload 2024-07-21 10:50:03 -07:00
Dennis Ernst
ccfc7db988
Add files via upload 2024-07-18 12:43:41 -07:00
Ha Thach
ce20340620
Merge pull request #339 from yosinski/master
Add .ramfunc attribute to flash_with_bootloader.ld to enable keeping functions in RAM
2024-07-18 17:57:17 +07:00
Ha Thach
6ed425f871
Merge pull request #362 from nerdyscout/fix/update_TinyUSB
update to 3.1.5 of Adafruit TinyUSB
2024-07-18 17:47:55 +07:00
Liz
576d6271ed Revert "Merge pull request #363 from BlitzCityDIY/trrs_update"
This reverts commit e7a9d6d762, reversing
changes made to 9bb5b21093.
2024-06-25 19:14:24 -04:00
Liz
726453fa91 Revert "Merge pull request #364 from BlitzCityDIY/master"
This reverts commit 3044845d73, reversing
changes made to e7a9d6d762.
2024-06-25 19:14:19 -04:00
Liz
3044845d73
Merge pull request #364 from BlitzCityDIY/master
two more TRRS
2024-06-25 18:59:56 -04:00
Liz
12e2013e2b two more TRRS 2024-06-25 18:52:49 -04:00
e7a9d6d762
Merge pull request #363 from BlitzCityDIY/trrs_update
updating TRRS Trinkey naming for case sensitivity
2024-06-25 16:21:58 -05:00
Liz
463eb00619 updating TRRS Trinkey naming for case sensitivity 2024-06-25 16:30:51 -04:00
nerdyscout
c0c7bd0bcb update to 3.1.5 2024-06-10 13:29:54 +02:00
Ha Thach
9bb5b21093
Merge pull request #361 from adafruit/bump-1.7.16
bump up version 1.7.16
2024-05-22 09:52:13 +07:00
Ha Thach
3a527f8e85
bump up version 1.7.16 2024-05-22 09:45:15 +07:00
ladyada
7473729af3 Merge branch 'master' of github.com:adafruit/ArduinoCore-samd 2024-05-21 20:23:06 -04:00
ladyada
b64fe90c4a fix for rev B hardware
cc @blitzcitydiy
2024-05-21 20:23:02 -04:00
Ha Thach
4693b93d69
Merge pull request #360 from adafruit/minor-update
update makeboards.py, fix board name typo
2024-05-17 10:09:16 +07:00
hathach
ffb6935392
update makeboards.py, fix board name typo 2024-05-17 09:58:01 +07:00
Ha Thach
9dc3465b47
Merge pull request #359 from adafruit/bump-version-1.7.15
bump up version to 1.7.15
2024-05-17 09:38:04 +07:00
hathach
61da91c518
bump up version to 1.7.15 2024-05-17 09:24:46 +07:00
Ha Thach
ac9e81e58e
Merge pull request #358 from rcross-lc/master
Use the correct openocd flash driver for ATSAMD51 devices
2024-05-15 16:54:15 +07:00
ladyada
72e88b41ea many variant trinks! 2024-05-11 13:10:07 -04:00
ladyada
5a5790412c hardware design rev B 2024-05-11 13:09:32 -04:00
Robert Cross
634b97cc40 Use the correct openocd flash driver for ATSAMD51 devices
see openocd docs ( https://github.com/openocd-org/openocd/blob/v0.11.0/doc/openocd.texi#L5827C1-L5827C54 )
2024-05-09 16:44:23 -04:00
Liz
b2358faa51
increase version for 1.7.14 release 2024-03-26 08:38:21 -04:00
Liz
1a8763701d
Merge pull request #355 from adafruit/sht4xtrinkey
Tested SHT4x Trinkey
2024-03-25 08:22:29 -04:00
hathach
e82192ca1a
update makeboards.py 2024-03-13 17:42:41 +07:00
ladyada
9b1b3ba02d Tested SHT4x Trinkey 2024-03-05 11:00:29 -05:00
Ha Thach
0bf32589c9
Merge pull request #328 from caternuson/iss320_dotstar
add PIN_DOTSTAR_CLOCK
2024-03-05 12:58:34 +07:00
Ha Thach
e43b1ef3aa
Merge pull request #347 from IanBurwell/ib/pyportal-ss-fix
PyPortal: fix SS pin definition
2024-03-05 12:58:12 +07:00
Ha Thach
4c6cc0ef6f
Merge pull request #354 from adafruit/update-tinyusb
Update tinyusb to v3.1
2024-03-05 12:56:23 +07:00
hathach
c1b79a8231
udpate tinyusb to v3.1 2024-03-05 12:44:54 +07:00
Ha Thach
767168482d
Merge pull request #353 from adafruit/update-libraries
update tinyusb and zerodma libraries
2024-02-06 16:17:17 +07:00
hathach
8619fd9190 update tinyusb and zerodma libraries 2024-02-06 15:22:24 +07:00
Ha Thach
21ac7624c9
Merge pull request #351 from adafruit/fix-sendStringDescriptor
fix sendStringDescriptor() maxlen uitn8_t to uint32_t
2023-11-27 18:32:44 +07:00
hathach
f85cf1b8a3 fix sendStringDescriptor() maxlen uitn8_t to uint32_t 2023-11-27 11:54:09 +07:00
Ha Thach
e2b78cbd36
Merge pull request #348 from adafruit/hathach-patch-1
increase version for release 1.7.13
2023-06-23 10:48:43 +07:00
Ha Thach
eebe841a7d
increase version for release 1.7.13 2023-06-23 10:41:05 +07:00
Ha Thach
164decde3b
Merge pull request #346 from adafruit/ide2-debug
Arduino IDE v2 debuging suport
2023-06-23 10:38:54 +07:00
hathach
bc76c89c90 explicit specify openocd 0.11.0-arduino2 2023-06-23 09:55:55 +07:00
Ian Burwell
b0322762a5 pyportal: add SS pin 2023-06-22 20:34:16 -04:00
hathach
df5b8c6054 comment out jlink over openocd since IDE does not pick that up and could cause questions 2023-06-22 23:28:21 +07:00
hathach
c3d53add36 add support for jlink as transport for openocd
though menu selection does not seem to work with debug script. Though
this is probably IDE issue.
2023-06-22 23:05:24 +07:00
hathach
c9e285c482 fix ci, rename script 2023-06-22 19:19:18 +07:00
hathach
41cd7a70e1 adding samd51 debug, still wip 2023-06-22 16:42:55 +07:00
hathach
463beee02d debug work with itsybitsy and pico probe 2023-06-22 12:25:24 +07:00
hathach
2f8f40c05c more script update 2023-06-21 23:07:26 +07:00
hathach
ef8903ac8e move makboards.py scripts tools/, refactor to use f-string 2023-06-21 21:34:19 +07:00
Ha Thach
313ef47993
Merge pull request #344 from adafruit/release-1.7.12
fix incorrect PID for pIRKey board (conflict with M0 trinket)
2023-05-23 11:14:01 +07:00
hathach
c307d378eb
fix incorrect PID for pIRKey board (conflict with M0 trinket) 2023-05-23 10:12:41 +07:00
dherrada
159e3c31ed Update CI action versions 2023-05-12 11:24:12 -04:00
Jason Yosinski
a6b4ae7738 Added .ramfunc attribute to linker script to enable keeping functions in RAM. 2022-12-20 11:27:08 -08:00
Ha Thach
0fd44a54b7
Merge pull request #278 from rlcamp/master
Fix typo in samd51 clock init which was preventing XOSC1K from being used in RTCCTRL
2022-11-15 09:24:47 +07:00
Ha Thach
7812526590
Merge pull request #338 from rlcamp/ltofix
Prevent LTO from omitting the ISR vector table
2022-11-15 09:02:35 +07:00
Richard Campbell
7ca484ac85 Prevent LTO from omitting the ISR vector table for SAMD21 too 2022-11-13 22:13:30 -08:00
Richard Campbell
88bafcc09e Prevent LTO from omitting the ISR vector table 2022-11-13 10:53:59 -08:00
rlcamp
22176f8c20
Merge branch 'adafruit:master' into master 2022-11-13 10:35:57 -08:00
Ha Thach
024eaa50d1
Merge pull request #337 from adafruit/release-1.7.11
Remove ARDUINO_SAMD_ZERO for some boards
2022-11-01 12:09:42 +07:00
hathach
66ebeeb4dc
bump version to 1.7.11 2022-11-01 11:51:41 +07:00
hathach
7c47afb817
remove ARDUINO_SAMD_ZERO from some boards due to fastled issue 2022-11-01 11:51:14 +07:00
hathach
ad12ce969f fix possible windows bossac tool 2022-10-12 21:42:23 +07:00
Tim Vrakas
c2d4153929
Proposal to improve WVariant part number define logic (#326)
* add ethernet interupt dummy handler

* fix timer definitions for -N and -P SAMx5x parts
2022-07-31 23:38:27 -04:00
Ha Thach
bd2a9cdbe7
change the SDA, SCL timer from alt to primary to avoid pwm conflict (#331) 2022-06-05 16:49:30 -04:00
caternuson
b13ae7f0b7 add PIN_DOTSTAR_CLOCK 2022-03-23 11:43:51 -07:00
Ha Thach
137b8d2de0
fix typo board defines for feather m0 express (#325) 2022-03-08 14:24:19 -05:00
Ha Thach
85f71fb7c1
Merge pull request #324 from adafruit/release-1.7.10
increase verion to 1.7.10
2022-02-17 17:07:05 +07:00
hathach
ada1b9d9d3 increase verion to 1.7.10
bump up included tinyusb to 1.9.4
2022-02-17 16:54:43 +07:00
Ha Thach
81f9ee0889
Merge pull request #323 from adafruit/revert-bossac-to-1.8
revert bossac tool from 1.9 back to 1.8
2022-02-06 00:39:01 +07:00
hathach
327fbceb48 revert bossac tool from 1.9 back to 1.8
move blm badge up in boards.txt, update id for portal m4
2022-02-04 12:12:52 +07:00
Kattni
d4ed1fd456
Merge pull request #321 from caternuson/iss320_dotstar
Add defines for internal DotStar pins
2022-01-26 18:50:42 -05:00
caternuson
dd787f583c paran u 2022-01-26 15:23:50 -08:00
caternuson
6398c2a1ac add dotstar pin defs 2022-01-26 15:19:30 -08:00
Ha Thach
2a7aae79ee
Update makeboards.py 2022-01-27 01:15:58 +07:00
Ha Thach
d8893ff12f
Merge pull request #319 from adafruit/bossac-1.9
migrate all boards upload tool from bossac 1.8 to 1.9 and auto-generate boards.txt
2022-01-27 01:15:03 +07:00
hathach
5528bf224f add makeboard.py to genearte boards.txt to prevent error in board addition 2022-01-26 17:25:48 +07:00
hathach
6bc12c92fe
migrate all boards from bossac 1.8 to 1.9 2022-01-25 22:03:49 +07:00
Ha Thach
67dfb93a4a
migrate all m0 upload tool to bossac 1.8 (#318) 2022-01-14 16:59:59 -05:00
Ha Thach
c999601efc
increase version to 1.7.7 for release 2022-01-13 11:42:21 +07:00
Ha Thach
3f214fea3b
Merge pull request #317 from adafruit/more-bossac18
update bossac18 for neokey, neo, rotary, slide trinkey m0
2022-01-13 11:27:05 +07:00
hathach
53248609ec
update bossac18 for neokey, neo, rotary, slide trinkey m0
also add fake SPI interfaces for them as well
2022-01-13 11:04:19 +07:00
Ha Thach
525980e0ee
Prepare BSP for Internal Flash filesystem (#316)
* update upload tool for adafruit_proxlighttrinkey_m0 to bossac18

* fake SPI Interface so we could compile with SdFat
2022-01-12 13:34:27 -05:00
hathach
90b4d35236
increase version 1.7.6 for release 2022-01-10 22:46:08 +07:00
Ha Thach
9785217e25
Merge pull request #315 from adafruit/add-Werror=return-type
add -Werror=return-type for all warning options
2022-01-07 02:19:25 +07:00
hathach
bac2839448 add -Werror=return-type for all warning options 2022-01-06 18:20:59 +07:00
ladyada
a8c4b4d8e3 Merge branch 'master' of github.com:adafruit/ArduinoCore-samd 2022-01-04 13:50:18 -05:00
ladyada
3db7484736 'hot fix' for https://github.com/arduino-libraries/WiFiNINA/issues/184 2022-01-04 13:50:14 -05:00
Ha Thach
e669a01bc1
Merge pull request #314 from prampec/patch-1
Introduce digital pin definitions
2021-12-21 12:24:25 +07:00
Balázs Kelemen
e715d707ef
Introduce digital pin definitions
Pin definitions are based on the schematics.
2021-12-20 23:20:19 +01:00
Ha Thach
1710c41552
enable DRVSTR for output pin (#313)
add neopixel and button pin define for circuitplay
2021-12-13 22:58:26 -05:00
Ha Thach
41c0a72f37
Merge pull request #310 from MartinL1/master
Add int64_t and uint64_t data types to Serial.print(ln)
2021-10-01 15:21:57 +07:00
hathach
6f5a596b31
indentation 2021-10-01 14:58:17 +07:00
MartinL1
3b2df62575
Update Print.cpp 2021-09-30 12:27:12 +01:00
MartinL1
6907751dd1
Update Print.h 2021-09-30 12:25:26 +01:00
Ha Thach
8b70e4c252
Merge pull request #309 from zuyan9/master
Bugfix - waiting for first ADC read to complete after ADC enable.
2021-09-17 17:38:54 +07:00
Zuyang
6ddfddf877
Bugfix - waiting for first ADC read to complete after ADC enable. 2021-09-15 19:14:42 -04:00
Ha Thach
bafcb36c19
bump up version for release 1.7.5 2021-09-01 12:27:38 +07:00
Ha Thach
11b223acef
Merge pull request #308 from adafruit/more-m4-can-typo
fix m4 can typo
2021-08-31 22:28:27 +07:00
hathach
e24e4af26b
fix m4 can typo 2021-08-31 22:15:41 +07:00
Ha Thach
1b17683575
increase version for 1.7.4 release 2021-08-17 11:38:02 +07:00
Ha Thach
46e2271984
fix m4 can pin typo (#307)
also bump up tinyusb lib
2021-08-16 11:56:21 -04:00
Ha Thach
de975d929c
Merge pull request #306 from 2bndy5/global-define-for-any-adafruit-boards
add -DADAFRUIT_ARCH_SAMD to all board's build.extra_flags
2021-07-16 00:19:08 +07:00
Brendan
42d3ad1e0b requested changes 2021-07-15 00:20:52 -07:00
Brendan
a02b851395 add -DADAFRUIT_ARCH_SAMD to all board's build.extra_flags 2021-07-14 18:45:39 -07:00
hathach
f5564f85f1 bump TinyUSB to 1.3.0 2021-06-29 11:55:50 +07:00
hathach
2163aa82fe
bump tinyusb 2021-06-26 01:38:30 +07:00
Ha Thach
203746757a
Update tinyusb library to compatible with 1.2.0 (#303)
* more Adafruit_TinyUSB include

* add metro m0 m4 with tinyusb to ci

* correct fqbn

* support ci with tinyusb variant

bump zeroDMA and fix warnings with USBHost library example

* install missing libraries

* more libraries

* update tinyusb library to 1.2.0

increase version to 1.7.3
2021-06-25 10:08:33 -04:00
Ha Thach
4e51791226
Merge pull request #301 from adafruit/more-ci-work
More ci work
2021-05-26 13:13:26 +07:00
hathach
aff98b3875
increase version 1.7.2 for release 2021-05-26 12:54:37 +07:00
hathach
3c601b613e
bump builtin TinyUSB to 1.0.3 2021-05-26 10:05:12 +07:00
hathach
481e4920dd
always build with all warnings, but not fatal error 2021-05-25 22:37:20 +07:00
hathach
8c2dd0b682
bump zeroDMA 2021-05-25 22:01:22 +07:00
hathach
9c2bdbc314
include TinyUSB header for builtin libraries if selected 2021-05-25 18:30:09 +07:00
hathach
69a2211b81
add Adafruit_ZeroDMA as submodules 2021-05-25 18:04:21 +07:00
hathach
14a6b40ed9
remove local copy of Adafruit_ZeroDMA 2021-05-25 18:03:58 +07:00
Ha Thach
cca8448cfe
Merge pull request #300 from adafruit/fix-warnings
Fix warnings
2021-05-24 23:41:00 +07:00
hathach
33a1e15fb0 increase version to 1.7.1 2021-05-24 23:33:50 +07:00
hathach
e49dab6406 also bump tinyusb 2021-05-24 23:33:24 +07:00
hathach
51bd7a7967 better fix warning with "-Wclass-memaccess" in SPI 2021-05-24 21:31:52 +07:00
hathach
a7a8b02854 use CMSIS-Atmel-1.2.2 to fix LITTLE_ENDIAN warning 2021-05-24 20:44:16 +07:00
Ha Thach
fa24f50fb4
increase version to 1.7.0 for release 2021-05-19 13:24:46 +07:00
Ha Thach
7585cb7b76
Merge pull request #298 from adafruit/rework-tinyusb
Rework tinyusb lib
2021-05-19 13:23:48 +07:00
hathach
461f855940 ci skip tinyusb lib examples for now 2021-05-18 21:24:48 +07:00
hathach
a7bab5b591 update tinyusb lib to 1.0.0 2021-05-18 17:35:49 +07:00
hathach
a9d41b6019 fix typo in tinyusb lib 2021-05-10 19:11:44 +07:00
hathach
c262dc2ff9 clean up and add note for "-Wclass-memaccess" 2021-05-10 19:06:44 +07:00
hathach
7234390bc1
sync tinyusb lib 2021-05-10 17:16:42 +07:00
hathach
3c173d5d19
update with TinyUSB_Device_FlushCDC() 2021-05-10 12:52:55 +07:00
hathach
30d0738262 sync with tinyusb lib latest change 2021-05-10 12:22:18 +07:00
hathach
704450cc1c
add libraries/Adafruit_TinyUSB_Arduino as submodule
include Adafruit_USBD_CDC.h from submodule
2021-05-08 01:08:31 +07:00
hathach
15fd604313 clean up 2021-05-07 17:30:00 +07:00
hathach
88520ba975 update tinyusb header 2021-05-07 14:49:02 +07:00
hathach
1f029ece68 fix typo 2021-05-07 00:30:15 +07:00
hathach
6fd7609c6e add feather m4 can to ci 2021-05-07 00:15:08 +07:00
hathach
d3091df758
change porting API 2021-05-06 21:47:26 +07:00
hathach
fc358eaf65
remove tinyusb core submodule, move tinyusb src to its own library to reduce dependency 2021-05-06 16:03:34 +07:00
Richard Campbell
146e8b8e53 Fix typo in samd51 clock init 2020-12-27 00:52:53 -08:00
97 changed files with 6088 additions and 2913 deletions

95
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View file

@ -0,0 +1,95 @@
name: Bug Report
description: Report a problem
labels: 'Bug'
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
It's okay to leave some blank if it doesn't apply to your problem.
- type: dropdown
attributes:
label: Operating System
options:
- Linux
- MacOS
- RaspberryPi OS
- Windows 7
- Windows 10
- Windows 11
- Others
validations:
required: true
- type: input
attributes:
label: Arduino IDE version
placeholder: e.g Arduino 1.8.15
validations:
required: true
- type: input
attributes:
label: Board
placeholder: e.g Metro M4 Express
validations:
required: true
- type: input
attributes:
label: ArduinoCore version
description: Can be found under "Board Manager" menu
validations:
required: true
- type: textarea
attributes:
label: Sketch as ATTACHED TXT
placeholder: |
e.g examples/MassStorage/msc_ramdisk.
If it is custom sketch, please provide it as **ATTACHED** files or link to it.
Pasting raw long code that hurts readability can get your issue **closed**
validations:
required: true
- type: textarea
attributes:
label: Compiled Log as ATTACHED TXT
placeholder: |
Compiled log from Arduino IDE as **ATTACHED** txt.
Pasting raw long log that hurts readability can get your issue **closed**
validations:
required: true
- type: textarea
attributes:
label: What happened ?
placeholder: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: How to reproduce ?
placeholder: |
1. Go to '...'
2. Click on '....'
3. See error
validations:
required: true
- type: textarea
attributes:
label: Debug Log as ATTACHED TXT
placeholder: |
Debug log where the issue occurred as attached txt file, best with comments to explain the actual events.
validations:
required: false
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem.
validations:
required: false

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1,5 @@
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

@ -0,0 +1,20 @@
---
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

@ -7,27 +7,30 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
arduino-platform: ['metro_m0', 'hallowing', 'circuitplayground_m0', board:
'metro_m4', 'pybadge_m4', 'pygamer_m4', 'hallowing_m4', 'pyportal_m4', 'pyportal_m4_titano'] # 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 runs-on: ubuntu-latest
steps: steps:
- name: Setup Python
uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v4
with:
submodules: 'true'
- name: Checkout submodules
shell: bash
run: |
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive
- name: Install Arduino CLI and Tools - name: Install Arduino CLI and Tools
run: | run: |
# make all our directories we need for files and libraries # make all our directories we need for files and libraries
@ -42,7 +45,6 @@ jobs:
env: env:
BSP_URL: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json BSP_URL: https://adafruit.github.io/arduino-board-index/package_adafruit_index.json
BSP_PATH: .arduino15/packages/adafruit/hardware/samd BSP_PATH: .arduino15/packages/adafruit/hardware/samd
LIB_DEPS: FlashStorage SD
run: | run: |
arduino-cli config init arduino-cli config init
arduino-cli core update-index arduino-cli core update-index
@ -53,11 +55,7 @@ jobs:
BSP_VERSION=`eval ls $HOME/$BSP_PATH` BSP_VERSION=`eval ls $HOME/$BSP_PATH`
rm -r $HOME/$BSP_PATH/* rm -r $HOME/$BSP_PATH/*
ln -s $GITHUB_WORKSPACE $HOME/$BSP_PATH/$BSP_VERSION ln -s $GITHUB_WORKSPACE $HOME/$BSP_PATH/$BSP_VERSION
arduino-cli lib install $LIB_DEPS arduino-cli lib install "Adafruit NeoPixel" "Adafruit seesaw Library" "Adafruit SPIFlash" "FlashStorage" "MIDI Library" "SD" "SdFat - Adafruit Fork"
- name: Build examples - name: Build examples
run: python3 extras/build_all.py ${{ matrix.arduino-platform }} run: python3 tools/build_all.py ${{ matrix.board }}
# How to mark this as allowed-to-fail?
- name: Build examples (-Wall)
run: python3 extras/build_all.py --all_warnings --warnings_do_not_cause_job_failure

3
.gitignore vendored
View file

@ -2,4 +2,5 @@
*.atsuo *.atsuo
bootloaders/*/build/ bootloaders/*/build/
*~ *~
/libraries/**/build/

9
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "cores/arduino/TinyUSB/Adafruit_TinyUSB_ArduinoCore"] [submodule "libraries/Adafruit_TinyUSB_Arduino"]
path = cores/arduino/TinyUSB/Adafruit_TinyUSB_ArduinoCore path = libraries/Adafruit_TinyUSB_Arduino
url = https://github.com/adafruit/Adafruit_TinyUSB_ArduinoCore.git url = https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
[submodule "libraries/Adafruit_ZeroDMA"]
path = libraries/Adafruit_ZeroDMA
url = https://github.com/adafruit/Adafruit_ZeroDMA

3034
boards.txt

File diff suppressed because it is too large Load diff

View file

@ -150,12 +150,13 @@ void loop( void ) ;
// USB // USB
#ifdef USE_TINYUSB #ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_Core.h" // Needed for declaring Serial
#include "Adafruit_USBD_CDC.h"
#else #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
#endif // Arduino_h #endif // Arduino_h

View file

@ -94,6 +94,28 @@ 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);
@ -172,6 +194,20 @@ 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);
@ -218,6 +254,81 @@ 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;
@ -262,3 +373,4 @@ size_t Print::printFloat(double number, uint8_t digits)
return n; return n;
} }

View file

@ -37,6 +37,7 @@ 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; }
@ -69,6 +70,8 @@ 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&);
@ -81,6 +84,8 @@ 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);

View file

@ -556,29 +556,35 @@ bool SERCOM::startTransmissionWIRE(uint8_t address, SercomWireReadWriteFlag flag
// Address Transmitted // Address Transmitted
if ( flag == WIRE_WRITE_FLAG ) // Write mode if ( flag == WIRE_WRITE_FLAG ) // Write mode
{ {
while( !sercom->I2CM.INTFLAG.bit.MB ) while( !sercom->I2CM.INTFLAG.bit.MB ) {
{
// Wait transmission complete // Wait transmission complete
// If certain errors occur, the MB bit may never be set (RFTM: SAMD21 sec:28.10.6; SAMD51 sec:36.10.7).
// The data transfer errors that can occur (including BUSERR) are all
// rolled up into INTFLAG.bit.ERROR from STATUS.reg
if (sercom->I2CM.INTFLAG.bit.ERROR) {
return false;
}
} }
} }
else // Read mode else // Read mode
{ {
while( !sercom->I2CM.INTFLAG.bit.SB ) while( !sercom->I2CM.INTFLAG.bit.SB ) {
{
// If the slave NACKS the address, the MB bit will be set.
// In that case, send a stop condition and return false.
if (sercom->I2CM.INTFLAG.bit.MB) {
sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
return false;
}
// Wait transmission complete // Wait transmission complete
// If the slave NACKS the address, the MB bit will be set.
// A variety of errors in the STATUS register can set the ERROR bit in the INTFLAG register
// In that case, send a stop condition and return false.
if (sercom->I2CM.INTFLAG.bit.MB || sercom->I2CM.INTFLAG.bit.ERROR) {
sercom->I2CM.CTRLB.bit.CMD = 3; // Stop condition
return false;
}
} }
// Clean the 'Slave on Bus' flag, for further usage. // Clean the 'Slave on Bus' flag, for further usage.
//sercom->I2CM.INTFLAG.bit.SB = 0x1ul; //sercom->I2CM.INTFLAG.bit.SB = 0x1ul;
} }
//ACK received (0: ACK, 1: NACK) //ACK received (0: ACK, 1: NACK)
if(sercom->I2CM.STATUS.bit.RXNACK) if(sercom->I2CM.STATUS.bit.RXNACK)
{ {
@ -597,10 +603,11 @@ 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.
// If a bus error occurs, the MB bit may never be set. // Check the error bit and bail if it's set.
// Check the bus error bit and bail if it's set. // The data transfer errors that can occur (including BUSERR) are all
if (sercom->I2CM.STATUS.bit.BUSERR) { // rolled up into INTFLAG.bit.ERROR from STATUS.reg
if (sercom->I2CM.INTFLAG.bit.ERROR) {
return false; return false;
} }
} }
@ -701,9 +708,17 @@ 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 ;

@ -1 +0,0 @@
Subproject commit e7b892095f2bb5d8bef6a748238369bdd268ed5e

View file

@ -1,195 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019, hathach for Adafruit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifdef USE_TINYUSB
#include "Arduino.h"
#include "Adafruit_TinyUSB_Core.h"
#include <Reset.h> // Needed for auto-reset with 1200bps port touch
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
extern "C"
{
#if defined(__SAMD51__)
void USB_0_Handler (void) { tud_int_handler(0); }
void USB_1_Handler (void) { tud_int_handler(0); }
void USB_2_Handler (void) { tud_int_handler(0); }
void USB_3_Handler (void) { tud_int_handler(0); }
#else
void USB_Handler(void) { tud_int_handler(0); }
#endif
} // extern C
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
//--------------------------------------------------------------------+
static void usb_hardware_init(void);
#if CFG_TUSB_DEBUG
extern "C" int serial1_printf(const char *__restrict format, ...)
{
char buf[PRINTF_BUF];
va_list ap;
va_start(ap, format);
vsnprintf(buf, sizeof(buf), format, ap);
Serial1.write(buf);
va_end(ap);
}
#endif
//--------------------------------------------------------------------+
// Core Init & Touch1200
//--------------------------------------------------------------------+
void Adafruit_TinyUSB_Core_init(void)
{
#if CFG_TUSB_DEBUG
Serial1.begin(115200);
serial1_printf("TinyUSB debugging with Serial1\n");
#endif
Serial.setStringDescriptor("TinyUSB Serial");
USBDevice.addInterface(Serial);
USBDevice.setID(USB_VID, USB_PID);
USBDevice.begin();
usb_hardware_init();
// Init tinyusb stack
tusb_init();
}
void Adafruit_TinyUSB_Core_touch1200(void)
{
initiateReset(250);
}
//--------------------------------------------------------------------+
// Adafruit_USBD_Device platform dependent
//--------------------------------------------------------------------+
uint8_t Adafruit_USBD_Device::getSerialDescriptor(uint16_t* serial_str)
{
enum { SERIAL_BYTE_LEN = 16 };
#ifdef __SAMD51__
uint32_t* id_addresses[4] = {(uint32_t *) 0x008061FC, (uint32_t *) 0x00806010,
(uint32_t *) 0x00806014, (uint32_t *) 0x00806018};
#else // samd21
uint32_t* id_addresses[4] = {(uint32_t *) 0x0080A00C, (uint32_t *) 0x0080A040,
(uint32_t *) 0x0080A044, (uint32_t *) 0x0080A048};
#endif
uint8_t raw_id[SERIAL_BYTE_LEN];
for (int i=0; i<4; i++) {
for (int k=0; k<4; k++) {
raw_id[4 * i + (3 - k)] = (*(id_addresses[i]) >> k * 8) & 0xff;
}
}
static const char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
for (unsigned int i = 0; i < sizeof(raw_id); i++) {
for (int j = 0; j < 2; j++) {
uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf;
// Strings are UTF-16-LE encoded.
serial_str[i * 2 + (1 - j)] = nibble_to_hex[nibble];
}
}
return sizeof(raw_id)*2;
}
//--------------------------------------------------------------------+
// Helpers
//--------------------------------------------------------------------+
// Init usb hardware when starting up. Softdevice is not enabled yet
static void usb_hardware_init(void)
{
#ifdef PIN_LED_TXL
// txLEDPulse = 0;
pinMode(PIN_LED_TXL, OUTPUT);
digitalWrite(PIN_LED_TXL, HIGH);
#endif
#ifdef PIN_LED_RXL
// rxLEDPulse = 0;
pinMode(PIN_LED_RXL, OUTPUT);
digitalWrite(PIN_LED_RXL, HIGH);
#endif
/* Enable USB clock */
#if defined(__SAMD51__)
MCLK->APBBMASK.reg |= MCLK_APBBMASK_USB;
MCLK->AHBMASK.reg |= MCLK_AHBMASK_USB;
// Set up the USB DP/DN pins
PORT->Group[0].PINCFG[PIN_PA24H_USB_DM].bit.PMUXEN = 1;
PORT->Group[0].PMUX[PIN_PA24H_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24H_USB_DM & 0x01u)));
PORT->Group[0].PMUX[PIN_PA24H_USB_DM/2].reg |= MUX_PA24H_USB_DM << (4 * (PIN_PA24H_USB_DM & 0x01u));
PORT->Group[0].PINCFG[PIN_PA25H_USB_DP].bit.PMUXEN = 1;
PORT->Group[0].PMUX[PIN_PA25H_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25H_USB_DP & 0x01u)));
PORT->Group[0].PMUX[PIN_PA25H_USB_DP/2].reg |= MUX_PA25H_USB_DP << (4 * (PIN_PA25H_USB_DP & 0x01u));
GCLK->PCHCTRL[USB_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK1_Val | (1 << GCLK_PCHCTRL_CHEN_Pos);
NVIC_SetPriority(USB_0_IRQn, 0UL);
NVIC_SetPriority(USB_1_IRQn, 0UL);
NVIC_SetPriority(USB_2_IRQn, 0UL);
NVIC_SetPriority(USB_3_IRQn, 0UL);
#else
PM->APBBMASK.reg |= PM_APBBMASK_USB;
// Set up the USB DP/DN pins
PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1;
PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u)));
PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg |= MUX_PA24G_USB_DM << (4 * (PIN_PA24G_USB_DM & 0x01u));
PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1;
PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u)));
PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u));
// Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference)
GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6) | // Generic Clock Multiplexer 6
GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
GCLK_CLKCTRL_CLKEN;
while (GCLK->STATUS.bit.SYNCBUSY)
;
NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL);
#endif
}
#endif // USE_TINYUSB

View file

@ -1,93 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018, hathach for Adafruit
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------
#ifdef __SAMD51__
#define CFG_TUSB_MCU OPT_MCU_SAMD51
#else
#define CFG_TUSB_MCU OPT_MCU_SAMD21
#endif
#ifdef USE_TINYUSB
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
#else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE
#endif
#define CFG_TUSB_OS OPT_OS_NONE
#define CFG_TUSB_DEBUG 0
#if CFG_TUSB_DEBUG
#define tu_printf serial1_printf
extern int serial1_printf(const char *__restrict __format, ...);
#endif
#define CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
#define CFG_TUD_ENDOINT0_SIZE 64
//------------- CLASS -------------//
#define CFG_TUD_CDC 1
#define CFG_TUD_MSC 1
#define CFG_TUD_HID 1
#define CFG_TUD_MIDI 1
#define CFG_TUD_VENDOR 1
// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE 256
#define CFG_TUD_CDC_TX_BUFSIZE 256
// MSC Buffer size of Device Mass storage
#define CFG_TUD_MSC_BUFSIZE 512
// HID buffer size Should be sufficient to hold ID (if any) + Data
#define CFG_TUD_HID_BUFSIZE 64
// MIDI FIFO size of TX and RX
#define CFG_TUD_MIDI_RX_BUFSIZE 128
#define CFG_TUD_MIDI_TX_BUFSIZE 128
// Vendor FIFO size of TX and RX
#define CFG_TUD_VENDOR_RX_BUFSIZE 64
#define CFG_TUD_VENDOR_TX_BUFSIZE 64
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CONFIG_H_ */

View file

@ -85,7 +85,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, uint8_t maxlen); bool sendStringDescriptor(const uint8_t *string, uint32_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

@ -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, uint8_t maxlen) bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint32_t maxlen)
{ {
if (maxlen < 2) if (maxlen < 2)
return false; return false;
uint8_t buffer[maxlen]; uint8_t* buffer = (uint8_t*)malloc(maxlen);
buffer[0] = strlen((const char*)string) * 2 + 2; buffer[0] = strlen((const char*)string) * 2 + 2;
buffer[1] = 0x03; buffer[1] = 0x03;
@ -126,7 +126,9 @@ bool USBDeviceClass::sendStringDescriptor(const uint8_t *string, uint8_t maxlen)
buffer[i] = 0; buffer[i] = 0;
} }
return USBDevice.sendControl(buffer, i); bool ret = USBDevice.sendControl(buffer, i);
free(buffer);
return ret;
} }
bool _dry_run = false; bool _dry_run = false;

View file

@ -136,7 +136,7 @@ typedef enum _ETCChannel
TC7_CH1 = (12<<8)|(1), TC7_CH1 = (12<<8)|(1),
} ETCChannel ; } ETCChannel ;
#elif defined(__SAMD51P19A__) || defined(__SAMD51P20A__) #elif defined(__SAME53N20A__) || defined(__SAME53N19A__) || defined(__SAME54P20A__) || defined(__SAME54P19A__) || defined(__SAME54N20A__) || defined(__SAME54N19A__) || defined(__SAMD51P20A__) || defined(__SAMD51P19A__) || defined(__SAMD51N20A__) || defined(__SAMD51N19A__) || defined(__SAME51N20A__) || defined(__SAME51N19A__)
typedef enum _ETCChannel typedef enum _ETCChannel
{ {

View file

@ -133,6 +133,7 @@ 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")));
@ -195,6 +196,7 @@ 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 */
@ -302,7 +304,7 @@ __attribute__ ((section(".isr_vector"))) const DeviceVectors exception_table =
(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*) (0UL), (void*) GMAC_Handler, /* 84 Ethernet MAC */
(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 */
@ -406,6 +408,7 @@ 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

@ -117,6 +117,17 @@ 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

@ -41,7 +41,7 @@ int main( void )
delay(1); delay(1);
#if defined(USE_TINYUSB) #if defined(USE_TINYUSB)
Adafruit_TinyUSB_Core_init(); TinyUSB_Device_Init(0);
#elif defined(USBCON) #elif defined(USBCON)
USBDevice.init(); USBDevice.init();
USBDevice.attach(); USBDevice.attach();
@ -59,14 +59,3 @@ int main( void )
return 0; return 0;
} }
#if defined(USE_TINYUSB)
// run TinyUSB background task when yield()
extern "C" void yield(void)
{
tud_task();
tud_cdc_write_flush();
}
#endif

View file

@ -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_EN32K | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_CGM_XT | OSC32KCTRL_XOSC32K_XTALEN; OSC32KCTRL->XOSC32K.reg = OSC32KCTRL_XOSC32K_ENABLE | OSC32KCTRL_XOSC32K_EN1K | OSC32KCTRL_XOSC32K_EN32K | OSC32KCTRL_XOSC32K_CGM_XT | OSC32KCTRL_XOSC32K_XTALEN;
while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){ while( (OSC32KCTRL->STATUS.reg & OSC32KCTRL_STATUS_XOSC32KRDY) == 0 ){
/* Wait for oscillator to be ready */ /* Wait for oscillator to be ready */

View file

@ -375,6 +375,9 @@ 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;

View file

@ -39,39 +39,39 @@ void pinMode( uint32_t ulPin, uint32_t 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[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN);
PORT->Group[port].DIRCLR.reg = pinMask ; PORT->Group[port].DIRCLR.reg = pinMask;
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[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN);
PORT->Group[port].DIRCLR.reg = pinMask ; PORT->Group[port].DIRCLR.reg = pinMask;
// 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[port].OUTSET.reg = pinMask;
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[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN);
PORT->Group[port].DIRCLR.reg = pinMask ; PORT->Group[port].DIRCLR.reg = pinMask;
// 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[port].OUTCLR.reg = pinMask;
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->Group[port].PINCFG[pin].reg = (uint8_t) (PORT_PINCFG_INEN | PORT_PINCFG_DRVSTR);
// Set pin to output mode // Set pin to output mode
PORT->Group[port].DIRSET.reg = pinMask ; PORT->Group[port].DIRSET.reg = pinMask;
break ; break;
default: default:
// do nothing // do nothing
break ; break;
} }
} }

View file

@ -25,6 +25,8 @@
#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

@ -1,124 +0,0 @@
import os
import glob
import sys
import subprocess
import time
import argparse
FQBN_PREFIX='adafruit:samd:adafruit_'
parser = argparse.ArgumentParser(
description='python wrapper for adafruit arduino CI workflows',
allow_abbrev=False
)
parser.add_argument(
'--all_warnings', '--Wall',
action='store_true',
help='build with all warnings enabled (`--warnings all`)',
)
parser.add_argument(
'--warnings_do_not_cause_job_failure',
action='store_true',
help='failed builds will be listed as failed, but not cause job to exit with an error status',
)
parser.add_argument(
'build_boards',
metavar='board',
nargs='*',
help='list of boards to be built -- Note that the fqbn is created by prepending "{}"'.format(FQBN_PREFIX),
default= [ 'metro_m0', 'metro_m4', 'circuitplayground_m0' ]
)
args = parser.parse_args()
exit_status = 0
success_count = 0
fail_count = 0
skip_count = 0
build_format = '| {:22} | {:30} | {:9} '
build_separator = '-' * 80
def errorOutputFilter(line: str):
if len(line) == 0:
return False
if line.isspace(): # Note: empty string does not match here!
return False
# TODO: additional items to remove?
return True
def build_examples(variant: str):
global args, exit_status, success_count, fail_count, skip_count, build_format, build_separator
print('\n')
print(build_separator)
print('| {:^76} |'.format('Board ' + variant))
print(build_separator)
print((build_format + '| {:6} |').format('Library', 'Example', 'Result', 'Time'))
print(build_separator)
fqbn = "{}{}".format(FQBN_PREFIX, variant)
for sketch in glob.iglob('libraries/**/*.ino', recursive=True):
start_time = time.monotonic()
# Skip if contains: ".board.test.skip" or ".all.test.skip"
# Skip if not contains: ".board.test.only" for a specific board
sketchdir = os.path.dirname(sketch)
if os.path.exists(sketchdir + '/.all.test.skip') or os.path.exists(sketchdir + '/.' + variant + '.test.skip'):
success = "\033[33mskipped\033[0m "
elif glob.glob(sketchdir+"/.*.test.only") and not os.path.exists(sketchdir + '/.build.' + variant):
success = "\033[33mskipped\033[0m "
else:
# TODO - preferably, would have STDERR show up in **both** STDOUT and STDERR.
# preferably, would use Python logging handler to get both distinct outputs and one merged output
# for now, split STDERR when building with all warnings enabled, so can detect warning/error output.
if args.all_warnings:
build_result = subprocess.run("arduino-cli compile --warnings all --fqbn {} {}".format(fqbn, sketch), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
build_result = subprocess.run("arduino-cli compile --warnings default --fqbn {} {}".format(fqbn, sketch), shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# get stderr into a form where len(warningLines) indicates a true warning was output to stderr
warningLines = [];
if args.all_warnings and build_result.stderr:
tmpWarningLines = build_result.stderr.decode("utf-8").splitlines()
warningLines = list(filter(errorOutputFilter, (tmpWarningLines)))
if build_result.returncode != 0:
exit_status = build_result.returncode
success = "\033[31mfailed\033[0m "
fail_count += 1
elif len(warningLines) != 0:
if not args.warnings_do_not_cause_job_failure:
exit_status = -1
success = "\033[31mwarnings\033[0m "
fail_count += 1
else:
success = "\033[32msucceeded\033[0m"
success_count += 1
build_duration = time.monotonic() - start_time
print((build_format + '| {:5.2f}s |').format(sketch.split(os.path.sep)[1], os.path.basename(sketch), success, build_duration))
if success != "\033[33mskipped\033[0m ":
if build_result.returncode != 0:
print(build_result.stdout.decode("utf-8"))
if (build_result.stderr):
print(build_result.stderr.decode("utf-8"))
if len(warningLines) != 0:
for line in warningLines:
print(line)
else:
skip_count += 1
build_time = time.monotonic()
for board in args.build_boards:
build_examples(board)
print(build_separator)
build_time = time.monotonic() - build_time
print("Build Summary: {} \033[32msucceeded\033[0m, {} \033[31mfailed\033[0m, {} \033[33mskipped\033[0m and took {:.2f}s".format(success_count, fail_count, skip_count, build_time))
print(build_separator)
sys.exit(exit_status)

@ -0,0 +1 @@
Subproject commit c953968c468218d8968138b5ed8482fa565373df

@ -0,0 +1 @@
Subproject commit acc5dadb458b2c329757a61dc4f18dda945a0c36

View file

@ -1,654 +0,0 @@
#include <Adafruit_ZeroDMA.h>
#include <malloc.h> // memalign() function
#include "utility/dma.h"
static volatile uint32_t _channelMask = 0; // Bitmask of allocated channels
// DMA descriptor list entry point (and writeback buffer) per channel
__attribute__((__aligned__(16))) static DmacDescriptor // 128 bit alignment
_descriptor[DMAC_CH_NUM] SECTION_DMAC_DESCRIPTOR,
_writeback[DMAC_CH_NUM] SECTION_DMAC_DESCRIPTOR;
// Pointer to ZeroDMA object for each channel is needed for the
// ISR (in C, outside of class context) to access callbacks.
static Adafruit_ZeroDMA *_dmaPtr[DMAC_CH_NUM] = { 0 }; // Init to NULL
// Adapted from ASF3 interrupt_sam_nvic.c:
static volatile unsigned long cpu_irq_critical_section_counter = 0;
static volatile unsigned char cpu_irq_prev_interrupt_state = 0;
static void cpu_irq_enter_critical(void) {
if(!cpu_irq_critical_section_counter) {
if(__get_PRIMASK() == 0) { // IRQ enabled?
__disable_irq(); // Disable it
__DMB();
cpu_irq_prev_interrupt_state = 1;
} else {
// Make sure the to save the prev state as false
cpu_irq_prev_interrupt_state = 0;
}
}
cpu_irq_critical_section_counter++;
}
static void cpu_irq_leave_critical(void) {
// Check if the user is trying to leave a critical section
// when not in a critical section
if(cpu_irq_critical_section_counter > 0) {
cpu_irq_critical_section_counter--;
// Only enable global interrupts when the counter
// reaches 0 and the state of the global interrupt flag
// was enabled when entering critical state */
if((!cpu_irq_critical_section_counter) &&
cpu_irq_prev_interrupt_state) {
__DMB();
__enable_irq();
}
}
}
// CONSTRUCTOR -------------------------------------------------------------
// Constructor initializes Adafruit_ZeroDMA basics but does NOT allocate a
// DMA channel (that's done in allocate()) or start a job (that's done in
// startJob()). This is because constructors in a global context are called
// before a sketch's setup() function, which may have some other hardware
// initialization of its own, don't want it clobbering us.
Adafruit_ZeroDMA::Adafruit_ZeroDMA(void) {
channel = 0xFF; // Channel not yet allocated
jobStatus = DMA_STATUS_OK;
hasDescriptors = false; // No descriptors allocated yet
loopFlag = false;
peripheralTrigger = 0; // Software trigger only by default
triggerAction = DMA_TRIGGER_ACTON_TRANSACTION;
memset(callback, 0, sizeof(callback));
}
// TODO: add destructor? Should stop job, delete descriptors, free channel.
// INTERRUPT SERVICE ROUTINE -----------------------------------------------
// This is a C function that exists outside the Adafruit_ZeroDMA context.
// DMA channel number is determined from the INTPEND register, from this
// we get a ZeroDMA object pointer through the _dmaPtr[] array.
// (It's done this way because jobStatus and callback[] are protected
// elements in the ZeroDMA object -- we can't touch them in C, but the
// next function after this, being part of the ZeroDMA class, can.)
#ifdef __SAMD51__
void DMAC_0_Handler(void) {
#else
void DMAC_Handler(void) {
#endif
cpu_irq_enter_critical();
uint8_t channel = DMAC->INTPEND.bit.ID; // Channel # causing interrupt
if(channel < DMAC_CH_NUM) {
Adafruit_ZeroDMA *dma;
if((dma = _dmaPtr[channel])) { // -> Channel's ZeroDMA object
#ifdef __SAMD51__
// Call IRQ handler with channel #
dma->_IRQhandler(channel);
#else
DMAC->CHID.bit.ID = channel;
// Call IRQ handler with interrupt flag(s)
dma->_IRQhandler(DMAC->CHINTFLAG.reg);
#endif
}
}
cpu_irq_leave_critical();
}
#ifdef __SAMD51__
void DMAC_1_Handler(void) __attribute__((weak, alias("DMAC_0_Handler")));
void DMAC_2_Handler(void) __attribute__((weak, alias("DMAC_0_Handler")));
void DMAC_3_Handler(void) __attribute__((weak, alias("DMAC_0_Handler")));
void DMAC_4_Handler(void) __attribute__((weak, alias("DMAC_0_Handler")));
#endif
void Adafruit_ZeroDMA::_IRQhandler(uint8_t flags) {
#ifdef __SAMD51__
// 'flags' is initially passed in as channel number,
// from which we look up the actual interrupt flags...
flags = DMAC->Channel[flags].CHINTFLAG.reg;
#endif
if(flags & DMAC_CHINTENCLR_TERR) {
// Clear error flag
#ifdef __SAMD51__
DMAC->Channel[channel].CHINTFLAG.reg = DMAC_CHINTENCLR_TERR;
#else
DMAC->CHINTFLAG.reg = DMAC_CHINTENCLR_TERR;
#endif
jobStatus = DMA_STATUS_ERR_IO;
if(callback[DMA_CALLBACK_TRANSFER_ERROR]) {
callback[DMA_CALLBACK_TRANSFER_ERROR](this);
}
} else if(flags & DMAC_CHINTENCLR_TCMPL) {
// Clear transfer complete flag
#ifdef __SAMD51__
DMAC->Channel[channel].CHINTFLAG.reg = DMAC_CHINTENCLR_TCMPL;
#else
DMAC->CHINTFLAG.reg = DMAC_CHINTENCLR_TCMPL;
#endif
jobStatus = DMA_STATUS_OK;
if(callback[DMA_CALLBACK_TRANSFER_DONE]) {
callback[DMA_CALLBACK_TRANSFER_DONE](this);
}
} else if(flags & DMAC_CHINTENCLR_SUSP) {
// Clear channel suspend flag
#ifdef __SAMD51__
DMAC->Channel[channel].CHINTFLAG.reg = DMAC_CHINTENCLR_SUSP;
#else
DMAC->CHINTFLAG.reg = DMAC_CHINTENCLR_SUSP;
#endif
jobStatus = DMA_STATUS_SUSPEND;
if(callback[DMA_CALLBACK_CHANNEL_SUSPEND]) {
callback[DMA_CALLBACK_CHANNEL_SUSPEND](this);
}
}
}
// DMA CHANNEL FUNCTIONS ---------------------------------------------------
// Allocates channel for ZeroDMA object
ZeroDMAstatus Adafruit_ZeroDMA::allocate(void) {
if(channel < DMAC_CH_NUM) return DMA_STATUS_OK; // Already alloc'd!
// Find index of first free DMA channel. As currently written,
// this "does not play well with others" as it assumes _channelMask
// is the final arbiter of channels in use (this is true only within
// this library -- but other DMA-driven code may have allocated its
// own channel(s) elsewhere, sometimes with an equally broken
// approach). A possible alternate approach, I haven't tested this
// yet, might be to loop through each channel, set DMAC->CHID.bit.ID
// and then test whether CHCTRLA.bit.ENABLE is set? But for now...
for(channel=0; (channel < DMAC_CH_NUM) &&
(_channelMask & (1 << channel)); channel++);
// Doesn't help that code later does a software reset of the DMA
// controller, which would blow out other DMA-using libraries
// anyway (or they're just as likely to blow out this one).
// I think it's just an all-or-nothing affair...use one library
// for DMA everything, never mix and match.
if(channel >= DMAC_CH_NUM) { // No free channel!
return DMA_STATUS_ERR_NOT_FOUND;
}
cpu_irq_enter_critical();
if(!_channelMask) { // No channels allocated yet; initialize DMA!
#if (SAML21) || (SAML22) || (SAMC20) || (SAMC21)
PM->AHBMASK.bit.DMAC_ = 1;
#elif defined(__SAMD51__)
MCLK->AHBMASK.bit.DMAC_ = 1; // Initialize DMA clocks
#else
PM->AHBMASK.bit.DMAC_ = 1; // Initialize DMA clocks
PM->APBBMASK.bit.DMAC_ = 1;
#endif
DMAC->CTRL.bit.DMAENABLE = 0; // Disable DMA controller
DMAC->CTRL.bit.SWRST = 1; // Perform software reset
// Initialize descriptor list addresses
DMAC->BASEADDR.bit.BASEADDR = (uint32_t)_descriptor;
DMAC->WRBADDR.bit.WRBADDR = (uint32_t)_writeback;
memset(_descriptor, 0, sizeof(_descriptor));
memset(_writeback , 0, sizeof(_writeback));
// Re-enable DMA controller with all priority levels
DMAC->CTRL.reg = DMAC_CTRL_DMAENABLE | DMAC_CTRL_LVLEN(0xF);
// Enable DMA interrupt at lowest priority
#ifdef __SAMD51__
IRQn_Type irqs[] = { DMAC_0_IRQn, DMAC_1_IRQn, DMAC_2_IRQn,
DMAC_3_IRQn, DMAC_4_IRQn };
for(uint8_t i=0; i<(sizeof irqs / sizeof irqs[0]); i++) {
NVIC_EnableIRQ(irqs[i]);
NVIC_SetPriority(irqs[i], (1<<__NVIC_PRIO_BITS)-1);
}
#else
NVIC_EnableIRQ(DMAC_IRQn);
NVIC_SetPriority(DMAC_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
#endif
}
_channelMask |= 1 << channel; // Mark channel as allocated
_dmaPtr[channel] = this; // Channel-index-to-object pointer
// Reset the allocated channel
#ifdef __SAMD51__
DMAC->Channel[channel].CHCTRLA.bit.ENABLE = 0;
DMAC->Channel[channel].CHCTRLA.bit.SWRST = 1;
#else
DMAC->CHID.bit.ID = channel;
DMAC->CHCTRLA.bit.ENABLE = 0;
DMAC->CHCTRLA.bit.SWRST = 1;
#endif
// Clear software trigger
DMAC->SWTRIGCTRL.reg &= ~(1 << channel);
// Configure default behaviors
#ifdef __SAMD51__
DMAC->Channel[channel].CHPRILVL.bit.PRILVL = 0;
DMAC->Channel[channel].CHCTRLA.bit.TRIGSRC = peripheralTrigger;
DMAC->Channel[channel].CHCTRLA.bit.TRIGACT = triggerAction;
DMAC->Channel[channel].CHCTRLA.bit.BURSTLEN =
DMAC_CHCTRLA_BURSTLEN_SINGLE_Val; // Single-beat burst length
#else
DMAC->CHCTRLB.bit.LVL = 0;
DMAC->CHCTRLB.bit.TRIGSRC = peripheralTrigger;
DMAC->CHCTRLB.bit.TRIGACT = triggerAction;
#endif
cpu_irq_leave_critical();
return DMA_STATUS_OK;
}
void Adafruit_ZeroDMA::setPriority(dma_priority pri) const {
#ifdef __SAMD51__
DMAC->Channel[channel].CHPRILVL.bit.PRILVL = pri;
#else
DMAC->CHCTRLB.bit.LVL = pri;
#endif
}
// Deallocate DMA channel
// TODO: should this delete/deallocate the descriptor list?
ZeroDMAstatus Adafruit_ZeroDMA::free(void) {
ZeroDMAstatus status = DMA_STATUS_OK;
cpu_irq_enter_critical(); // jobStatus is volatile
if(jobStatus == DMA_STATUS_BUSY) {
status = DMA_STATUS_BUSY; // Can't leave when busy
} else if((channel < DMAC_CH_NUM) && (_channelMask & (1 << channel))) {
// Valid in-use channel; release it
_channelMask &= ~(1 << channel); // Clear bit
if(!_channelMask) { // No more channels in use?
#ifdef __SAMD51__
NVIC_DisableIRQ(DMAC_0_IRQn); // Disable DMA interrupt
DMAC->CTRL.bit.DMAENABLE = 0; // Disable DMA
MCLK->AHBMASK.bit.DMAC_ = 0; // Disable DMA clock
#else
NVIC_DisableIRQ(DMAC_IRQn); // Disable DMA interrupt
DMAC->CTRL.bit.DMAENABLE = 0; // Disable DMA
PM->APBBMASK.bit.DMAC_ = 0; // Disable DMA clocks
PM->AHBMASK.bit.DMAC_ = 0;
#endif
}
_dmaPtr[channel] = NULL;
channel = 0xFF;
} else {
status = DMA_STATUS_ERR_NOT_INITIALIZED; // Channel not in use
}
cpu_irq_leave_critical();
return status;
}
// Start DMA transfer job. Channel and descriptors should be allocated
// before calling this.
ZeroDMAstatus Adafruit_ZeroDMA::startJob(void) {
ZeroDMAstatus status = DMA_STATUS_OK;
cpu_irq_enter_critical(); // Job status is volatile
if(jobStatus == DMA_STATUS_BUSY) {
status = DMA_STATUS_BUSY; // Resource is busy
} else if(channel >= DMAC_CH_NUM) {
status = DMA_STATUS_ERR_NOT_INITIALIZED; // Channel not in use
} else if(!hasDescriptors || (_descriptor[channel].BTCNT.reg <= 0)) {
status = DMA_STATUS_ERR_INVALID_ARG; // Bad transfer size
} else {
uint8_t i, interruptMask = 0;
for(i=0; i<DMA_CALLBACK_N; i++) {
if(callback[i]) interruptMask |= (1 << i);
}
jobStatus = DMA_STATUS_BUSY;
#ifdef __SAMD51__
DMAC->Channel[channel].CHINTENSET.reg =
DMAC_CHINTENSET_MASK & interruptMask;
DMAC->Channel[channel].CHINTENCLR.reg =
DMAC_CHINTENCLR_MASK & ~interruptMask;
DMAC->Channel[channel].CHCTRLA.bit.ENABLE = 1;
#else
DMAC->CHID.bit.ID = channel;
DMAC->CHINTENSET.reg = DMAC_CHINTENSET_MASK & interruptMask;
DMAC->CHINTENCLR.reg = DMAC_CHINTENCLR_MASK & ~interruptMask;
DMAC->CHCTRLA.bit.ENABLE = 1; // Enable the transfer channel
#endif
}
cpu_irq_leave_critical();
return status;
}
// Set and enable callback function for ZeroDMA object. This can be called
// before or after channel and/or descriptors are allocated, but needs
// to be called before job is started.
void Adafruit_ZeroDMA::setCallback(
void (*cb)(Adafruit_ZeroDMA *), dma_callback_type type) {
callback[type] = cb;
}
// Suspend/resume don't quite do what I thought -- avoid using for now.
void Adafruit_ZeroDMA::suspend(void) const {
cpu_irq_enter_critical();
#ifdef __SAMD51__
DMAC->Channel[channel].CHCTRLB.reg |= DMAC_CHCTRLB_CMD_SUSPEND;
#else
DMAC->CHID.bit.ID = channel;
DMAC->CHCTRLB.reg |= DMAC_CHCTRLB_CMD_SUSPEND;
#endif
cpu_irq_leave_critical();
}
#define MAX_JOB_RESUME_COUNT 10000
void Adafruit_ZeroDMA::resume(void) {
cpu_irq_enter_critical(); // jobStatus is volatile
if(jobStatus == DMA_STATUS_SUSPEND) {
int count;
uint32_t bitMask = 1 << channel;
#ifdef __SAMD51__
DMAC->Channel[channel].CHCTRLB.reg |= DMAC_CHCTRLB_CMD_RESUME;
#else
DMAC->CHID.bit.ID = channel;
DMAC->CHCTRLB.reg |= DMAC_CHCTRLB_CMD_RESUME;
#endif
for(count = 0; (count < MAX_JOB_RESUME_COUNT) &&
!(DMAC->BUSYCH.reg & bitMask); count++);
jobStatus = (count < MAX_JOB_RESUME_COUNT) ?
DMA_STATUS_BUSY : DMA_STATUS_ERR_TIMEOUT;
}
cpu_irq_leave_critical();
}
// Abort is OK though.
void Adafruit_ZeroDMA::abort(void) {
if(channel <= DMAC_CH_NUM) {
cpu_irq_enter_critical();
#ifdef __SAMD51__
DMAC->Channel[channel].CHCTRLA.reg = 0; // Disable channel
#else
DMAC->CHID.bit.ID = channel; // Select channel
DMAC->CHCTRLA.reg = 0; // Disable
#endif
jobStatus = DMA_STATUS_ABORTED;
cpu_irq_leave_critical();
}
}
// Set DMA peripheral trigger.
// This can be done before or after channel is allocated.
void Adafruit_ZeroDMA::setTrigger(uint8_t trigger) {
peripheralTrigger = trigger; // Save value for allocate()
// If channel already allocated, configure peripheral trigger
// (old lib required configure before alloc -- either way OK now)
if(channel < DMAC_CH_NUM) {
cpu_irq_enter_critical();
#ifdef __SAMD51__
DMAC->Channel[channel].CHCTRLA.bit.TRIGSRC = trigger;
#else
DMAC->CHID.bit.ID = channel;
DMAC->CHCTRLB.bit.TRIGSRC = trigger;
#endif
cpu_irq_leave_critical();
}
}
// Set DMA trigger action.
// This can be done before or after channel is allocated.
void Adafruit_ZeroDMA::setAction(dma_transfer_trigger_action action) {
triggerAction = action; // Save value for allocate()
// If channel already allocated, configure trigger action
// (old lib required configure before alloc -- either way OK now)
if(channel < DMAC_CH_NUM) {
cpu_irq_enter_critical();
#ifdef __SAMD51__
DMAC->Channel[channel].CHCTRLA.bit.TRIGACT = action;
#else
DMAC->CHID.bit.ID = channel;
DMAC->CHCTRLB.bit.TRIGACT = action;
#endif
cpu_irq_leave_critical();
}
}
// Issue software trigger. Channel must be allocated & descriptors added!
void Adafruit_ZeroDMA::trigger(void) const {
if((channel <= DMAC_CH_NUM) & hasDescriptors) {
DMAC->SWTRIGCTRL.reg |= (1 << channel);
}
}
// Returns true if DMA transfer in progress.
bool Adafruit_ZeroDMA::isActive(void) const {
return _writeback[channel].BTCTRL.bit.VALID;
}
// DMA DESCRIPTOR FUNCTIONS ------------------------------------------------
// Allocates a new DMA descriptor (if needed) and appends it to the
// channel's descriptor list. Returns pointer to DmacDescriptor,
// or NULL on various errors. You'll want to keep the pointer for
// later if you need to modify or free the descriptor.
// Channel must be allocated first!
DmacDescriptor *Adafruit_ZeroDMA::addDescriptor(
void *src,
void *dst,
uint32_t count,
dma_beat_size size,
bool srcInc,
bool dstInc,
uint32_t stepSize,
bool stepSel) {
// Channel must be allocated first
if(channel >= DMAC_CH_NUM) return NULL;
// Can't do while job's busy
if(jobStatus == DMA_STATUS_BUSY) return NULL;
DmacDescriptor *desc;
// Scan descriptor list to find last entry. If an entry's
// DESCADDR value is 0, that's the end of the list and it's
// currently un-looped. If the DESCADDR value is the same
// as the first entry, that's the end of the list and it's
// looped. Either way, set the last entry's DESCADDR value
// to the new descriptor, and the descriptor's own DESCADDR
// will be set later either to 0 or the list head.
if(hasDescriptors) {
// DMA descriptors must be 128-bit (16 byte) aligned.
// memalign() is considered 'obsolete' but it's replacements
// (aligned_alloc() or posix_memalign()) are not currently
// available in the version of ARM GCC in use, but this is,
// so here we are.
if(!(desc = (DmacDescriptor *)memalign(16, sizeof(DmacDescriptor)))) {
return NULL;
}
DmacDescriptor *prev = &_descriptor[channel];
while(prev->DESCADDR.reg &&
(prev->DESCADDR.reg != (uint32_t)&_descriptor[channel])) {
prev = (DmacDescriptor *)prev->DESCADDR.reg;
}
prev->DESCADDR.reg = (uint32_t)desc;
} else {
desc = &_descriptor[channel];
}
hasDescriptors = true;
uint8_t bytesPerBeat; // Beat transfer size IN BYTES
switch(size) {
default: bytesPerBeat = 1; break;
case DMA_BEAT_SIZE_HWORD: bytesPerBeat = 2; break;
case DMA_BEAT_SIZE_WORD: bytesPerBeat = 4; break;
}
desc->BTCTRL.bit.VALID = true;
desc->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_DISABLE;
desc->BTCTRL.bit.BLOCKACT = DMA_BLOCK_ACTION_NOACT;
desc->BTCTRL.bit.BEATSIZE = size;
desc->BTCTRL.bit.SRCINC = srcInc;
desc->BTCTRL.bit.DSTINC = dstInc;
desc->BTCTRL.bit.STEPSEL = stepSel;
desc->BTCTRL.bit.STEPSIZE = stepSize;
desc->BTCNT.reg = count;
desc->SRCADDR.reg = (uint32_t)src;
if(srcInc) {
if(stepSel) {
desc->SRCADDR.reg += bytesPerBeat * count * (1 << stepSize);
} else {
desc->SRCADDR.reg += bytesPerBeat * count;
}
}
desc->DSTADDR.reg = (uint32_t)dst;
if(dstInc) {
if(!stepSel) {
desc->DSTADDR.reg += bytesPerBeat * count * (1 << stepSize);
} else {
desc->DSTADDR.reg += bytesPerBeat * count;
}
}
desc->DESCADDR.reg = loopFlag ? (uint32_t)&_descriptor[channel] : 0;
return desc;
}
// Modify DMA descriptor with a new source address, destination address &
// block transfer count. All other attributes (including increment enables,
// etc.) are unchanged. Mostly for changing the data being pushed to a
// peripheral (DAC, SPI, whatev.)
void Adafruit_ZeroDMA::changeDescriptor(DmacDescriptor *desc,
void *src, void *dst, uint32_t count) {
uint8_t bytesPerBeat; // Beat transfer size IN BYTES
switch(desc->BTCTRL.bit.BEATSIZE) {
default: bytesPerBeat = 1; break;
case DMA_BEAT_SIZE_HWORD: bytesPerBeat = 2; break;
case DMA_BEAT_SIZE_WORD: bytesPerBeat = 4; break;
}
if(count) desc->BTCNT.reg = count;
if(src) {
desc->SRCADDR.reg = (uint32_t)src;
if(desc->BTCTRL.bit.SRCINC) {
if(desc->BTCTRL.bit.STEPSEL) {
desc->SRCADDR.reg += desc->BTCNT.reg *
bytesPerBeat * (1 << desc->BTCTRL.bit.STEPSIZE);
} else {
desc->SRCADDR.reg += desc->BTCNT.reg * bytesPerBeat;
}
}
}
if(dst) {
desc->DSTADDR.reg = (uint32_t)dst;
if(desc->BTCTRL.bit.DSTINC) {
if(!desc->BTCTRL.bit.STEPSEL) {
desc->DSTADDR.reg += desc->BTCNT.reg *
bytesPerBeat * (1 << desc->BTCTRL.bit.STEPSIZE);
} else {
desc->DSTADDR.reg += desc->BTCNT.reg * bytesPerBeat;
}
}
}
// I think this code is here by accident -- disabling for now.
#if 0
cpu_irq_enter_critical();
jobStatus = DMA_STATUS_OK;
#ifdef __SAMD51__
DMAC->Channel[channel].CHCTRLA.bit.ENABLE = 1;
#else
DMAC->CHID.bit.ID = channel;
DMAC->CHCTRLA.reg |= DMAC_CHCTRLA_ENABLE;
#endif
cpu_irq_leave_critical();
#endif
}
// TODO: delete descriptor, delete whole descriptor chain
// Select whether channel's descriptor list should repeat or not.
// This can be done before or after channel & any descriptors are allocated.
void Adafruit_ZeroDMA::loop(boolean flag) {
// The loop selection is 'sticky' -- that is, you can enable or
// disable looping before a descriptor list is built, or after
// the fact. This requires some extra steps in the library code
// but avoids a must-do-in-X-order constraint on user.
loopFlag = flag;
if(hasDescriptors) { // Descriptor list already started?
// Scan descriptor list to find last entry. If an entry's
// DESCADDR value is 0, that's the end of the list and it's
// currently un-looped. If the DESCADDR value is the same
// as the first entry, that's the end of the list and it's
// already looped.
DmacDescriptor *desc = &_descriptor[channel];
while(desc->DESCADDR.reg &&
(desc->DESCADDR.reg != (uint32_t)&_descriptor[channel])) {
desc = (DmacDescriptor *)desc->DESCADDR.reg;
}
// Loop or unloop descriptor list as appropriate
desc->DESCADDR.reg = loopFlag ? (uint32_t)&_descriptor[channel] : 0;
}
}
// MISCELLANY --------------------------------------------------------------
void Adafruit_ZeroDMA::printStatus(ZeroDMAstatus s) const {
if(s == DMA_STATUS_JOBSTATUS) s = jobStatus;
Serial.print("Status: ");
switch(s) {
case DMA_STATUS_OK:
Serial.println("OK");
break;
case DMA_STATUS_ERR_NOT_FOUND:
Serial.println("NOT FOUND");
break;
case DMA_STATUS_ERR_NOT_INITIALIZED:
Serial.println("NOT INITIALIZED");
break;
case DMA_STATUS_ERR_INVALID_ARG:
Serial.println("INVALID ARGUMENT");
break;
case DMA_STATUS_ERR_IO:
Serial.println("IO ERROR");
break;
case DMA_STATUS_ERR_TIMEOUT:
Serial.println("TIMEOUT");
break;
case DMA_STATUS_BUSY:
Serial.println("BUSY");
break;
case DMA_STATUS_SUSPEND:
Serial.println("SUSPENDED");
break;
case DMA_STATUS_ABORTED:
Serial.println("ABORTED");
break;
default:
Serial.print("Unknown 0x");
Serial.println((int)s);
break;
}
}

View file

@ -1,66 +0,0 @@
#ifndef _ADAFRUIT_ZERODMA_H_
#define _ADAFRUIT_ZERODMA_H_
#include "Arduino.h"
#include "utility/dma.h"
// Status codes returned by some DMA functions and/or held in
// a channel's jobStatus variable.
enum ZeroDMAstatus {
DMA_STATUS_OK = 0,
DMA_STATUS_ERR_NOT_FOUND,
DMA_STATUS_ERR_NOT_INITIALIZED,
DMA_STATUS_ERR_INVALID_ARG,
DMA_STATUS_ERR_IO,
DMA_STATUS_ERR_TIMEOUT,
DMA_STATUS_BUSY,
DMA_STATUS_SUSPEND,
DMA_STATUS_ABORTED,
DMA_STATUS_JOBSTATUS = -1 // For printStatus() function
};
class Adafruit_ZeroDMA {
public:
Adafruit_ZeroDMA(void);
// DMA channel functions
ZeroDMAstatus allocate(void), // Allocates DMA channel
startJob(void),
free(void); // Deallocates DMA channel
void trigger(void) const,
setTrigger(uint8_t trigger),
setAction(dma_transfer_trigger_action action),
setCallback(void (*callback)(Adafruit_ZeroDMA *) = NULL,
dma_callback_type type = DMA_CALLBACK_TRANSFER_DONE),
loop(boolean flag),
suspend(void) const,
resume(void),
abort(void),
setPriority(dma_priority pri) const,
printStatus(ZeroDMAstatus s = DMA_STATUS_JOBSTATUS) const;
uint8_t getChannel(void) const { return channel; }
// DMA descriptor functions
DmacDescriptor *addDescriptor(void *src, void *dst, uint32_t count = 0,
dma_beat_size size = DMA_BEAT_SIZE_BYTE,
bool srcInc = true, bool dstInc = true,
uint32_t stepSize = DMA_ADDRESS_INCREMENT_STEP_SIZE_1,
bool stepSel = DMA_STEPSEL_DST);
void changeDescriptor(DmacDescriptor *d, void *src = NULL,
void *dst = NULL, uint32_t count = 0);
bool isActive(void) const;
void _IRQhandler(uint8_t flags); // DO NOT TOUCH
protected:
uint8_t channel;
volatile enum ZeroDMAstatus jobStatus;
bool hasDescriptors;
bool loopFlag;
uint8_t peripheralTrigger;
dma_transfer_trigger_action triggerAction;
void (*callback[DMA_CALLBACK_N])(Adafruit_ZeroDMA *);
};
#endif // _ADAFRUIT_ZERODMA_H_

View file

@ -1,22 +0,0 @@
The MIT License (MIT)
Copyright (c) 2016 Adafruit Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,6 +0,0 @@
# Adafruit_ZeroDMA
DMA helper/wrapped for ATSAMD21 such as Arduino Zero &amp; Feather M0
Current version of this library no longer requires Adafruit_ASFcore as a prerequisite. However...IT BREAKS COMPATIBILITY WITH PRIOR VERSIONS. Function names, calling sequence and return types/values have changed. See examples!
Item(s) in 'utility' directory are much pared-down derivatives of Atmel ASFcore 3 files. Please keep their original copyright and license intact when editing.

View file

@ -1,95 +0,0 @@
// Simple ZeroDMA example -- an equivalent to the memcpy() function.
// Decause it uses DMA, unlike memcpy(), your code could be doing other
// things simultaneously while the copy operation runs.
#include <Adafruit_ZeroDMA.h>
#include "utility/dma.h"
Adafruit_ZeroDMA myDMA;
ZeroDMAstatus stat; // DMA status codes returned by some functions
// The memory we'll be moving:
#define DATA_LENGTH 1024
uint8_t source_memory[DATA_LENGTH],
destination_memory[DATA_LENGTH];
volatile bool transfer_is_done = false; // Done yet?
// Callback for end-of-DMA-transfer
void dma_callback(Adafruit_ZeroDMA *dma) {
(void)dma; // avoid compiler warning about unused function parameter
transfer_is_done = true;
}
void setup() {
uint32_t t;
pinMode(LED_BUILTIN, OUTPUT); // Onboard LED can be used for precise
digitalWrite(LED_BUILTIN, LOW); // benchmarking with an oscilloscope
Serial.begin(115200);
while(!Serial); // Wait for Serial monitor before continuing
Serial.println("DMA test: memory copy");
Serial.print("Allocating DMA channel...");
stat = myDMA.allocate();
myDMA.printStatus(stat);
Serial.println("Setting up transfer");
myDMA.addDescriptor(source_memory, destination_memory, DATA_LENGTH);
Serial.println("Adding callback");
// register_callback() can optionally take a second argument
// (callback type), default is DMA_CALLBACK_TRANSFER_DONE
myDMA.setCallback(dma_callback);
// Fill the source buffer with incrementing bytes, dest buf with 0's
for(uint32_t i=0; i<DATA_LENGTH; i++) source_memory[i] = i;
memset(destination_memory, 0, DATA_LENGTH);
// Show the destination buffer is empty before transfer
Serial.println("Destination buffer before transfer:");
dump();
Serial.println("Starting transfer job");
stat = myDMA.startJob();
myDMA.printStatus(stat);
Serial.println("Triggering DMA transfer...");
t = micros();
digitalWrite(LED_BUILTIN, HIGH);
myDMA.trigger();
// Your code could do other things here while copy happens!
while(!transfer_is_done); // Chill until DMA transfer completes
digitalWrite(LED_BUILTIN, LOW);
t = micros() - t; // Elapsed time
Serial.print("Done! ");
Serial.print(t);
Serial.println(" microseconds");
Serial.println("Destination buffer after transfer:");
dump();
// Now repeat the same operation, but 'manually' using memcpy() (not DMA):
t = micros();
digitalWrite(LED_BUILTIN, HIGH);
memcpy(destination_memory, source_memory, DATA_LENGTH);
digitalWrite(LED_BUILTIN, LOW);
t = micros() - t; // Elapsed time
Serial.print("Same operation without DMA: ");
Serial.print(t);
Serial.println(" microseconds");
}
// Show contents of destination_memory[] array
void dump() {
for(uint32_t i=0; i<DATA_LENGTH; i++) {
Serial.print(destination_memory[i], HEX); Serial.print(' ');
if ((i & 15) == 15) Serial.println();
}
}
void loop() { }

View file

@ -1,98 +0,0 @@
// DMA-based SPI buffer write. This is transmit-only as written, i.e.
// not equivalent to Arduino's SPI.transfer() which both sends and
// receives a single byte or word. Also, this is single-buffered to
// demonstrate a simple SPI write case. See zerodma_spi2.ino for an
// example using double buffering (2 buffers alternating fill & transmit).
#include <SPI.h>
#include <Adafruit_ZeroDMA.h>
#include "utility/dma.h"
Adafruit_ZeroDMA myDMA;
ZeroDMAstatus stat; // DMA status codes returned by some functions
// The memory we'll be issuing to SPI:
#define DATA_LENGTH 2048
uint8_t source_memory[DATA_LENGTH];
volatile bool transfer_is_done = false; // Done yet?
// Callback for end-of-DMA-transfer
void dma_callback(Adafruit_ZeroDMA *dma) {
(void)dma; // avoid compiler warning about unused parameter
transfer_is_done = true;
}
void setup() {
uint32_t t;
pinMode(LED_BUILTIN, OUTPUT); // Onboard LED can be used for precise
digitalWrite(LED_BUILTIN, LOW); // benchmarking with an oscilloscope
Serial.begin(115200);
while(!Serial); // Wait for Serial monitor before continuing
Serial.println("DMA test: SPI data out");
SPI.begin();
Serial.println("Configuring DMA trigger");
#ifdef __SAMD51__
// SERCOM2 is the 'native' SPI SERCOM on Metro M4
myDMA.setTrigger(SERCOM2_DMAC_ID_TX);
#else
// SERCOM4 is the 'native' SPI SERCOM on most M0 boards
myDMA.setTrigger(SERCOM4_DMAC_ID_TX);
#endif
myDMA.setAction(DMA_TRIGGER_ACTON_BEAT);
Serial.print("Allocating DMA channel...");
stat = myDMA.allocate();
myDMA.printStatus(stat);
Serial.println("Setting up transfer");
myDMA.addDescriptor(
source_memory, // move data from here
#ifdef __SAMD51__
(void *)(&SERCOM2->SPI.DATA.reg), // to here (M4)
#else
(void *)(&SERCOM4->SPI.DATA.reg), // to here (M0)
#endif
DATA_LENGTH, // this many...
DMA_BEAT_SIZE_BYTE, // bytes/hword/words
true, // increment source addr?
false); // increment dest addr?
Serial.println("Adding callback");
// register_callback() can optionally take a second argument
// (callback type), default is DMA_CALLBACK_TRANSFER_DONE
myDMA.setCallback(dma_callback);
// Fill the source buffer with incrementing bytes
for(uint32_t i=0; i<DATA_LENGTH; i++) source_memory[i] = i;
// Start SPI transaction at 12 MHz
SPI.beginTransaction(SPISettings(12000000, MSBFIRST, SPI_MODE0));
Serial.println("Starting transfer job");
t = micros();
digitalWrite(LED_BUILTIN, HIGH);
// Because we've configured a peripheral trigger (SPI), there's
// no need to manually trigger transfer, it starts up on its own.
stat = myDMA.startJob();
// Your code could do other things here while SPI write happens!
while(!transfer_is_done); // Chill until DMA transfer completes
digitalWrite(LED_BUILTIN, LOW);
t = micros() - t; // Elapsed time
SPI.endTransaction();
myDMA.printStatus(stat); // Results of start_transfer_job()
Serial.print("Done! ");
Serial.print(t);
Serial.println(" microseconds");
}
void loop() { }

View file

@ -1,104 +0,0 @@
// Double-buffered DMA on auxiliary SPI peripheral on pins 11/12/13.
// Continuously alternates between two data buffers...one is filled
// with new data as the other is being transmitted.
#include <SPI.h>
#include <Adafruit_ZeroDMA.h>
#include "utility/dma.h"
#include "wiring_private.h" // pinPeripheral() function
// Declare our own SPI peripheral 'mySPI' on pins 11/12/13:
// (Do not call this SPI1; Arduino Zero and Metro M0 already
// have an SPI1 (the EDBG interface) and it won't compile.)
SPIClass mySPI(
&sercom1, // -> Sercom peripheral
34, // MISO pin (also digital pin 12)
37, // SCK pin (also digital pin 13)
35, // MOSI pin (also digital pin 11)
SPI_PAD_0_SCK_1, // TX pad (MOSI, SCK pads)
SERCOM_RX_PAD_3); // RX pad (MISO pad)
Adafruit_ZeroDMA myDMA;
ZeroDMAstatus stat; // DMA status codes returned by some functions
// Data we'll issue to mySPI. There are TWO buffers; one being
// filled with new data while the other's being transmitted in
// the background.
#define DATA_LENGTH 512
uint8_t source_memory[2][DATA_LENGTH],
buffer_being_filled = 0, // Index of 'filling' buffer
buffer_value = 0; // Value of fill
volatile bool transfer_is_done = true; // Done yet?
// Callback for end-of-DMA-transfer
void dma_callback(Adafruit_ZeroDMA *dma) {
(void)dma; // avoid compiler warning about unused parameter
transfer_is_done = true;
}
DmacDescriptor *desc; // DMA descriptor address (so we can change contents)
void setup() {
Serial.begin(115200);
while(!Serial); // Wait for Serial monitor before continuing
Serial.println("DMA test: SPI data out");
mySPI.begin();
// Assign pins 11, 12, 13 to SERCOM functionality
pinPeripheral(11, PIO_SERCOM);
pinPeripheral(12, PIO_SERCOM);
pinPeripheral(13, PIO_SERCOM);
// Configure DMA for SERCOM1 (our 'mySPI' port on 11/12/13)
Serial.println("Configuring DMA trigger");
myDMA.setTrigger(SERCOM1_DMAC_ID_TX);
myDMA.setAction(DMA_TRIGGER_ACTON_BEAT);
Serial.print("Allocating DMA channel...");
stat = myDMA.allocate();
myDMA.printStatus(stat);
desc = myDMA.addDescriptor(
source_memory[buffer_being_filled], // move data from here
(void *)(&SERCOM1->SPI.DATA.reg), // to here
DATA_LENGTH, // this many...
DMA_BEAT_SIZE_BYTE, // bytes/hword/words
true, // increment source addr?
false); // increment dest addr?
Serial.println("Adding callback");
// register_callback() can optionally take a second argument
// (callback type), default is DMA_CALLBACK_TRANSFER_DONE
myDMA.setCallback(dma_callback);
}
void loop() {
// Fill buffer with new data. The other buffer might
// still be transmitting in the background via DMA.
memset(source_memory[buffer_being_filled], buffer_value, DATA_LENGTH);
// Wait for prior transfer to complete before starting new one...
Serial.print("Waiting on prior transfer...");
while(!transfer_is_done) Serial.write('.');
mySPI.endTransaction();
Serial.println("Done!");
// Modify the DMA descriptor using the newly-filled buffer as source...
myDMA.changeDescriptor(desc, // DMA descriptor address
source_memory[buffer_being_filled]); // New src; dst & count don't change
// Begin new transfer...
Serial.println("Starting new transfer job");
mySPI.beginTransaction(SPISettings(12000000, MSBFIRST, SPI_MODE0));
transfer_is_done = false; // Reset 'done' flag
stat = myDMA.startJob(); // Go!
myDMA.printStatus(stat);
// Switch buffer indices so the alternate buffer is filled/xfer'd
// on the next pass.
buffer_being_filled = 1 - buffer_being_filled;
buffer_value++;
}

View file

@ -1,9 +0,0 @@
name=Adafruit Zero DMA Library
version=1.0.4
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=DMA helper/wrapped for ATSAMD21 such as Arduino Zero & Feather M0
paragraph=DMA helper/wrapped for ATSAMD21 such as Arduino Zero & Feather M0
category=Signal Input/Output
url=https://github.com/adafruit/Adafruit_ZeroDMA
architectures=samd

View file

@ -1,145 +0,0 @@
/**
* \file
*
* \brief SAM Direct Memory Access Controller Driver
*
* Copyright (C) 2014-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef DMA_H_INCLUDED
#define DMA_H_INCLUDED
// THIS IS A PARED-DOWN VERSION OF DMA.H FROM ATMEL ASFCORE 3.
// Please keep original copyright and license intact!
#ifdef __cplusplus
extern "C" {
#endif
#if (SAML21) || (SAML22) || (SAMC20) || (SAMC21) || defined(__DOXYGEN__) || defined(__SAMD51__)
#define FEATURE_DMA_CHANNEL_STANDBY
#endif
enum dma_transfer_trigger_action{
#ifdef __SAMD51__
// SAMD51 has a 'burst' transfer which can be set to one
// beat to accomplish same idea as SAMD21's 'beat' transfer.
// Trigger name is ACTON_BEAT for backward compatibility.
DMA_TRIGGER_ACTON_BLOCK = DMAC_CHCTRLA_TRIGACT_BLOCK_Val,
DMA_TRIGGER_ACTON_BEAT = DMAC_CHCTRLA_TRIGACT_BURST_Val,
DMA_TRIGGER_ACTON_TRANSACTION = DMAC_CHCTRLA_TRIGACT_TRANSACTION_Val,
#else
DMA_TRIGGER_ACTON_BLOCK = DMAC_CHCTRLB_TRIGACT_BLOCK_Val,
DMA_TRIGGER_ACTON_BEAT = DMAC_CHCTRLB_TRIGACT_BEAT_Val,
DMA_TRIGGER_ACTON_TRANSACTION = DMAC_CHCTRLB_TRIGACT_TRANSACTION_Val,
#endif
};
enum dma_callback_type {
// First item here is for any transfer errors. A transfer error is
// flagged if a bus error is detected during an AHB access or when
// the DMAC fetches an invalid descriptor
DMA_CALLBACK_TRANSFER_ERROR,
DMA_CALLBACK_TRANSFER_DONE,
DMA_CALLBACK_CHANNEL_SUSPEND,
DMA_CALLBACK_N, // Number of available callbacks
};
enum dma_beat_size {
DMA_BEAT_SIZE_BYTE = 0, // 8-bit
DMA_BEAT_SIZE_HWORD, // 16-bit
DMA_BEAT_SIZE_WORD, // 32-bit
};
enum dma_event_output_selection {
DMA_EVENT_OUTPUT_DISABLE = 0, // Disable event generation
DMA_EVENT_OUTPUT_BLOCK, // Event strobe when block xfer complete
DMA_EVENT_OUTPUT_RESERVED,
DMA_EVENT_OUTPUT_BEAT, // Event strobe when beat xfer complete
};
enum dma_block_action {
DMA_BLOCK_ACTION_NOACT = 0,
// Channel in normal operation and sets transfer complete interrupt
// flag after block transfer
DMA_BLOCK_ACTION_INT,
// Trigger channel suspend after block transfer and sets channel
// suspend interrupt flag once the channel is suspended
DMA_BLOCK_ACTION_SUSPEND,
// Sets transfer complete interrupt flag after a block transfer and
// trigger channel suspend. The channel suspend interrupt flag will
// be set once the channel is suspended.
DMA_BLOCK_ACTION_BOTH,
};
// DMA step selection. This bit determines whether the step size setting
// is applied to source or destination address.
enum dma_step_selection {
DMA_STEPSEL_DST = 0,
DMA_STEPSEL_SRC,
};
// Address increment step size. These bits select the address increment step
// size. The setting apply to source or destination address, depending on
// STEPSEL setting.
enum dma_address_increment_stepsize {
DMA_ADDRESS_INCREMENT_STEP_SIZE_1 = 0, // beat size * 1
DMA_ADDRESS_INCREMENT_STEP_SIZE_2, // beat size * 2
DMA_ADDRESS_INCREMENT_STEP_SIZE_4, // beat size * 4
DMA_ADDRESS_INCREMENT_STEP_SIZE_8, // etc...
DMA_ADDRESS_INCREMENT_STEP_SIZE_16,
DMA_ADDRESS_INCREMENT_STEP_SIZE_32,
DMA_ADDRESS_INCREMENT_STEP_SIZE_64,
DMA_ADDRESS_INCREMENT_STEP_SIZE_128,
};
// higher numbers are higher priority
enum dma_priority {
DMA_PRIORITY_0, // lowest (default)
DMA_PRIORITY_1,
DMA_PRIORITY_2,
DMA_PRIORITY_3, // highest
};
#ifdef __cplusplus
}
#endif
#endif // DMA_H_INCLUDED

View file

@ -37,6 +37,12 @@ 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,6 +19,11 @@
#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

@ -22,6 +22,11 @@
#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
@ -332,20 +337,16 @@ void SPIClass::dmaAllocate(void) {
totalDescriptors * sizeof(DmacDescriptor)))) { totalDescriptors * sizeof(DmacDescriptor)))) {
use_dma = true; // Everything allocated successfully use_dma = true; // Everything allocated successfully
extraWriteDescriptors = &extraReadDescriptors[numReadDescriptors]; extraWriteDescriptors = &extraReadDescriptors[numReadDescriptors];
// Initialize descriptors (copy from first ones) // 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++) { for(int i=0; i<numReadDescriptors; i++) {
#pragma GCC diagnostic push memcpy((void*) &extraReadDescriptors[i], firstReadDescriptor,
#pragma GCC diagnostic ignored "-Wclass-memaccess"
memcpy(&extraReadDescriptors[i], firstReadDescriptor,
sizeof(DmacDescriptor)); sizeof(DmacDescriptor));
#pragma GCC diagnostic pop
} }
for(int i=0; i<numWriteDescriptors; i++) { for(int i=0; i<numWriteDescriptors; i++) {
#pragma GCC diagnostic push memcpy((void*) &extraWriteDescriptors[i], firstWriteDescriptor,
#pragma GCC diagnostic ignored "-Wclass-memaccess"
memcpy(&extraWriteDescriptors[i], firstWriteDescriptor,
sizeof(DmacDescriptor)); sizeof(DmacDescriptor));
#pragma GCC diagnostic pop
} }
} // end malloc } // end malloc
} // end extra descriptor check } // end extra descriptor check

View file

@ -21,6 +21,11 @@
#include <Arduino.h> #include <Arduino.h>
#include <Servo.h> #include <Servo.h>
#ifdef USE_TINYUSB
// For Serial when selecting TinyUSB
#include <Adafruit_TinyUSB.h>
#endif
#if defined(__SAMD51__) #if defined(__SAMD51__)
// Different prescalers depending on FCPU (avoid overflowing 16-bit counter) // Different prescalers depending on FCPU (avoid overflowing 16-bit counter)
#if(F_CPU > 200000000) #if(F_CPU > 200000000)

View file

@ -216,6 +216,7 @@ byte getconfdescr( byte addr, byte conf )
uint16_t total_length; uint16_t total_length;
// FIXME -- no check of return code from usb.getConfDescr() // FIXME -- no check of return code from usb.getConfDescr()
rcode = usb.getConfDescr( addr, 0, 4, conf, buf ); //get total length rcode = usb.getConfDescr( addr, 0, 4, conf, buf ); //get total length
(void) rcode;
LOBYTE( total_length ) = buf[ 2 ]; LOBYTE( total_length ) = buf[ 2 ];
HIBYTE( total_length ) = buf[ 3 ]; HIBYTE( total_length ) = buf[ 3 ];
if( total_length > sizeof(buf)) { //check if total length is larger than buffer if( total_length > sizeof(buf)) { //check if total length is larger than buffer
@ -224,6 +225,7 @@ byte getconfdescr( byte addr, byte conf )
} }
// FIXME -- no check of return code from usb.getConfDescr() // FIXME -- no check of return code from usb.getConfDescr()
rcode = usb.getConfDescr( addr, 0, total_length, conf, buf ); //get the whole descriptor rcode = usb.getConfDescr( addr, 0, total_length, conf, buf ); //get the whole descriptor
(void) rcode;
while( buf_ptr < buf + total_length ) { //parsing descriptors while( buf_ptr < buf + total_length ) { //parsing descriptors
descr_length = *( buf_ptr ); descr_length = *( buf_ptr );
descr_type = *( buf_ptr + 1 ); descr_type = *( buf_ptr + 1 );

View file

@ -24,6 +24,11 @@ extern "C" {
#include <Arduino.h> #include <Arduino.h>
#include <wiring_private.h> #include <wiring_private.h>
#ifdef USE_TINYUSB
// For Serial when selecting TinyUSB
#include <Adafruit_TinyUSB.h>
#endif
#include "Wire.h" #include "Wire.h"
TwoWire::TwoWire(SERCOM * s, uint8_t pinSDA, uint8_t pinSCL) TwoWire::TwoWire(SERCOM * s, uint8_t pinSDA, uint8_t pinSCL)

View file

@ -17,19 +17,19 @@
# Arduino SAMD Core and platform. # Arduino SAMD Core and platform.
# #
# For more info: # For more info:
# https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification # https://arduino.github.io/arduino-cli/0.33/platform-specification/
name=Adafruit SAMD (32-bits ARM Cortex-M0+ and Cortex-M4) Boards name=Adafruit SAMD (32-bits ARM Cortex-M0+ and Cortex-M4) Boards
version=1.6.8 version=1.7.16
# Compile variables # Compile variables
# ----------------- # -----------------
compiler.warning_flags=-w compiler.warning_flags=-Werror=return-type
compiler.warning_flags.none=-w compiler.warning_flags.none=-Werror=return-type
compiler.warning_flags.default= compiler.warning_flags.default=-Werror=return-type
compiler.warning_flags.more=-Wall -Wno-expansion-to-defined compiler.warning_flags.more=-Wall -Werror=return-type -Wno-expansion-to-defined
compiler.warning_flags.all=-Wall -Wextra -Wno-expansion-to-defined compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-expansion-to-defined
compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/ compiler.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
compiler.c.cmd=arm-none-eabi-gcc compiler.c.cmd=arm-none-eabi-gcc
@ -70,14 +70,14 @@ compiler.S.extra_flags=
compiler.ar.extra_flags= compiler.ar.extra_flags=
compiler.elf2hex.extra_flags= compiler.elf2hex.extra_flags=
compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/DSP/Include/" "-I{runtime.tools.CMSIS-Atmel-1.2.1.path}/CMSIS/Device/ATMEL/" compiler.arm.cmsis.c.flags="-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Core/Include/" "-I{runtime.tools.CMSIS-5.4.0.path}/CMSIS/DSP/Include/" "-I{runtime.tools.CMSIS-Atmel-1.2.2.path}/CMSIS/Device/ATMEL/"
compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" -larm_cortexM0l_math compiler.arm.cmsis.ldflags="-L{runtime.tools.CMSIS-5.4.0.path}/CMSIS/Lib/GCC/" -larm_cortexM0l_math
compiler.libraries.ldflags= compiler.libraries.ldflags=
# USB Flags # USB Flags
# --------- # ---------
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON -DUSB_CONFIG_POWER={build.usb_power} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {build.flags.usbstack} {build.flags.debug} "-I{build.core.path}/TinyUSB" "-I{build.core.path}/TinyUSB/Adafruit_TinyUSB_ArduinoCore" "-I{build.core.path}/TinyUSB/Adafruit_TinyUSB_ArduinoCore/tinyusb/src" build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} -DUSBCON -DUSB_CONFIG_POWER={build.usb_power} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {build.flags.usbstack} {build.flags.debug} "-I{runtime.platform.path}/libraries/Adafruit_TinyUSB_Arduino/src/arduino"
# Default advertised device power setting in mA # Default advertised device power setting in mA
build.usb_power=100 build.usb_power=100
@ -91,13 +91,13 @@ build.usb_manufacturer="Unknown"
# ---------------- # ----------------
## Compile c files ## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.cache_flags} {build.flags.debug} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_SAMD_ADAFRUIT {compiler.c.extra_flags} {build.extra_flags} {build.cache_flags} {build.flags.debug} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files ## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.cache_flags} {build.flags.debug} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_SAMD_ADAFRUIT {compiler.cpp.extra_flags} {build.extra_flags} {build.cache_flags} {build.flags.debug} {build.flags.optimize} {build.flags.maxspi} {build.flags.maxqspi} {build.extra_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
## Compile S files ## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.cache_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}" recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_SAMD_ADAFRUIT {compiler.S.extra_flags} {build.extra_flags} {build.cache_flags} {compiler.arm.cmsis.c.flags} {includes} "{source_file}" -o "{object_file}"
## Create archives ## Create archives
# archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value # archive_file_path is needed for backwards compatibility with IDE 1.6.5 or older, IDE 1.6.6 or newer overrides this value
@ -143,6 +143,7 @@ tools.bossac.upload.network_pattern="{network_cmd}" -address {serial.port} -port
tools.bossac18.path={runtime.tools.bossac-1.8.0-48-gb176eee.path} tools.bossac18.path={runtime.tools.bossac-1.8.0-48-gb176eee.path}
tools.bossac18.cmd=bossac tools.bossac18.cmd=bossac
tools.bossac18.cmd.windows=bossac.exe
tools.bossac18.upload.params.verbose=-i -d tools.bossac18.upload.params.verbose=-i -d
tools.bossac18.upload.params.quiet= tools.bossac18.upload.params.quiet=
@ -172,13 +173,13 @@ tools.bossacI.upload.network_pattern="{network_cmd}" -address {serial.port} -por
# OpenOCD sketch upload # OpenOCD sketch upload
# #
tools.openocd.path={runtime.tools.openocd-0.10.0-arduino7.path} tools.openocd.path={runtime.tools.openocd-0.11.0-arduino2.path}
tools.openocd.cmd=bin/openocd tools.openocd.cmd=bin/openocd
tools.openocd.cmd.windows=bin/openocd.exe tools.openocd.cmd.windows=bin/openocd.exe
tools.openocd.upload.params.verbose=-d2 tools.openocd.upload.params.verbose=-d2
tools.openocd.upload.params.quiet=-d0 tools.openocd.upload.params.quiet=-d0
tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset 0x2000; shutdown" tools.openocd.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset 0x2000; shutdown"
tools.openocd.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA tools.openocd.network_cmd={runtime.tools.arduinoOTA.path}/bin/arduinoOTA
tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port 65280 -username arduino -password "{network.password}" -sketch "{build.path}/{build.project_name}.bin" -upload /sketch -b
@ -186,7 +187,7 @@ tools.openocd.upload.network_pattern={network_cmd} -address {serial.port} -port
# Program flashes the binary at 0x0000, so use the linker script without_bootloader # Program flashes the binary at 0x0000, so use the linker script without_bootloader
tools.openocd.program.params.verbose=-d2 tools.openocd.program.params.verbose=-d2
tools.openocd.program.params.quiet=-d0 tools.openocd.program.params.quiet=-d0
tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown" tools.openocd.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown"
tools.openocd.erase.params.verbose=-d3 tools.openocd.erase.params.verbose=-d3
tools.openocd.erase.params.quiet=-d0 tools.openocd.erase.params.quiet=-d0
@ -194,25 +195,25 @@ tools.openocd.erase.pattern=
tools.openocd.bootloader.params.verbose=-d2 tools.openocd.bootloader.params.verbose=-d2
tools.openocd.bootloader.params.quiet=-d0 tools.openocd.bootloader.params.quiet=-d0
tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown" tools.openocd.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; init; halt; $_FLASHDRIVER bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown"
# #
# OpenOCD sketch upload - version with configurable bootloader size # OpenOCD sketch upload - version with configurable bootloader size
# FIXME: this programmer is a workaround for default options being overwritten by uploadUsingPreferences # FIXME: this programmer is a workaround for default options being overwritten by uploadUsingPreferences
# #
tools.openocd-withbootsize.path={runtime.tools.openocd-0.10.0-arduino7.path} tools.openocd-withbootsize.path={runtime.tools.openocd-0.11.0-arduino2.path}
tools.openocd-withbootsize.cmd=bin/openocd tools.openocd-withbootsize.cmd=bin/openocd
tools.openocd-withbootsize.cmd.windows=bin/openocd.exe tools.openocd-withbootsize.cmd.windows=bin/openocd.exe
tools.openocd-withbootsize.upload.params.verbose=-d2 tools.openocd-withbootsize.upload.params.verbose=-d2
tools.openocd-withbootsize.upload.params.quiet=-d0 tools.openocd-withbootsize.upload.params.quiet=-d0
tools.openocd-withbootsize.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset {bootloader.size}; shutdown" tools.openocd-withbootsize.upload.pattern="{path}/{cmd}" {upload.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.bin} verify reset {bootloader.size}; shutdown"
# Program flashes the binary at 0x0000, so use the linker script without_bootloader # Program flashes the binary at 0x0000, so use the linker script without_bootloader
tools.openocd-withbootsize.program.params.verbose=-d2 tools.openocd-withbootsize.program.params.verbose=-d2
tools.openocd-withbootsize.program.params.quiet=-d0 tools.openocd-withbootsize.program.params.quiet=-d0
tools.openocd-withbootsize.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown" tools.openocd-withbootsize.program.pattern="{path}/{cmd}" {program.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; program {{build.path}/{build.project_name}.elf} verify reset; shutdown"
tools.openocd-withbootsize.erase.params.verbose=-d3 tools.openocd-withbootsize.erase.params.verbose=-d3
tools.openocd-withbootsize.erase.params.quiet=-d0 tools.openocd-withbootsize.erase.params.quiet=-d0
@ -220,4 +221,28 @@ tools.openocd-withbootsize.erase.pattern=
tools.openocd-withbootsize.bootloader.params.verbose=-d2 tools.openocd-withbootsize.bootloader.params.verbose=-d2
tools.openocd-withbootsize.bootloader.params.quiet=-d0 tools.openocd-withbootsize.bootloader.params.quiet=-d0
tools.openocd-withbootsize.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/variants/{build.variant}/{build.openocdscript}" -c "telnet_port disabled; init; halt; at91samd bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown" tools.openocd-withbootsize.bootloader.pattern="{path}/{cmd}" {bootloader.verbose} -s "{path}/share/openocd/scripts/" -f "{runtime.platform.path}/{build.openocdscript}" -c "telnet_port disabled; init; halt; $_FLASHDRIVER bootloader 0; program {{runtime.platform.path}/bootloaders/{bootloader.file}} verify reset; shutdown"
# ----------------------------------------
# Debugger configuration (general options)
# ----------------------------------------
# EXPERIMENTAL feature:
# - this is alpha and may be subject to change without notice
debug.executable={build.path}/{build.project_name}.elf
debug.toolchain=gcc
debug.toolchain.path={runtime.tools.arm-none-eabi-gcc.path}/bin/
debug.toolchain.prefix=arm-none-eabi-
debug.server=openocd
debug.server.openocd.path={runtime.tools.openocd-0.11.0-arduino2.path}/bin/openocd
debug.server.openocd.scripts_dir={runtime.tools.openocd-0.11.0-arduino2.path}/share/openocd/scripts/
debug.server.openocd.script={runtime.platform.path}/{build.openocdscript}
# JLinkServer is not supported by arduino-cli yet
# https://github.com/arduino/arduino-cli/blob/eca9d9a8f00582a08fadea8a4b7e3ef01b40d082/commands/debug/debug.go#L160
# use debug_custom.json to run JLinkGDBServer instead
# https://docs.arduino.cc/tutorials/mkr-wifi-1010/mkr-jlink-setup
#debug.server=jlink
#debug.server.jlink.path=JLinkGDBServer
#debug.server.jlink.device=ATSAMD21G18
#debug.server.jlink.script={runtime.platform.path}/{build.openocdscript}

View file

@ -0,0 +1,6 @@
{
"servertype": "jlink",
"device": "ATSAMD21G18A",
"interface": "SWD",
"serverpath": "JLinkGDBServer"
}

View file

@ -0,0 +1,6 @@
{
"servertype": "jlink",
"device": "ATSAMD51G18",
"interface": "SWD",
"serverpath": "JLinkGDBServer"
}

View file

@ -0,0 +1,29 @@
#
# Arduino Zero OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
source [find interface/cmsis-dap.cfg]
transport select swd
# chip name
set CHIPNAME samd21
set _FLASHDRIVER at91samd
source [find target/at91samdXX.cfg]

View file

@ -0,0 +1,29 @@
#
# Arduino Zero OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
source [find interface/cmsis-dap.cfg]
transport select swd
# chip name
set CHIPNAME samd51
set _FLASHDRIVER atsame5
source [find target/atsame5x.cfg]

View file

@ -0,0 +1,29 @@
#
# Arduino Zero OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
source [find interface/jlink.cfg]
transport select swd
# chip name
set CHIPNAME samd21
set _FLASHDRIVER at91samd
source [find target/at91samdXX.cfg]

View file

@ -0,0 +1,29 @@
#
# Arduino Zero OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
source [find interface/jlink.cfg]
transport select swd
# chip name
set CHIPNAME samd51
set _FLASHDRIVER atsame5
source [find target/atsame5x.cfg]

106
tools/build_all.py Normal file
View file

@ -0,0 +1,106 @@
import os
import glob
import sys
import subprocess
from subprocess import Popen, PIPE
import time
SUCCEEDED = "\033[32msucceeded\033[0m"
FAILED = "\033[31mfailed\033[0m"
SKIPPED = "\033[35mskipped\033[0m"
WARNING = "\033[33mwarnings\033[0m "
exit_status = 0
success_count = 0
fail_count = 0
skip_count = 0
build_format = '| {:25} | {:35} | {:18} | {:6} |'
build_separator = '-' * 88
FQBN_PREFIX='adafruit:samd:adafruit_'
#default_boards = [ 'metro_m0', 'metro_m4', 'circuitplayground_m0', 'feather_m4_can', 'metro_m0:usbstack=tinyusb', 'metro_m4:speed=120,usbstack=tinyusb' ]
default_boards = [ 'metro_m0', 'metro_m0:usbstack=tinyusb' ]
build_boards = []
# build all variants if input not existed
if len(sys.argv) > 1:
build_boards.append(sys.argv[1])
else:
build_boards = default_boards
all_examples = list(glob.iglob('libraries/**/*.ino', recursive=True))
all_examples.sort()
def build_examples(variant):
global exit_status, success_count, fail_count, skip_count, build_format, build_separator
print('\n')
print(build_separator)
print('| {:^84} |'.format('Board ' + variant))
print(build_separator)
print(build_format.format('Library', 'Example', '\033[39mResult\033[0m', 'Time'))
print(build_separator)
fqbn = "{}{}".format(FQBN_PREFIX, variant)
for sketch in all_examples:
start_time = time.monotonic()
# Skip if contains: ".board.test.skip" or ".all.test.skip"
# Skip if not contains: ".board.test.only" for a specific board
sketchdir = os.path.dirname(sketch)
if os.path.exists(sketchdir + '/.all.test.skip') or os.path.exists(sketchdir + '/.' + variant + '.test.skip'):
success = SKIPPED
skip_count += 1
elif glob.glob(sketchdir+"/.*.test.only") and not os.path.exists(sketchdir + '/.' + variant + '.test.only'):
success = SKIPPED
skip_count += 1
elif 'usbstack=tinyusb' not in variant and "libraries/Adafruit_TinyUSB_Arduino" in sketch:
# skip non-tinyusb variant for tinyusb examples
success = SKIPPED
skip_count += 1
elif 'usbstack=tinyusb' in variant and "libraries/USBHost" in sketch:
# skip -tinyusb variant for USBHost examples
success = SKIPPED
skip_count += 1
else:
build_result = subprocess.run("arduino-cli compile --warnings all --fqbn {} {}".format(fqbn, sketch), shell=True, stdout=PIPE, stderr=PIPE)
# get stderr into a form where warning/error was output to stderr
if build_result.returncode != 0:
exit_status = build_result.returncode
success = FAILED
fail_count += 1
else:
success_count += 1
if build_result.stderr:
success = WARNING
else:
success = SUCCEEDED
build_duration = time.monotonic() - start_time
print(build_format.format(sketch.split(os.path.sep)[1], os.path.basename(sketch), success, '{:5.2f}s'.format(build_duration)))
if success != SKIPPED:
# Build failed
if build_result.returncode != 0:
print(build_result.stdout.decode("utf-8"))
# Build with warnings
if build_result.stderr:
print(build_result.stderr.decode("utf-8"))
build_time = time.monotonic()
for board in build_boards:
build_examples(board)
print(build_separator)
build_time = time.monotonic() - build_time
print("Build Summary: {} {}, {} {}, {} {} and took {:.2f}s".format(success_count, SUCCEEDED, fail_count, FAILED, skip_count, SKIPPED, build_time))
print(build_separator)
sys.exit(exit_status)

414
tools/makeboards.py Executable file
View file

@ -0,0 +1,414 @@
#!/usr/bin/env python3
print('''# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
''')
mcu_dict = {
'SAMD21': {
'flash_size': 262144,
'data_size': 0,
'offset': '0x2000',
'build_mcu': 'cortex-m0plus',
'f_cpu': '48000000L',
'extra_flags': '-DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS',
'openocdscript': 'scripts/openocd/daplink_samd21.cfg',
},
'SAMD51': {
'flash_size': 507904, # SAMD51P20A and SAMD51J20A has 1032192
'data_size': 0,
'offset': '0x4000',
'build_mcu': 'cortex-m4',
'f_cpu': '120000000L',
'extra_flags': '-D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16',
'openocdscript': 'scripts/openocd/daplink_samd51.cfg',
},
'SAME51': {
'flash_size': 507904,
'data_size': 0,
'offset': '0x4000',
'build_mcu': 'cortex-m4',
'f_cpu': '120000000L',
'extra_flags': '-D__SAMD51__ -D__FPU_PRESENT -DARM_MATH_CM4 -mfloat-abi=hard -mfpu=fpv4-sp-d16',
'openocdscript': 'scripts/openocd/daplink_samd51.cfg',
},
}
def build_header(mcu, name, vendor, product, vid, pid_list):
prettyname = f"{vendor} {product} ({mcu})"
print()
print("# -----------------------------------")
print(f"# {prettyname}")
print("# -----------------------------------")
print(f"{name}.name={prettyname}")
print()
print("# VID/PID for Bootloader, Arduino & CircuitPython")
for i in range(len(pid_list)):
print(f"{name}.vid.{i}={vid}")
print(f"{name}.pid.{i}={pid_list[i]}")
print()
def build_upload(mcu, name, extra_flags):
print("# Upload")
print(f"{name}.upload.tool=bossac18")
print(f"{name}.upload.protocol=sam-ba")
if ('SAMD51P20A' in extra_flags) or ('SAMD51J20A' in extra_flags):
flash_size = 1032192
else:
flash_size = mcu_dict[mcu]['flash_size']
print(f"{name}.upload.maximum_size={flash_size}")
#print(f"{name}.upload.maximum_data_size={mcu_dict[mcu]['data_size']}")
print(f"{name}.upload.offset={mcu_dict[mcu]['offset']}")
print(f"{name}.upload.use_1200bps_touch=true")
print(f"{name}.upload.wait_for_upload_port=true")
print(f"{name}.upload.native_usb=true")
print()
def build_build(mcu, name, variant, vendor, product, vid, pid_list, boarddefine, extra_flags, bootloader):
mcu_properties = mcu_dict[mcu]
print("# Build")
print(f"{name}.build.mcu={mcu_properties['build_mcu']}")
print(f"{name}.build.f_cpu={mcu_properties['f_cpu']}")
print(f'{name}.build.usb_product="{product}"')
print(f'{name}.build.usb_manufacturer="{vendor}"')
print(f"{name}.build.board={boarddefine}")
print(f"{name}.build.core=arduino")
# Due to fastLed issue https://github.com/FastLED/FastLED/issues/1363
# although there is a simple fix already https://github.com/FastLED/FastLED/pull/1424
# fastLED is not well maintained, and we need to skip ARDUINO_SAMD_ZERO for affected boards
# in the long run we should move all of our libraries away from ARDUINO_SAMD_ZERO
if variant in [ 'gemma_m0', 'trinket_m0', 'qtpy_m0', 'itsybitsy_m0' ]:
print(f"{name}.build.extra_flags={extra_flags} -DARM_MATH_CM0PLUS {{build.usb_flags}}")
else:
print(f"{name}.build.extra_flags={extra_flags} {mcu_properties['extra_flags']} {{build.usb_flags}}")
print(f"{name}.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld")
print(f"{name}.build.openocdscript={mcu_properties['openocdscript']}")
print(f"{name}.build.variant={variant}")
print(f"{name}.build.variant_system_lib=")
print(f"{name}.build.vid={vid}")
print(f"{name}.build.pid={pid_list[0]}")
print(f"{name}.bootloader.tool=openocd")
print(f"{name}.bootloader.file={bootloader}")
if (mcu == 'SAMD51' or mcu == 'SAME51'):
print(f'{name}.compiler.arm.cmsis.ldflags="-L{{runtime.tools.CMSIS-5.4.0.path}}/CMSIS/Lib/GCC/" "-L{{build.variant.path}}" -larm_cortexM4lf_math -mfloat-abi=hard -mfpu=fpv4-sp-d16')
print()
def build_menu(mcu, name):
if (mcu == 'SAMD51' or mcu == 'SAME51'):
print("# Menu: Cache")
print(f"{name}.menu.cache.on=Enabled")
print(f"{name}.menu.cache.on.build.cache_flags=-DENABLE_CACHE")
print(f"{name}.menu.cache.off=Disabled")
print(f"{name}.menu.cache.off.build.cache_flags=")
print()
print("# Menu: Speed")
print(f"{name}.menu.speed.120=120 MHz (standard)")
print(f"{name}.menu.speed.120.build.f_cpu=120000000L")
print(f"{name}.menu.speed.150=150 MHz (overclock)")
print(f"{name}.menu.speed.150.build.f_cpu=150000000L")
print(f"{name}.menu.speed.180=180 MHz (overclock)")
print(f"{name}.menu.speed.180.build.f_cpu=180000000L")
print(f"{name}.menu.speed.200=200 MHz (overclock)")
print(f"{name}.menu.speed.200.build.f_cpu=200000000L")
print()
print("# Menu: Optimization")
print(f"{name}.menu.opt.small=Small (-Os) (standard)")
print(f"{name}.menu.opt.small.build.flags.optimize=-Os")
print(f"{name}.menu.opt.fast=Fast (-O2)")
print(f"{name}.menu.opt.fast.build.flags.optimize=-O2")
print(f"{name}.menu.opt.faster=Faster (-O3)")
print(f"{name}.menu.opt.faster.build.flags.optimize=-O3")
print(f"{name}.menu.opt.fastest=Fastest (-Ofast)")
print(f"{name}.menu.opt.fastest.build.flags.optimize=-Ofast")
print(f"{name}.menu.opt.dragons=Here be dragons (-Ofast -funroll-loops)")
print(f"{name}.menu.opt.dragons.build.flags.optimize=-Ofast -funroll-loops")
print()
if (mcu == 'SAMD51' or mcu == 'SAME51'):
print("# Menu: QSPI Speed")
print(f"{name}.menu.maxqspi.50=50 MHz (standard)")
print(f"{name}.menu.maxqspi.50.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=50000000")
print(f"{name}.menu.maxqspi.fcpu=CPU Speed / 2")
print(f"{name}.menu.maxqspi.fcpu.build.flags.maxqspi=-DVARIANT_QSPI_BAUD_DEFAULT=({{build.f_cpu}})")
print()
print("# Menu: USB Stack")
print(f"{name}.menu.usbstack.arduino=Arduino")
print(f"{name}.menu.usbstack.tinyusb=TinyUSB")
print(f"{name}.menu.usbstack.tinyusb.build.flags.usbstack=-DUSE_TINYUSB")
print()
print("# Menu: Debug")
print(f"{name}.menu.debug.off=Off")
print(f"{name}.menu.debug.on=On")
print(f"{name}.menu.debug.on.build.flags.debug=-g")
print()
# comment out for now since debugger selection does not work, debug does not pickup the right openocd script
# print("# Menu: Debugger")
# script_mcu = 'samd21' if mcu == 'SAMD21' else 'samd51'
# print(f"{name}.menu.debugger.daplink=CMSIS-DAP (DAPLink)")
# print(f"{name}.menu.debugger.daplink.build.openocdscript=scripts/openocd/daplink_{script_mcu}.cfg")
# print(f"{name}.menu.debugger.jlink=J-Link")
# print(f"{name}.menu.debugger.jlink.build.openocdscript=scripts/openocd/jlink_{script_mcu}.cfg")
def build_global_menu():
print("menu.cache=Cache")
print("menu.speed=CPU Speed")
print("menu.opt=Optimize")
print("menu.maxqspi=Max QSPI")
print("menu.usbstack=USB Stack")
print("menu.debug=Debug")
#print("menu.debugger=Debugger")
def make_board(mcu, name, variant, vendor, product, vid, pid_list, boarddefine, extra_flags, bootloader):
build_header(mcu, name, vendor, product, vid, pid_list)
build_upload(mcu, name, extra_flags)
build_build(mcu, name, variant, vendor, product, vid, pid_list, boarddefine, extra_flags, bootloader)
build_menu(mcu, name)
# ------------------------------
# main
# ------------------------------
build_global_menu()
# ------------------------------
# SAM D21 (M0)
# ------------------------------
# name, variant, vendor, product, vid, pid_list, boarddefine, extra_flags, bootloader
# try to sort in Alphabetical order
d21_board_list = [
["adafruit_feather_m0", "feather_m0", "Adafruit", "Feather M0",
"0x239A", ["0x800B", "0x000B", "0x0015"],
"SAMD_ZERO", "-D__SAMD21G18A__ -DADAFRUIT_FEATHER_M0",
"featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin"],
["adafruit_feather_m0_express", "feather_m0_express", "Adafruit", "Feather M0 Express",
"0x239A", ["0x801B", "0x001B"],
"SAMD_FEATHER_M0_EXPRESS", "-D__SAMD21G18A__ -DARDUINO_SAMD_FEATHER_M0 -DADAFRUIT_FEATHER_M0_EXPRESS",
"featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin"],
["adafruit_metro_m0", "metro_m0", "Adafruit", "Metro M0 Express",
"0x239A", ["0x8013", "0x0013"],
"SAMD_ZERO", "-D__SAMD21G18A__ -DADAFRUIT_METRO_M0_EXPRESS",
"metroM0/bootloader-metro_m0-v2.0.0-adafruit.5.bin"],
["adafruit_circuitplayground_m0", "circuitplay", "Adafruit", "Circuit Playground Express",
"0x239A", ["0x8018", "0x0019"],
"SAMD_CIRCUITPLAYGROUND_EXPRESS", "-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_CIRCUITPLAYGROUND_M0",
"circuitplayM0/bootloader-circuitplay_m0-v2.0.0-adafruit.5.bin"],
["adafruit_gemma_m0", "gemma_m0", "Adafruit", "Gemma M0",
"0x239A", ["0x801C", "0x001C"],
"GEMMA_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_GEMMA_M0",
"gemmaM0/bootloader-gemma_m0-v2.0.0-adafruit.5.bin"],
["adafruit_trinket_m0", "trinket_m0", "Adafruit", "Trinket M0",
"0x239A", ["0x801E", "0x001E"],
"TRINKET_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_TRINKET_M0",
"trinketm0/bootloader-trinket_m0-v2.0.0-adafruit.5.bin"],
["adafruit_qtpy_m0", "qtpy_m0", "Adafruit", "QT Py M0",
"0x239A", ["0x80CB", "0x00CB", "0x00CC"],
"QTPY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_QTPY_M0",
"qtpyM0/bootloader-qtpy_m0.bin"],
["adafruit_neotrinkey_m0", "neotrinkey_m0", "Adafruit", "NeoPixel Trinkey M0",
"0x239A", ["0x80EF", "0x00EF", "0x80F0"],
"NEOTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_NEOTRINKEY_M0",
"neotrinkey_m0/bootloader-neotrinkey_m0.bin"],
["adafruit_rotarytrinkey_m0", "rotarytrinkey_m0", "Adafruit", "Rotary Trinkey M0",
"0x239A", ["0x80FB", "0x00FB", "0x80FC"],
"ROTARYTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_ROTARYTRINKEY_M0",
"rotarytrinkey_m0/bootloader-rotarytrinkey_m0.bin"],
["adafruit_neokeytrinkey_m0", "neokeytrinkey_m0", "Adafruit", "NeoKey Trinkey M0",
"0x239A", ["0x80FF", "0x00FF", "0x8100"],
"NEOKEYTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_NEOKEYTRINKEY_M0",
"neokeytrinkey_m0/bootloader-neokeytrinkey_m0.bin"],
["adafruit_slidetrinkey_m0", "slidetrinkey_m0", "Adafruit", "Slide Trinkey M0",
"0x239A", ["0x8101", "0x0101", "0x8102"],
"SLIDETRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_SLIDETRINKEY_M0",
"slidetrinkey_m0/bootloader-slidetrinkey_m0.bin"],
["adafruit_proxlighttrinkey_m0", "proxlighttrinkey_m0", "Adafruit", "ProxLight Trinkey M0",
"0x239A", ["0x8103", "0x0103", "0x8104"],
"PROXLIGHTTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PROXLIGHTTRINKEY_M0",
"proxlighttrinkey_m0/bootloader-proxlighttrinkey_m0.bin"],
["adafruit_sht4xtrinkey_m0", "sht4xtrinkey_m0", "Adafruit", "SHT4x Trinkey M0",
"0x239A", ["0x8153", "0x0153", "0x8154"],
"SHT4XTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_SHT4XTRINKEY_M0",
"sht4xtrinkey_m0/bootloader-sht4xtrinkey_m0.bin"],
["adafruit_pixeltrinkey_m0", "pixeltrinkey_m0", "Adafruit", "Pixel Trinkey M0",
"0x239A", ["0x8155", "0x0155", "0x8156"],
"PIXELTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PIXELTRINKEY_M0",
"pixeltrinkey_m0/bootloader-pixeltrinkey_m0.bin"],
["adafruit_TRRStrinkey_m0", "trrstrinkey_m0", "Adafruit", "TRRS Trinkey M0",
"0x239A", ["0x8157", "0x0157", "0x8158"],
"TRRSTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_TRRSTRINKEY_M0",
"trrstrinkey_m0/bootloader-TRRStrinkey_m0.bin"],
["adafruit_thumbsticktrinkey_m0", "thumbsticktrinkey_m0", "Adafruit", "Thumbstick Trinkey M0",
"0x239A", ["0x8159", "0x0159", "0x8160"],
"THUMBSTICKTRINKEY_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_THUMBSTICKTRINKEY_M0",
"thumbsticktrinkey_m0/bootloader-thumbsticktrinkey_m0.bin"],
["adafruit_itsybitsy_m0", "itsybitsy_m0", "Adafruit", "ItsyBitsy M0 Express",
"0x239A", ["0x800F", "0x000F", "0x8012"],
"ITSYBITSY_M0", "-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_ITSYBITSY_M0",
"itsybitsyM0/bootloader-itsybitsy_m0-v2.0.0-adafruit.5.bin"],
["adafruit_pirkey", "pirkey", "Adafruit", "pIRKey",
"0x239A", ["0x8027", "0x0027", "0x8028"],
"PIRKEY", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_PIRKEY",
"pirkey/bootloader-pirkey-v2.0.0-adafruit.5.bin"],
["adafruit_hallowing", "hallowing_m0_express", "Adafruit", "Hallowing M0",
"0x239A", ["0xDEAD", "0xD1ED", "0xB000"],
"SAMD_HALLOWING", "-D__SAMD21G18A__ -DCRYSTALLESS -DARDUINO_SAMD_HALLOWING_M0 -DADAFRUIT_HALLOWING",
"hallowingM0/bootloader-hallowing_m0-v2.0.0-adafruit.0-21-g887cc30.bin"],
["adafruit_crickit_m0", "crickit_m0", "Adafruit", "Crickit M0",
"0x239A", ["0x802D", "0x002D", "0x802D"],
"CRICKIT_M0", "-D__SAMD21G18A__ -DCRYSTALLESS -DADAFRUIT_CRICKIT_M0",
"crickit/samd21_sam_ba.bin"],
["adafruit_blm_badge", "blm_badge", "Adafruit", "BLM Badge",
"0x239A", ["0x80BF", "0x00BF", "0x80C0"],
"BLM_BADGE_M0", "-D__SAMD21E18A__ -DCRYSTALLESS -DADAFRUIT_BLM_BADGE",
"blmbadge/bootloader-blm_badge.bin"],
]
for b in d21_board_list:
make_board("SAMD21", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8])
# ----------------------------
# SAM D51 and E51 (M4)
# ----------------------------
d51_board_list = [
["adafruit_metro_m4", "metro_m4", "Adafruit", "Metro M4",
"0x239A", ["0x8020", "0x0020", "0x8021", "0x0021"],
"METRO_M4", "-D__SAMD51J19A__ -DADAFRUIT_METRO_M4_EXPRESS",
"metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin"],
["adafruit_grandcentral_m4", "grand_central_m4", "Adafruit", "Grand Central M4",
"0x239A", ["0x8031", "0x0031", "0x0032"],
"GRAND_CENTRAL_M4", "-D__SAMD51P20A__ -DADAFRUIT_GRAND_CENTRAL_M4",
"grand_central_m4/bootloader-grandcentral_m4.bin"],
["adafruit_itsybitsy_m4", "itsybitsy_m4", "Adafruit", "ItsyBitsy M4",
"0x239A", ["0x802B", "0x002B"],
"ITSYBITSY_M4", "-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_ITSYBITSY_M4_EXPRESS",
"itsybitsyM4/bootloader-itsybitsy_m4-v2.0.0-adafruit.5.bin"],
["adafruit_feather_m4", "feather_m4", "Adafruit", "Feather M4 Express",
"0x239A", ["0x8022", "0x0022", "0x8026"],
"FEATHER_M4", "-D__SAMD51J19A__ -DADAFRUIT_FEATHER_M4_EXPRESS",
"featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"],
["adafruit_feather_m4_can", "feather_m4_can", "Adafruit", "Feather M4 CAN",
"0x239A", ["0x80CD", "0x00CD"],
"FEATHER_M4_CAN", "-D__SAME51J19A__ -DADAFRUIT_FEATHER_M4_EXPRESS -DADAFRUIT_FEATHER_M4_CAN",
"featherM4/bootloader-feather_m4_express-v2.0.0-adafruit.5.bin"],
# ["adafruit_feather_m4_log", "feather_m4_log", "Adafruit", "Feather M4 Adalogger",
# "0x239A", ["0x8115", "0x0115", "0x8116"],
# "FEATHER_M4_ADALOGGER", "-D__SAME51J19A__ -DADAFRUIT_FEATHER_M4_ADALOGGER",
# "feather_m4_log/bootloader-feather_m4_log-v2.0.0-adafruit.5.bin"],
["adafruit_trellis_m4", "trellis_m4",
"Adafruit", "Trellis M4", "0x239A", ["0x802F", "0x002F", "0x0030"],
"TRELLIS_M4", "-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_TRELLIS_M4_EXPRESS",
"trellisM4/bootloader-trellis_m4-v2.0.0-adafruit.5.bin"],
["adafruit_pyportal_m4", "pyportal_m4", "Adafruit", "PyPortal M4",
"0x239A", ["0x8035", "0x0035", "0x8036"],
"PYPORTAL_M4", "-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYPORTAL",
"metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin"],
["adafruit_pyportal_m4_titano", "pyportal_m4_titano", "Adafruit", "PyPortal M4 Titano",
"0x239A", ["0x8053", "0x8053"],
"PYPORTAL_M4_TITANO", "-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYPORTAL_M4_TITANO",
"metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin"],
["adafruit_pybadge_m4", "pybadge_m4", "Adafruit", "pyBadge M4 Express",
"0x239A", ["0x8033", "0x0033", "0x8034", "0x0034"],
"PYBADGE_M4", "-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_PYBADGE_M4_EXPRESS",
"featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"],
["adafruit_metro_m4_airliftlite", "metro_m4_airlift", "Adafruit", "Metro M4 AirLift Lite",
"0x239A", ["0x8037", "0x0037"],
"METRO_M4_AIRLIFT_LITE", "-D__SAMD51J19A__ -DADAFRUIT_METRO_M4_AIRLIFT_LITE",
"metroM4/bootloader-metro_m4-v2.0.0-adafruit.5.bin"],
["adafruit_pygamer_m4", "pygamer_m4", "Adafruit", "PyGamer M4 Express",
"0x239A", ["0x803D", "0x003D", "0x803E"],
"PYGAMER_M4", "-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_PYGAMER_M4_EXPRESS",
"featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"],
["adafruit_pybadge_airlift_m4", "pybadge_airlift_m4", "Adafruit", "pyBadge AirLift M4",
"0x239A", ["0x8043", "0x0043", "0x8044"],
"PYBADGE_AIRLIFT_M4", "-D__SAMD51J20A__ -DCRYSTALLESS -DADAFRUIT_PYBADGE_AIRLIFT_M4",
"featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"],
["adafruit_monster_m4sk", "monster_m4sk", "Adafruit", "MONSTER M4SK",
"0x239A", ["0x8047", "0x0047", "0x8048"],
"MONSTER_M4SK", "-D__SAMD51G19A__ -DCRYSTALLESS -DADAFRUIT_MONSTER_M4SK_EXPRESS",
"featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"],
["adafruit_hallowing_m4", "hallowing_m4", "Adafruit", "Hallowing M4",
"0x239A", ["0x8049", "0x0049", "0x804A"],
"HALLOWING_M4", "-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_HALLOWING_M4_EXPRESS",
"featherM4/bootloader-feather_m4-v2.0.0-adafruit.5.bin"],
["adafruit_matrixportal_m4", "matrixportal_m4", "Adafruit", "Matrix Portal M4",
"0x239A", ["0x80C9", "0x00C9", "0x80CA"],
"MATRIXPORTAL_M4", "-D__SAMD51J19A__ -DCRYSTALLESS -DADAFRUIT_MATRIXPORTAL_M4_EXPRESS",
"matrixportalM4/bootloader-matrixportal_m4.bin"],
]
for b in d51_board_list:
# M4 CAN is the only SAME51
if b[0] == "adafruit_feather_m4_can":
make_board("SAME51", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8])
else:
make_board("SAMD51", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8])

View file

@ -66,12 +66,37 @@
// #define digitalPinToTimer(P) // #define digitalPinToTimer(P)
// Digital pins
// ----
#define PIN_D4 (4u)
#define PIN_D5 (5u)
#define PIN_D7 (7u)
#define PIN_D8 (8u)
#define PIN_D11 (25u)
#define PIN_D12 (26u)
#define PIN_D13 (13u)
#define D4 PIN_D4
#define D5 PIN_D5
#define D7 PIN_D7
#define D8 PIN_D8
#define D11 PIN_D11
#define D12 PIN_D12
#define D13 PIN_D13
// LEDs // LEDs
// ---- // ----
#define PIN_LED_13 (13u) #define PIN_LED_13 (D13)
#define PIN_LED PIN_LED_13 #define PIN_LED PIN_LED_13
#define LED_BUILTIN PIN_LED #define LED_BUILTIN PIN_LED
// Neopixel
#define PIN_NEOPIXEL D8
#define NEOPIXEL_NUM 10
#define PIN_BUTTON1 D4 // Left Button
#define PIN_BUTTON2 D5 // Right Button
//#define PIN_LED_RXL (25u) //#define PIN_LED_RXL (25u)
//#define PIN_LED_TXL (26u) //#define PIN_LED_TXL (26u)
@ -242,10 +267,7 @@ extern Uart Serial1;
// //
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX // SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default. // pins are NOT connected to anything by default.
#define SERIAL_PORT_USBVIRTUAL SerialUSB #define SERIAL_PORT_USBVIRTUAL Serial
#define SERIAL_PORT_MONITOR SerialUSB #define SERIAL_PORT_MONITOR Serial
#define SERIAL_PORT_HARDWARE Serial1 #define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1 #define SERIAL_PORT_HARDWARE_OPEN Serial1
// Alias Serial to SerialUSB
#define Serial SerialUSB

View file

@ -170,6 +170,10 @@ SECTIONS
KEEP(*(.fini_array)) KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .); PROVIDE_HIDDEN (__fini_array_end = .);
. = ALIGN(4);
/* Keep .ramfunc functions in RAM */
KEEP(*(.ramfunc))
KEEP(*(.jcr*)) KEEP(*(.jcr*))
. = ALIGN(16); . = ALIGN(16);
/* All data end */ /* All data end */

View file

@ -67,7 +67,7 @@ const PinDescription g_APinDescription[PINS_COUNT]=
{ PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 }, { PORTA, 6, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM_E), ADC_Channel6, TC1_CH0, TC1_CH0, EXTERNAL_INT_6 },
// A6, D20 - VDiv! // A6, D20 - VDiv!
{ PORTB, 1, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel13, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_1 }, { PORTB, 0, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel12, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_0 },
// 21..22 I2C pins (SDA/SCL) // 21..22 I2C pins (SDA/SCL)

View file

@ -85,8 +85,12 @@ extern "C"
#define PIN_LED3 PIN_LED_TXL #define PIN_LED3 PIN_LED_TXL
#define LED_BUILTIN PIN_LED_13 #define LED_BUILTIN PIN_LED_13
// DotStar LED // DotStar LED
#define INTERNAL_DS_DATA 3 #define INTERNAL_DS_DATA (3u)
#define INTERNAL_DS_CLK 4 #define INTERNAL_DS_CLK (4u)
#define PIN_DOTSTAR_DATA (3u)
#define PIN_DOTSTAR_CLK (4u)
#define PIN_DOTSTAR_CLOCK PIN_DOTSTAR_CLK
#define DOTSTAR_NUM (1u)
/* /*
* Analog pins * Analog pins

View file

@ -80,6 +80,11 @@ extern "C"
#define PIN_LED_13 (13u) #define PIN_LED_13 (13u)
#define PIN_LED PIN_LED_13 #define PIN_LED PIN_LED_13
#define LED_BUILTIN PIN_LED_13 #define LED_BUILTIN PIN_LED_13
// DotStar LED
#define PIN_DOTSTAR_DATA (41u)
#define PIN_DOTSTAR_CLK (40u)
#define PIN_DOTSTAR_CLOCK PIN_DOTSTAR_CLK
#define DOTSTAR_NUM (1u)
/* /*
* Analog pins * Analog pins

View file

@ -84,6 +84,11 @@ extern "C"
#define PIN_LED_13 (13u) #define PIN_LED_13 (13u)
#define PIN_LED PIN_LED_13 #define PIN_LED PIN_LED_13
#define LED_BUILTIN PIN_LED_13 #define LED_BUILTIN PIN_LED_13
// DotStar LED
#define PIN_DOTSTAR_DATA (8u)
#define PIN_DOTSTAR_CLK (6u)
#define PIN_DOTSTAR_CLOCK PIN_DOTSTAR_CLK
#define DOTSTAR_NUM (1u)
/* /*
* Analog pins * Analog pins
@ -137,7 +142,7 @@ static const uint8_t ATN = PIN_ATN;
#define PAD_SPI_TX SPI_PAD_0_SCK_1 #define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_3 #define PAD_SPI_RX SERCOM_RX_PAD_3
static const uint8_t SS = PIN_A2 ; static const uint8_t SS = PIN_A2 ;
static const uint8_t MOSI = PIN_SPI_MOSI ; static const uint8_t MOSI = PIN_SPI_MOSI ;
static const uint8_t MISO = PIN_SPI_MISO ; static const uint8_t MISO = PIN_SPI_MISO ;
static const uint8_t SCK = PIN_SPI_SCK ; static const uint8_t SCK = PIN_SPI_SCK ;

View file

@ -98,8 +98,22 @@ static const uint8_t A1 = PIN_A1;
/* /*
* SPI Interfaces * SPI Interfaces
* Fake SPI Interface just so we can compile
*/ */
#define SPI_INTERFACES_COUNT 0 #define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO PIN_A0
#define PIN_SPI_MOSI PIN_A0
#define PIN_SPI_SCK PIN_A0
#define PERIPH_SPI sercom0
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_0
static const uint8_t SS = PIN_A0;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/* /*
* Wire Interfaces * Wire Interfaces

View file

@ -97,8 +97,21 @@ static const uint8_t A2 = PIN_A2;
/* /*
* SPI Interfaces * SPI Interfaces
* Fake SPI Interface just so we can compile
*/ */
#define SPI_INTERFACES_COUNT 0 #define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO PIN_A0
#define PIN_SPI_MOSI PIN_A0
#define PIN_SPI_SCK PIN_A0
#define PERIPH_SPI sercom0
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_0
static const uint8_t SS = PIN_A0;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/* /*
* Wire Interfaces * Wire Interfaces

View file

@ -0,0 +1,31 @@
#
# Arduino Zero OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Define 'reset' command
define reset
info reg
break main
# End of 'reset' command
end
target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log"

View file

@ -0,0 +1,216 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__text_start__ = .;
KEEP(*(.sketch_boot))
. = ALIGN(0x2000);
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(16);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View file

@ -0,0 +1,214 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
* __ram_end__
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__text_start__ = .;
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(16);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM) ;
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View file

@ -0,0 +1,28 @@
#
# Adafruit ItsyBitsy M0 OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# chip name
set CHIPNAME at91samd21e18
set ENDIAN little
# choose a port here
set telnet_port 0
source [find target/at91samdXX.cfg]

View file

@ -0,0 +1,21 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// API compatibility
#include "variant.h"

View file

@ -0,0 +1,52 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "Arduino.h"
/*
* Pins descriptions
*/
const PinDescription g_APinDescription[]=
{
// DAC / A0 for monitoring 5V
{ PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC
// Internal NeoPixel / D1
{ PORTA, 1, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
// SPI MOSI/SCK
{ PORTA, 4, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // D2 / MOSI
{ PORTA, 5, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D3 / SCK
// A6 / MISO
{ PORTA, 6, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel6, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // A6 / MISO
// USB pins D5, D6, D7
{ PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable
{ PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM
{ PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP
} ;
const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ;
// Multi-serial objects instantiation
SERCOM sercom0( SERCOM0 ) ;
SERCOM sercom1( SERCOM1 ) ;
SERCOM sercom2( SERCOM2 ) ;
SERCOM sercom3( SERCOM3 ) ;

View file

@ -0,0 +1,189 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VARIANT_PIXELTRINKEY_ZERO_
#define _VARIANT_PIXELTRINKEY_ZERO_
// The definitions here needs a SAMD core >=1.6.10
#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Frequency of the board main oscillator */
#define VARIANT_MAINOSC (32768ul)
/** Master clock frequency */
#define VARIANT_MCK (F_CPU)
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
#include "SERCOM.h"
#include "Uart.h"
#endif // __cplusplus
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*----------------------------------------------------------------------------
* Pins
*----------------------------------------------------------------------------*/
// Number of pins defined in PinDescription array
#define PINS_COUNT (7u)
#define NUM_DIGITAL_PINS (4u)
#define NUM_ANALOG_INPUTS (1u)
#define NUM_ANALOG_OUTPUTS (1u)
#define analogInputToDigitalPin(p) (p)
#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) )
#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin )
//#define analogInPinToBit(P) ( )
#define portOutputRegister(port) ( &(port->OUT.reg) )
#define portInputRegister(port) ( &(port->IN.reg) )
#define portModeRegister(port) ( &(port->DIR.reg) )
#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER )
/*
* digitalPinToTimer(..) is AVR-specific and is not defined for SAMD
* architecture. If you need to check if a pin supports PWM you must
* use digitalPinHasPWM(..).
*
* https://github.com/arduino/Arduino/issues/1833
*/
// #define digitalPinToTimer(P)
// LEDs
#define PIN_NEOPIXEL (1u)
#define NUM_NEOPIXEL (1u)
#define PIN_DATA (2u)
#define PIN_CLOCK (3u)
/*
* Analog pins
*/
#define PIN_A0 (0ul)
#define PIN_DAC0 PIN_A0
#define PIN_A6 (4ul)
static const uint8_t A0 = PIN_A0;
static const uint8_t A6 = PIN_A6;
#define ADC_RESOLUTION 12
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO (4ul) // off 3-pin JST, broken out
#define PIN_SPI_MOSI (2ul)
#define PIN_SPI_SCK (3ul)
#define PERIPH_SPI sercom0
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_2
static const uint8_t SS = (5ul); // not actually broken out
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/*
* Wire Interfaces, fake just for compilation
*/
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (2u)
#define PIN_WIRE_SCL (3u)
#define PERIPH_WIRE sercom0
#define WIRE_IT_HANDLER SERCOM0_Handler
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
/*
* USB
*/
#define PIN_USB_HOST_ENABLE (5ul)
#define PIN_USB_DM (6ul)
#define PIN_USB_DP (7ul)
/*
* I2S Interfaces
*/
#define I2S_INTERFACES_COUNT 0
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#ifdef __cplusplus
/* =========================
* ===== SERCOM DEFINITION
* =========================
*/
extern SERCOM sercom0;
extern SERCOM sercom1;
extern SERCOM sercom2;
extern SERCOM sercom3;
extern SERCOM sercom4;
extern SERCOM sercom5;
#endif
// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
#define SERIAL_PORT_USBVIRTUAL Serial
#define SERIAL_PORT_MONITOR Serial
// Serial has no physical pins broken out, so it's not listed as HARDWARE port
#define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1
#endif /* _VARIANT_ARDUINO_ZERO_ */

View file

@ -41,7 +41,7 @@ const PinDescription g_APinDescription[]=
// Interrupt D6 // Interrupt D6
{ PORTA, 0, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, { PORTA, 0, PIO_DIGITAL, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 },
// USB pins // USB pins D7, D8, D9
{ PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable { PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable
{ PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM { PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM
{ PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP { PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP

View file

@ -103,8 +103,21 @@ static const uint8_t A2 = PIN_A2;
/* /*
* SPI Interfaces * SPI Interfaces
* Fake SPI Interface just so we can compile
*/ */
#define SPI_INTERFACES_COUNT 0 #define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO PIN_A0
#define PIN_SPI_MOSI PIN_A0
#define PIN_SPI_SCK PIN_A0
#define PERIPH_SPI sercom0
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_0
static const uint8_t SS = PIN_A0;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/* /*
* Wire Interfaces * Wire Interfaces

View file

@ -160,7 +160,7 @@ static const uint8_t ATN = PIN_ATN;
#define PAD_SPI_TX SPI_PAD_0_SCK_1 #define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_2 #define PAD_SPI_RX SERCOM_RX_PAD_2
static const uint8_t SS = PIN_A2; // ??? static const uint8_t SS = 32;
static const uint8_t MOSI = PIN_SPI_MOSI; static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO; static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK; static const uint8_t SCK = PIN_SPI_SCK;

View file

@ -160,7 +160,7 @@ static const uint8_t ATN = PIN_ATN;
#define PAD_SPI_TX SPI_PAD_0_SCK_1 #define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_2 #define PAD_SPI_RX SERCOM_RX_PAD_2
static const uint8_t SS = PIN_A2; // ??? static const uint8_t SS = 32;
static const uint8_t MOSI = PIN_SPI_MOSI; static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO; static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK; static const uint8_t SCK = PIN_SPI_SCK;

View file

@ -23,14 +23,14 @@
*/ */
const PinDescription g_APinDescription[]= const PinDescription g_APinDescription[]=
{ {
{ PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC { PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 }, // A0 / D0 / DAC
{ PORTA, 3, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // A1 / D1 / AREF { PORTA, 3, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 }, // A1 / D1 / AREF
{ PORTA, 4, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // A2 / D2 / PWM { PORTA, 4, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel4, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_4 }, // A2 / D2 / PWM
{ PORTA, 5, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // A3 / D3 / PWM { PORTA, 5, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel5, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_5 }, // A3 / D3 / PWM
// I2C SDA & SCL // I2C SDA & SCL
{ PORTA, 16, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH6, TCC0_CH6, EXTERNAL_INT_0 }, // D4 / SDA / PWM { PORTA, 16, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_0 }, // D4 / SDA / PWM
{ PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER_ALT), No_ADC_Channel, PWM0_CH7, TCC0_CH7, EXTERNAL_INT_1 }, // D5 / SCL / PWM { PORTA, 17, PIO_SERCOM, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM2_CH1, TCC2_CH1, EXTERNAL_INT_1 }, // D5 / SCL / PWM
// UART TX & RX // UART TX & RX
{ PORTA, 6, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // A6 / D6 / TX / PWM { PORTA, 6, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 }, // A6 / D6 / TX / PWM

View file

@ -104,8 +104,21 @@ static const uint8_t A2 = PIN_A2;
/* /*
* SPI Interfaces * SPI Interfaces
* Fake SPI Interface just so we can compile
*/ */
#define SPI_INTERFACES_COUNT 0 #define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO PIN_A0
#define PIN_SPI_MOSI PIN_A0
#define PIN_SPI_SCK PIN_A0
#define PERIPH_SPI sercom0
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_0
static const uint8_t SS = PIN_A0;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/* /*
* Wire Interfaces * Wire Interfaces

View file

@ -0,0 +1,31 @@
#
# Arduino Zero OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Define 'reset' command
define reset
info reg
break main
# End of 'reset' command
end
target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log"

View file

@ -0,0 +1,216 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__text_start__ = .;
KEEP(*(.sketch_boot))
. = ALIGN(0x2000);
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(16);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View file

@ -0,0 +1,214 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
* __ram_end__
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__text_start__ = .;
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(16);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM) ;
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View file

@ -0,0 +1,28 @@
#
# Adafruit ItsyBitsy M0 OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# chip name
set CHIPNAME at91samd21e18
set ENDIAN little
# choose a port here
set telnet_port 0
source [find target/at91samdXX.cfg]

View file

@ -0,0 +1,21 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// API compatibility
#include "variant.h"

View file

@ -0,0 +1,52 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "Arduino.h"
/*
* Pins descriptions
*/
const PinDescription g_APinDescription[]=
{
// Fake DAC A0 pin just so we can compile stuff
{ PORTA, 2, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel0, PWM2_CH0, TCC2_CH0, EXTERNAL_INT_2 }, // A0 / D0 / DAC
// touch / A1
{ PORTA, 7, PIO_ANALOG, (PIN_ATTR_ANALOG|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 }, // TCC1/WO[1]
// NeoPixel / D2
{ PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
// I2C SDA D3 & SCL D4
{ PORTA, 4, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 }, // D4 / SDA / PWM
{ PORTA, 5, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 }, // D5 / SCL / PWM
// USB pins D5, D6, D7
{ PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable
{ PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM
{ PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP
} ;
const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ;
// Multi-serial objects instantiation
SERCOM sercom0( SERCOM0 ) ;
SERCOM sercom1( SERCOM1 ) ;
SERCOM sercom2( SERCOM2 ) ;
SERCOM sercom3( SERCOM3 ) ;

View file

@ -0,0 +1,188 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VARIANT_SHT4XTRINKEY_ZERO_
#define _VARIANT_SHT4XTRINKEY_ZERO_
// The definitions here needs a SAMD core >=1.6.10
#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Frequency of the board main oscillator */
#define VARIANT_MAINOSC (32768ul)
/** Master clock frequency */
#define VARIANT_MCK (F_CPU)
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
#include "SERCOM.h"
#include "Uart.h"
#endif // __cplusplus
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*----------------------------------------------------------------------------
* Pins
*----------------------------------------------------------------------------*/
// Number of pins defined in PinDescription array
#define PINS_COUNT (10u)
#define NUM_DIGITAL_PINS (6u)
#define NUM_ANALOG_INPUTS (2u)
#define NUM_ANALOG_OUTPUTS (1u)
#define analogInputToDigitalPin(p) (p)
#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) )
#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin )
//#define analogInPinToBit(P) ( )
#define portOutputRegister(port) ( &(port->OUT.reg) )
#define portInputRegister(port) ( &(port->IN.reg) )
#define portModeRegister(port) ( &(port->DIR.reg) )
#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER )
/*
* digitalPinToTimer(..) is AVR-specific and is not defined for SAMD
* architecture. If you need to check if a pin supports PWM you must
* use digitalPinHasPWM(..).
*
* https://github.com/arduino/Arduino/issues/1833
*/
// #define digitalPinToTimer(P)
// LEDs
#define PIN_NEOPIXEL (2u)
#define NUM_NEOPIXEL (1u)
// TOUCH PINS
#define PIN_TOUCH 1
/*
* Analog pins
*/
#define PIN_A0 (0ul)
#define PIN_A1 (1)
#define PIN_DAC0 PIN_A0
static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
#define ADC_RESOLUTION 12
/*
* SPI Interfaces
* Fake SPI Interface just so we can compile
*/
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO PIN_A0
#define PIN_SPI_MOSI PIN_A0
#define PIN_SPI_SCK PIN_A0
#define PERIPH_SPI sercom0
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_0
static const uint8_t SS = PIN_A0;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/*
* Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE_SDA (3u)
#define PIN_WIRE_SCL (4u)
#define PERIPH_WIRE sercom0
#define WIRE_IT_HANDLER SERCOM0_Handler
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
/*
* USB
*/
#define PIN_USB_HOST_ENABLE (5ul)
#define PIN_USB_DM (6ul)
#define PIN_USB_DP (7ul)
/*
* I2S Interfaces
*/
#define I2S_INTERFACES_COUNT 0
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#ifdef __cplusplus
/* =========================
* ===== SERCOM DEFINITION
* =========================
*/
extern SERCOM sercom0;
extern SERCOM sercom1;
extern SERCOM sercom2;
extern SERCOM sercom3;
extern SERCOM sercom4;
extern SERCOM sercom5;
#endif
// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
#define SERIAL_PORT_USBVIRTUAL Serial
#define SERIAL_PORT_MONITOR Serial
// Serial has no physical pins broken out, so it's not listed as HARDWARE port
#define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1
#endif /* _VARIANT_ARDUINO_ZERO_ */

View file

@ -101,8 +101,21 @@ static const uint8_t A2 = PIN_A2;
/* /*
* SPI Interfaces * SPI Interfaces
* Fake SPI Interface just so we can compile
*/ */
#define SPI_INTERFACES_COUNT 0 #define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO PIN_A0
#define PIN_SPI_MOSI PIN_A0
#define PIN_SPI_SCK PIN_A0
#define PERIPH_SPI sercom0
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_0
static const uint8_t SS = PIN_A0;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/* /*
* Wire Interfaces * Wire Interfaces

View file

@ -0,0 +1,31 @@
#
# Arduino Zero OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Define 'reset' command
define reset
info reg
break main
# End of 'reset' command
end
target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log"

View file

@ -0,0 +1,216 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__text_start__ = .;
KEEP(*(.sketch_boot))
. = ALIGN(0x2000);
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(16);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View file

@ -0,0 +1,214 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
* __ram_end__
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__text_start__ = .;
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(16);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM) ;
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View file

@ -0,0 +1,28 @@
#
# Adafruit ItsyBitsy M0 OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# chip name
set CHIPNAME at91samd21e18
set ENDIAN little
# choose a port here
set telnet_port 0
source [find target/at91samdXX.cfg]

View file

@ -0,0 +1,21 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// API compatibility
#include "variant.h"

View file

@ -0,0 +1,52 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "Arduino.h"
/*
* Pins descriptions
*/
const PinDescription g_APinDescription[]=
{
// X (D0)
{ PORTA, 9, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel17, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_9 },
// Y (D1)
{ PORTA, 11, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_ANALOG), ADC_Channel19, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 },
// Button 1 (D2)
{ PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 },
// Button 2 (D3)
{ PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 },
// NeoPixel (D4)
{ PORTA, 0, PIO_DIGITAL, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_6 }, // TCC1/WO[0]
// USB pins D5, D6, D7
{ PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable
{ PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM
{ PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP
} ;
const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ;
// Multi-serial objects instantiation
SERCOM sercom0( SERCOM0 ) ;
SERCOM sercom1( SERCOM1 ) ;
SERCOM sercom2( SERCOM2 ) ;
SERCOM sercom3( SERCOM3 ) ;

View file

@ -0,0 +1,171 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VARIANT_THUMBSTICKTRINKEY_ZERO_
#define _VARIANT_THUMBSTICKTRINKEY_ZERO_
// The definitions here needs a SAMD core >=1.6.10
#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Frequency of the board main oscillator */
#define VARIANT_MAINOSC (32768ul)
/** Master clock frequency */
#define VARIANT_MCK (F_CPU)
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
#include "SERCOM.h"
#include "Uart.h"
#endif // __cplusplus
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*----------------------------------------------------------------------------
* Pins
*----------------------------------------------------------------------------*/
// Number of pins defined in PinDescription array
#define PINS_COUNT (10u)
#define NUM_DIGITAL_PINS (7u)
#define NUM_ANALOG_INPUTS (6u)
#define NUM_ANALOG_OUTPUTS (1u)
#define analogInputToDigitalPin(p) (p)
#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) )
#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin )
//#define analogInPinToBit(P) ( )
#define portOutputRegister(port) ( &(port->OUT.reg) )
#define portInputRegister(port) ( &(port->IN.reg) )
#define portModeRegister(port) ( &(port->DIR.reg) )
#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER )
/*
* digitalPinToTimer(..) is AVR-specific and is not defined for SAMD
* architecture. If you need to check if a pin supports PWM you must
* use digitalPinHasPWM(..).
*
* https://github.com/arduino/Arduino/issues/1833
*/
// #define digitalPinToTimer(P)
// LEDs
#define PIN_NEOPIXEL (4u)
#define NUM_NEOPIXEL (1u)
#define PIN_JOY_X (0ul)
#define PIN_JOY_Y (1ul)
#define PIN_BUTTON1 (2ul)
#define PIN_BUTTON2 (3ul)
/*
* Analog pins
*/
#define PIN_A0 (0ul)
#define PIN_A1 (1ul)
#define PIN_DAC0 PIN_A0
static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
#define ADC_RESOLUTION 12
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 0
/*
* Wire Interfaces
*/
#define WIRE_INTERFACES_COUNT 0
/*
* USB
*/
#define PIN_USB_HOST_ENABLE (5ul)
#define PIN_USB_DM (6ul)
#define PIN_USB_DP (7ul)
/*
* I2S Interfaces
*/
#define I2S_INTERFACES_COUNT 0
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#ifdef __cplusplus
/* =========================
* ===== SERCOM DEFINITION
* =========================
*/
extern SERCOM sercom0;
extern SERCOM sercom1;
extern SERCOM sercom2;
extern SERCOM sercom3;
extern SERCOM sercom4;
extern SERCOM sercom5;
#endif
// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
#define SERIAL_PORT_USBVIRTUAL Serial
#define SERIAL_PORT_MONITOR Serial
// Serial has no physical pins broken out, so it's not listed as HARDWARE port
#define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1
#endif /* _VARIANT_ARDUINO_ZERO_ */

View file

@ -85,8 +85,12 @@ extern "C"
#define PIN_LED3 PIN_LED_TXL #define PIN_LED3 PIN_LED_TXL
#define LED_BUILTIN PIN_LED_13 #define LED_BUILTIN PIN_LED_13
// DotStar LED // DotStar LED
#define INTERNAL_DS_DATA 7 #define INTERNAL_DS_DATA (7u)
#define INTERNAL_DS_CLK 8 #define INTERNAL_DS_CLK (8u)
#define PIN_DOTSTAR_DATA (7u)
#define PIN_DOTSTAR_CLK (8u)
#define PIN_DOTSTAR_CLOCK PIN_DOTSTAR_CLK
#define DOTSTAR_NUM (1u)
/* /*
* Analog pins * Analog pins

View file

@ -0,0 +1,31 @@
#
# Arduino Zero OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Define 'reset' command
define reset
info reg
break main
# End of 'reset' command
end
target remote | openocd -c "interface cmsis-dap" -c "set CHIPNAME at91samd21e18" -f target/at91samdXX.cfg -c "gdb_port pipe; log_output openocd.log"

View file

@ -0,0 +1,216 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__text_start__ = .;
KEEP(*(.sketch_boot))
. = ALIGN(0x2000);
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(16);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View file

@ -0,0 +1,214 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
* __ram_end__
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
__text_start__ = .;
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(16);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM) ;
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

View file

@ -0,0 +1,28 @@
#
# Adafruit ItsyBitsy M0 OpenOCD script.
#
# Copyright (c) 2014-2015 Arduino LLC. All right reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# chip name
set CHIPNAME at91samd21e18
set ENDIAN little
# choose a port here
set telnet_port 0
source [find target/at91samdXX.cfg]

View file

@ -0,0 +1,21 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// API compatibility
#include "variant.h"

View file

@ -0,0 +1,64 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "variant.h"
#include "Arduino.h"
/*
* Pins descriptions
*/
const PinDescription g_APinDescription[]=
{
// TRRS Tip, D0 / DAC / A0
{ PORTA, 2, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel0, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_2 },
// TRRS Tip Switch, D1, A1
{ PORTA, 3, PIO_ANALOG, PIN_ATTR_ANALOG, ADC_Channel1, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_3 },
// TRRS Ring 1, D2, A2
{ PORTA, 6, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel6, PWM1_CH0, TCC1_CH0, EXTERNAL_INT_6 },
// TRRS Ring 1 Switch, D3, A3
{ PORTA, 7, PIO_ANALOG, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER|PIN_ATTR_ANALOG), ADC_Channel7, PWM1_CH1, TCC1_CH1, EXTERNAL_INT_7 },
// TRRS Ring2, D4, A4
{ PORTA, 4, PIO_ANALOG, PIN_ATTR_DIGITAL, ADC_Channel4, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_4 },
// TRRS Sleeve, D5, A5
{ PORTA, 5, PIO_ANALOG, PIN_ATTR_DIGITAL, ADC_Channel5, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_5 },
// Internal NeoPixel / D6
{ PORTA, 1, PIO_ANALOG, PIN_ATTR_ANALOG, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE },
// QT SDA D7
{ PORTA, 8, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel16, PWM0_CH0, TCC0_CH0, EXTERNAL_INT_NMI }, // TCC0/WO[0]
// QT SCL D8
{ PORTA, 9, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), ADC_Channel17, PWM0_CH1, TCC0_CH1, EXTERNAL_INT_9 }, // TCC0/WO[1]
// USB pins D9, D10, D11
{ PORTA, 28, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB Host enable
{ PORTA, 24, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DM
{ PORTA, 25, PIO_COM, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // USB/DP
} ;
const void* g_apTCInstances[TCC_INST_NUM+TC_INST_NUM]={ TCC0, TCC1, TCC2, TC3, TC4, TC5 } ;
// Multi-serial objects instantiation
SERCOM sercom0( SERCOM0 ) ;
SERCOM sercom1( SERCOM1 ) ;
SERCOM sercom2( SERCOM2 ) ;
SERCOM sercom3( SERCOM3 ) ;

View file

@ -0,0 +1,207 @@
/*
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _VARIANT_TRRSTRINKEY_ZERO_
#define _VARIANT_TRRSTRINKEY_ZERO_
// The definitions here needs a SAMD core >=1.6.10
#define ARDUINO_SAMD_VARIANT_COMPLIANCE 10610
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
/** Frequency of the board main oscillator */
#define VARIANT_MAINOSC (32768ul)
/** Master clock frequency */
#define VARIANT_MCK (F_CPU)
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "WVariant.h"
#ifdef __cplusplus
#include "SERCOM.h"
#include "Uart.h"
#endif // __cplusplus
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus
/*----------------------------------------------------------------------------
* Pins
*----------------------------------------------------------------------------*/
// Number of pins defined in PinDescription array
#define PINS_COUNT (10u)
#define NUM_DIGITAL_PINS (7u)
#define NUM_ANALOG_INPUTS (6u)
#define NUM_ANALOG_OUTPUTS (1u)
#define analogInputToDigitalPin(p) (p)
#define digitalPinToPort(P) ( &(PORT->Group[g_APinDescription[P].ulPort]) )
#define digitalPinToBitMask(P) ( 1 << g_APinDescription[P].ulPin )
//#define analogInPinToBit(P) ( )
#define portOutputRegister(port) ( &(port->OUT.reg) )
#define portInputRegister(port) ( &(port->IN.reg) )
#define portModeRegister(port) ( &(port->DIR.reg) )
#define digitalPinHasPWM(P) ( g_APinDescription[P].ulPWMChannel != NOT_ON_PWM || g_APinDescription[P].ulTCChannel != NOT_ON_TIMER )
/*
* digitalPinToTimer(..) is AVR-specific and is not defined for SAMD
* architecture. If you need to check if a pin supports PWM you must
* use digitalPinHasPWM(..).
*
* https://github.com/arduino/Arduino/issues/1833
*/
// #define digitalPinToTimer(P)
// LEDs
#define PIN_NEOPIXEL (6u)
#define NUM_NEOPIXEL (1u)
#define PIN_TIP (0ul)
#define PIN_TIP_SWITCH (1ul)
#define PIN_RING1 (2ul)
#define PIN_RING1_SWITCH (3ul)
#define PIN_RING2 (4ul)
#define PIN_SLEEVE (5ul)
/*
* Analog pins
*/
#define PIN_A0 (0ul)
#define PIN_A1 (1ul)
#define PIN_A2 (2ul)
#define PIN_A3 (3ul)
#define PIN_A4 (4ul)
#define PIN_A5 (5ul)
#define PIN_DAC0 PIN_A0
static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
static const uint8_t A2 = PIN_A2;
static const uint8_t A3 = PIN_A3;
static const uint8_t A4 = PIN_A4;
static const uint8_t A5 = PIN_A5;
#define ADC_RESOLUTION 12
/*
* SPI Interfaces
*/
#define SPI_INTERFACES_COUNT 1
#define PIN_SPI_MISO PIN_RING1
#define PIN_SPI_MOSI PIN_RING2
#define PIN_SPI_SCK PIN_SLEEVE
#define PERIPH_SPI sercom0
#define PAD_SPI_TX SPI_PAD_0_SCK_1
#define PAD_SPI_RX SERCOM_RX_PAD_2
static const uint8_t SS = PIN_TIP;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
/*
* Wire Interfaces, fake just for compilation
*/
#define WIRE_INTERFACES_COUNT 2
// QT Port
#define PIN_WIRE_SDA (7ul)
#define PIN_WIRE_SCL (8ul)
#define PERIPH_WIRE sercom2
#define WIRE_IT_HANDLER SERCOM2_Handler
// second, sekret I2C on the headphone jack
#define PIN_WIRE1_SDA PIN_RING2
#define PIN_WIRE1_SCL PIN_SLEEVE
#define PERIPH_WIRE1 sercom0
#define WIRE1_IT_HANDLER SERCOM0_Handler
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
/*
* USB
*/
#define PIN_USB_HOST_ENABLE (9ul)
#define PIN_USB_DM (10ul)
#define PIN_USB_DP (11ul)
/*
* I2S Interfaces
*/
#define I2S_INTERFACES_COUNT 0
#ifdef __cplusplus
}
#endif
/*----------------------------------------------------------------------------
* Arduino objects - C++ only
*----------------------------------------------------------------------------*/
#ifdef __cplusplus
/* =========================
* ===== SERCOM DEFINITION
* =========================
*/
extern SERCOM sercom0;
extern SERCOM sercom1;
extern SERCOM sercom2;
extern SERCOM sercom3;
extern SERCOM sercom4;
extern SERCOM sercom5;
#endif
// These serial port names are intended to allow libraries and architecture-neutral
// sketches to automatically default to the correct port name for a particular type
// of use. For example, a GPS module would normally connect to SERIAL_PORT_HARDWARE_OPEN,
// the first hardware serial port whose RX/TX pins are not dedicated to another use.
//
// SERIAL_PORT_MONITOR Port which normally prints to the Arduino Serial Monitor
//
// SERIAL_PORT_USBVIRTUAL Port which is USB virtual serial
//
// SERIAL_PORT_LINUXBRIDGE Port which connects to a Linux system via Bridge library
//
// SERIAL_PORT_HARDWARE Hardware serial port, physical RX & TX pins.
//
// SERIAL_PORT_HARDWARE_OPEN Hardware serial ports which are open for use. Their RX & TX
// pins are NOT connected to anything by default.
#define SERIAL_PORT_USBVIRTUAL Serial
#define SERIAL_PORT_MONITOR Serial
// Serial has no physical pins broken out, so it's not listed as HARDWARE port
#define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1
#endif /* _VARIANT_ARDUINO_ZERO_ */