Compare commits

...
125 Commits
Author SHA1 Message Date
majbthrd 47a4d9f803 Add pico-debug support (#239) 2021-07-07 12:55:03 -07:00
Earle F. Philhower, III e4185ce4ce Update toolchain, add CMSIS-DAP to OpenOCD (#241)
Enable use of the included openocd binary with pico-debug
2021-07-05 19:29:47 -07:00
Earle F. Philhower, III c539742e13 Disable ignored-qualifier warning in SDK (#238)
The Pico SDK has some magic with const pointers that generates lots of
"ignored qualifer" warnings on the more pedantic modes.  To clean the
normal builds up, disable this warning for now.  At some point a PR to
the PICO-SDK may be indicated.
2021-07-04 13:46:50 -07:00
Earle F. Philhower, III ebd2289971 Add warning flags to build, catch missing return (#237)
Fixes #236

Compiler warning flags were completely ignored/missed in platform.txt.
Add them, as normal, and include -Werror=return-type because GCC will
produce crashing apps when a function return value is missing.
2021-07-04 12:30:59 -07:00
Earle F. Philhower, III d67329a2b8 Rename assembly dir to boot2, only has boot2.Ss (#230) 2021-06-30 08:42:13 -07:00
Ha Thach 3a9703fc20 Update tinyusb 1.3.0 (#228)
* update included tinyusb to 1.2.0

move tusb_config.h from core to library for more portability

* pump tinyusb

* update tinyusb to 1.3.0

* try to fix ci warning
2021-06-30 08:22:36 -07:00
Earle F. Philhower, III 856b105ab9 Clean up include paths, remove duplicates/invalids (#229) 2021-06-30 08:13:19 -07:00
Earle F. Philhower, III 03e740a511 Add CPU cycle counter accessors (#226)
Use the 24-bit SYSTICK peripheral, wrapped in logic to extend it to a
full 32 or 64bits.  W/o the wrapper, SYSTICK will wrap around in ~100ms.

Adds rp2040.getCycleCount() and rp2040.getCycleCount64()

Clean up the libpico build process as crt0.S from the pico-sdk should
be directly used.

Clean up the keywords file.
2021-06-28 20:53:40 -07:00
Earle F. Philhower, III e628c8e211 Upgrade Newlib to include 64-bit/8-bit %llu/%hhd (#227) 2021-06-28 20:46:08 -07:00
Ha Thach 7eca6c609f Use correct tusb_config.h for built-in usb (pico-sdk) (#219)
Fix issue with usbd_desc_cfg value may not be initialized as zero.
2021-06-26 09:37:41 -07:00
Earle F. Philhower, III f299120798 Remove accidental debug message 2021-06-25 18:47:02 -07:00
Earle F. Philhower, III aac8146f00 Clear I2C status on short slave reads
Fixes #222

The HW needs to have the TXC_ABRT flag cleared when a slave transmission is
cut short by the master, or else it will effectively break the I2C bus and
never recover.
2021-06-25 18:39:44 -07:00
Earle F. Philhower, III 35c974d4c0 Fix file creation on SD and SDFS (#216)
The O_CREAT/etc. flags on the Pico are a full 32-bits in size, but the
core was generating a flag for SdFat using an 8-bit type, so all the
O_CREAT, O_TRUNC, O_APPEND, etc. flags got cut off.

Fix the flag size.

Fixes #214
2021-06-19 12:15:11 -07:00
Earle F. Philhower, III 27476815ab Fix SerialUART flush (#215)
Serial1.flush/Serial2.flush was not waiting for the proper FIFO to clear.
Use the proper call from the Pico SDK.

Thanks to Peter Remias for noting it.
2021-06-16 08:25:24 -07:00
Earle F. Philhower, III b02b9c4be8 Add PDM library for Arduino Nano RP2040 Connect (#213)
* Add PDM library for Arduino Nano RP2040 Connect

* No PDM test in CI, only works on Arduino Nano RP2040
2021-06-16 08:17:09 -07:00
Earle F. Philhower, III 6afcf5881d Initial Arduino Nano RP2040 Connect support (#212)
Thanks to @Claupio for the bringup!
Reference #208
2021-06-14 08:59:52 -07:00
Earle F. Philhower, III 30704a7c5e Obey timeout value on SerialUART.read/.peek (#211)
Fixes a hang when reading from the Serial UART ports because before the
core would pause indefinitely for the next character.

Now, wait up to Serial.setTimeout() milliseconds and if it times out
return -1 to the app.

Fixes #210
2021-06-13 14:11:23 -07:00
Earle F. Philhower, III 08b6748d79 Update to PICO-SDK version 1.2.0 (#207)
Minor rev to the tinyUSB version used, new ID function.
2021-06-11 12:48:09 -07:00
Earle F. Philhower, III bedfbda372 Clear PIO FIFOs when updating Tone and Servos (#206)
The PIO programs that generate tone() and Servo() use the TX FIFO to
receive updates to the period/duty cycle.

The original code would push into the FIFO (potentially blocking the
app if the FIFO was full) and generate at least one cycle of every
value written into the control.  Basically, the output would
lag the changes by 1 cycle or more (which could be 20ms+ on Servo).

Fix this by clearing any old, ungrabbed values from the FIFO before
sending a new one to the program.  Instead of a FIFO, there is
effectively now just a control register and updates will be immediate.

Update the Siren.ino example with delays because now the tone() calls
will not block and run 10x+ faster.
2021-06-11 12:27:48 -07:00
Earle F. Philhower, III 9fbf6ab35d Clean up Arduino.h header, remove duplicates (#205)
Many functions are defined inside the api/Common.h, so remove them from
the Arduino.h header to have them appear only once.

Fix up the abs() macro to avoid macro problems, add round()
2021-06-11 12:23:23 -07:00
Earle F. Philhower, III 793496da98 Set GPIO digital output on digitalWrite (#203)
Fixes #202
2021-06-10 07:58:09 -07:00
Earle F. Philhower, III 81cbf8357d Update README.md 2021-06-08 08:39:58 -07:00
Earle F. Philhower, III 55a260e4e8 Update README.md 2021-06-08 08:35:32 -07:00
Earle F. Philhower, III 5c71564844 Add PIOASM online tool link, thanks @jake653! (#197) 2021-06-08 08:34:53 -07:00
Earle F. Philhower, III bf4f0454e1 Update README.md 2021-06-08 08:02:07 -07:00
Earle F. Philhower, III 33b9e915d9 Add new boards to package.json 2021-06-08 07:02:25 -07:00
Earle F. Philhower, III 77712f5904 Add SparkFun ProMicro RP2040 (#196)
It's still OOS, so hookup taken from their schematics.
2021-06-08 06:55:13 -07:00
Earle F. Philhower, III c02388dfbe Update README.md 2021-06-07 15:12:03 -07:00
Earle F. Philhower, III 56dae62b8e Add back Featherwing CI test (#195) 2021-06-07 13:54:25 -07:00
Earle F. Philhower, III 53b52a975a Update README.md 2021-06-07 07:10:41 -07:00
Earle F. Philhower, III f87ccacdb1 Upgrade to GCC 10.3. Fix OpenOCD packaging (#194)
GCC 10.2 has a bug which causes Windows to rebuild every library on every
compile, instead of caching the first results.

Upgrade to GCC 10.3 which has this fixed.

Add proper OpenOCD executables for non-Linux x86_64 archs.
2021-06-06 22:43:26 -07:00
Limor "Ladyada" Friedandhathach d2a2fcb89d Add a new board - the Adafruit Macropad w/RP2040 (#191)
* add two variant files

* add trinkey and stemma friend

* add fast SPI transfer using pico-sdk blocks

* update makeboards.py for new variants

- STEMMA Friend RP2040
- Trinkey RP2040 QT

* run astyle on SPI library

* fix auto -> ssize type

* astyled

* woops ssizet != sizet!

* a nice day for a new board definition! this is a macropad with 12 keys, oled and rotary encoder

Co-authored-by: hathach <thach@tinyusb.org>
2021-06-06 12:53:06 -07:00
Earle F. Philhower, III c65c4bfb4e Allow continuous tone frequency changes (#186)
Fixes #121
Supersedes #185

Redo the PIO program to allow the tone generator on a pin to be updated
without interruption, at waveform boundaries.  This allows for things like
sirens or slurs to be implemented simply.

Use an alarm, not the PIO hardware, to manage time-limited tones().

Add a simple siren example.
2021-06-04 02:45:13 -07:00
Ha Thach 6431b8157b Add tone music example (#185) 2021-06-04 02:39:04 -07:00
per1234 7d1e83b416 Use optimal bundled library names (#183)
When multiple libraries contain files matching an #include directive in the program, the Arduino build system must pick
one to use for compilation. Multiple factors are used in order to make an intelligent determination of which library is
best.

In order to enhance this determination, the closeness of match between the library.properties name value and the
filename in the #include directive is being added as one of those factors. This new factor is referred to as
"Library Name Priority".

Unfortunately, this change can result in platform bundled libraries which had previously been correctly correctly chosen
no longer being given priority over their equivalent standalone libraries, which may be incompatible or not optimized
for the platform's boards.

This priority inversion only occurs when all the following conditions are true:

- There is a standalone library installed which provides a header filename collision.
- The platform bundled library is architecture optimized (e.g., architectures=esp32).
- The standalone library is architecture compatible (architectures=*).
- The standalone library has equal "Folder Name Priority".
- The standalone library has better "Library Name Priority" (e.g., name=SD vs name=SD(ESP32) for a library with primary
  header file SD.h.

The fix is to simply give the platform bundled library a perfect "Library Name Priority".

Some platform bundled libraries were given a modified name as a workaround to a bug in the Arduino IDE's Library Manager
which caused Library Manager to always show the library as updatable under specific circumstances. That bug was fixed in
Arduino IDE 1.8.6, ~3 years ago.
2021-05-31 07:32:20 -07:00
Earle F. Philhower, III fd685aac82 PANIC on attempting an invalid setXXX pin (#182)
Fixes #169

Trying to change pinout while running, or to an illegal configuration,
will now immediately panic() with an error message.  Such an attempt
is a pretty big problem since pinouts are hardware related/static.

Prior code would fail silently and return false, but nobody checked
the setXXX return values, anyway.
2021-05-29 10:50:13 -07:00
Earle F. Philhower, III 79539d7d8d Re-add pico-sdk/extra submodules to release ZIP (#181) 2021-05-28 19:55:09 -07:00
Earle F. Philhower, III 457e763466 Update release-to-publish.yml 2021-05-28 19:39:29 -07:00
Earle F. Philhower, III 0da71844fd Install PyGitHub before publishing 2021-05-28 19:29:57 -07:00
Earle F. Philhower, III 1fd0b0404d Add TinyUSB include to all libs (#180)
Fixes #167

For Serial when selecting TinyUSB.  Can't include in the core because Arduino IDE
will not link in libraries called from the core.  Instead, add the header to all
the standard libraries in the hope it will still catch some user cases where they
use these libraries.

See https://github.com/earlephilhower/arduino-pico/issues/167#issuecomment-848622174
2021-05-28 19:23:19 -07:00
Earle F. Philhower, III d0f3e89954 Create README describing release publish process (#179) 2021-05-28 19:12:28 -07:00
Earle F. Philhower, III 9c95c4d7ab CI to update JSON when releases are published (#178) 2021-05-28 19:04:12 -07:00
Earle F. Philhower, III 7e0eefe802 Typo fix in CI script 2021-05-28 15:14:04 -07:00
Earle F. Philhower, III 5d7ff8e628 Fix release tagging 2021-05-28 15:11:44 -07:00
Earle F. Philhower, III 83163797c6 Update tag-to-draft-release.yml 2021-05-28 15:00:02 -07:00
Earle F. Philhower, III 6393eac4f8 Try and fix multiline comment on release build 2021-05-28 14:45:02 -07:00
Earle F. Philhower, III 376e4770f3 Update build_boards_manager_package.sh 2021-05-28 14:28:48 -07:00
Earle F. Philhower, III c91b0ae605 Add'l release cleanup 2021-05-28 14:12:37 -07:00
Earle F. Philhower, III b14c49ad5d Fix log generation in CI package stage 2021-05-28 14:07:11 -07:00
Earle F. Philhower, III 88485e56f5 More CI packaging work 2021-05-28 13:50:29 -07:00
Earle F. Philhower, III e339e4f51c Clean up build release script 2021-05-28 13:41:30 -07:00
Earle F. Philhower, III a6307afadd Update tag-to-draft-release.yml 2021-05-28 13:34:30 -07:00
Earle F. Philhower, III 436bf0fe41 Update upload_release.py 2021-05-28 13:24:30 -07:00
Earle F. Philhower, III e72975af68 Update tag-to-draft-release.yml 2021-05-28 13:20:18 -07:00
Earle F. Philhower, III 099b7034d4 Update tag-to-draft-release.yml 2021-05-28 13:19:41 -07:00
Earle F. Philhower, III 5173d2668e Use CI to build draft releases on a tag push (#177)
Ensure no stray files get sucked into the release ZIP by using a clean CI
image to build the package and JSON file.  Auto-populate the draft with
the git commits since the last release.
2021-05-28 13:15:09 -07:00
Earle F. Philhower, III ab02801d76 Check in Arduino API directory to avoid symlink (#176)
Fixes #171

Under Windows, it is very hard to make a symlink and by default git won't
make one to the Arduino API directory, causing annoying build errors.

Avoid the issue by duplicating the ArduinoAPI directory explicitly and using
CI to verify that there are no differences between the two.
2021-05-28 08:50:48 -07:00
Earle F. Philhower, III e0d33e2536 Try to mount Pico drive if not already present (#175)
Fixes #27

As @vslinuxdotnet discovered, sometimes the Pico firmware update emulated USB
stick does not get automounted under Linux.  Add logic to attempt to use
standard tools to mount it to the uploader, only tried if no drives are
detected normally.
2021-05-27 13:07:55 -07:00
Earle F. Philhower, III 657464f134 Display offending lines in Style CI failure (#174) 2021-05-26 18:40:28 -07:00
Brian Slesinsky 799e3a03f5 Docs: larify pin assignments for i2c (#173) 2021-05-26 18:25:48 -07:00
Earle F. Philhower, III 6d11ec6e70 Update README.md 2021-05-26 18:12:50 -07:00
Limor "Ladyada" Fried 860b43b342 Two board variant definitions and a high speed SPI transfer function (#172) 2021-05-26 18:09:49 -07:00
Earle F. Philhower, III 35260c1f0f Add baud rate to main Serial.begin() (#170) 2021-05-26 02:45:18 -07:00
Brian Slesinsky a1c9dfe84d Add TinyUSB usage note. (#168) 2021-05-26 02:17:42 -07:00
Earle F. Philhower, III 8016a932f3 Add astyle format, boards.txt, and package check (#166)
Miscellaneous CI checks for code style, boards.txt update, and that all
referenced packages are available.
2021-05-24 15:01:03 -07:00
Earle F. Philhower, III fd4f7bbf0b Add TinyUSB examples to CI (#163) 2021-05-23 09:29:44 -07:00
Earle F. Philhower, III 77eae66cb1 Add Win and Mac build to CI (#159) 2021-05-22 03:42:22 -07:00
Earle F. Philhower, III eb6750d7d4 Add Arduino examples to CI (#158)
* Add Arduino examples to CI
* Remove bad example sketches
2021-05-22 03:24:56 -07:00
Earle F. Philhower, III 83a32f1ba3 Add compilation to CI (#155)
Stolen from ESP8266, modified to run basic sanity compiles on the core.

Fix warnings identified by the new checks.
2021-05-22 02:58:57 -07:00
Earle F. Philhower, III 10a44c83f1 Add quasi-sane abs() implementation to Arduino.h (#157)
As mentioned in https://github.com/earlephilhower/arduino-pico/discussions/156#discussion-3376456
2021-05-21 15:32:31 -07:00
Earle F. Philhower, III a55fac8c82 Typo fix in docs 2021-05-21 13:40:02 -07:00
Earle F. Philhower, III 052331168e Fix repo spelling issues (#152) 2021-05-19 18:03:12 -07:00
Scott Smith 4509e6cf38 Fix debug level "Wire" compile error (#151)
* add missing character for debug level "Wire"

if Debug Level "Wire" is chosen, the compiler posts error
> arm-none-eabi-g++: error: DDEBUG_RP2040_WIRE: No such file or directory

Add the missing '-' to correct the issue.

* change must be made via makeboards.py

The generator script needs to be fixed and rerun. If we just update the boards.txt, changes will be lost on a rebuild.

* Update boards.txt

boards.txt as generated by revised makeboards.py

* correct spelling issue for CI tool
2021-05-19 17:46:21 -07:00
Earle F. Philhower, III 69876c7d03 Place CI script in the right spot 2021-05-19 17:21:56 -07:00
Earle F. Philhower, III a6bd1c55ac Add initial CI check (spelling) (#150) 2021-05-19 17:21:10 -07:00
Earle F. Philhower, III 0d593252e6 Ignore non-UTF8 chars in UF2 upload (#148)
Fixes #95
2021-05-19 15:38:56 -07:00
Earle F. Philhower, III a1dc348ec7 Fix over/underclock support (#147)
Removed needed header from main.cpp during prior cleanup.  Re-add.

Fixes #146
2021-05-19 12:28:47 -07:00
Earle F. Philhower, III a0dac52e0e Rationalize Adafruit Feather infra, update docs (#145)
Use same board.txt format as other Adafruit boards.
Add in quick note about the new USB stack to the docs.
2021-05-19 10:07:03 -07:00
Ha Thach 010039578f Add Adafruit ItsyBitsy and QTPy RP2040 (#144)
* add adafruit qtpy and itsybitsy rp2040
* change qtpy boot2 to generic_03h_4
2021-05-19 09:39:19 -07:00
Ha Thach f8a2f38fe7 Port Adafruit_TinyUSB_Arduino lib (#127)
* initial tinyusb lib port

* add Adafruit_TinyUSB_Arduino as submodules

* add yield() to main loop

* sync with tinyusb lib latest

* add USB manufacturer and product

* fix typo in tinyusb lib

* sync with master

updating implementation

* Rationalize link stage command line

Make the build process less insane.

* clean up delay

* clean up platform and board

* update makeboards.py for generating usbstack menu

* update tinyusb lib to 1.0.0
2021-05-18 18:10:47 -07:00
Earle F. Philhower, III 39d1a286a8 Rationalize link stage command line (#143) 2021-05-18 02:47:57 -07:00
Khoi Hoang 7dc0aa16ec Add defs for compatibility (#142)
Add definitions for compatibility to many platforms and libraries
- clockCyclesPerMicrosecond()
- clockCyclesToMicroseconds(a)
- microsecondsToClockCycles(a)
2021-05-16 20:48:44 -07:00
Khoi Hoang b504feaa50 Add -DBOARD_NAME="{build.board}" (#136)
Add -DBOARD_NAME="{build.board}" to Compile patterns to facilitate using BOARD_NAME in sketches
2021-05-16 08:10:10 -07:00
Earle F. Philhower, III fa982c8dd0 Update index.md 2021-05-16 04:14:37 -07:00
Earle F. Philhower, III f1f62264fe Split newlib syscall support to its own file (#141) 2021-05-16 03:59:32 -07:00
Earle F. Philhower, III 1de1d04fb4 Remove hack sync__synchronize from main.cpp (#139)
Was required before due to C++ internals, but is not needed anymore thanks
to #137
2021-05-16 03:49:22 -07:00
Earle F. Philhower, III af8b548e29 Add time support (time, gettimeofday, etc.) (#138) 2021-05-16 03:23:25 -07:00
Earle F. Philhower, III 0550fe75b2 Massively reduce generated code and RAM size (#137)
Older builds included C++ locale information in RAM/flash as well as a
bunch of exception code which can't get called since they're not enabled.

Remove them by adjusting final link command and not instantiating them
in main.cpp in the first place.

Blink went from:
> Sketch uses 215604 bytes (10%) of program storage space. Maximum is 2093056 bytes.
> Global variables use 18152 bytes (6%) of dynamic memory, leaving 243992 bytes for local variables. Maximum is 262144 bytes.

To:
> Sketch uses 56112 bytes (5%) of program storage space. Maximum is 1044480 bytes.
> Global variables use 12152 bytes (4%) of dynamic memory, leaving 249992 bytes for local variables. Maximum is 262144 bytes.

For a savings of **155KB of flash** and **6KB of RAM**
2021-05-16 02:14:58 -07:00
Earle F. Philhower, III ef6024911a Merge branch 'master' of https://github.com/earlephilhower/arduino-pico 2021-05-15 16:29:46 -07:00
Earle F. Philhower, III 78c021aadf Add forgotten USB header 2021-05-15 16:29:32 -07:00
Earle F. Philhower, III fdcfe549cb Add forgotten USB header 2021-05-15 16:29:08 -07:00
Earle F. Philhower, III a64339b195 Update README.md 2021-05-15 16:19:55 -07:00
Earle F. Philhower, III 9725155f25 Fix SPI default pinouts to SPI0, not SPI1 pins (#135)
Should fix #134 .  The SPI pin macros were set using the SPI1 set, not
the SPI0 set of pins it should have been using.
2021-05-15 16:13:11 -07:00
Earle F. Philhower, III cdc2831103 Update install.rst 2021-05-15 12:24:14 -07:00
Earle F. Philhower, III d3c5039c2f Clean up USB includes and naming 2021-05-14 12:08:00 -07:00
Earle F. Philhower, III 13f4be33bc Update index.rst 2021-05-14 08:18:33 -07:00
Earle F. Philhower, III 6cf90add8c Add basic USB documentation 2021-05-14 07:58:32 -07:00
Earle F. Philhower, III 2723a6e71d Update README.md 2021-05-14 07:51:31 -07:00
Earle F. Philhower, III 4a8ac3d902 Add support for shared USB Serial, Keyboard, Mouse (#132)
Use a shared infrastructure based on TinyUSB, allow users to use sketches
with ported Arduino Keyboard and Mouse libraries.
2021-05-13 19:20:24 -07:00
Earle F. Philhower, III 9c17986ae6 Point people to READTHEDOCS for help, not GitHub
Most users w/the Library Manager will get a little nervous with the GH site.
The ReadTheDocs site includes links to the GH site, too, so they can still
find the origin.
2021-05-13 17:47:56 -07:00
Earle F. Philhower, III 93c30e0233 Reorder TOC slightly 2021-05-13 00:20:48 -07:00
Earle F. Philhower, III f327e09e3e Add stdlib_noniso.h to Arduino.h (#131)
Per #130 request, the dtostrf() definition and others were not visible.
2021-05-13 00:15:22 -07:00
drmpf c2cf09acbf SF_printable_fix (#130)
Added Printable.h in dir where it can be found
2021-05-13 00:06:16 -07:00
Earle F. Philhower, III 72a644f77d Update README.md 2021-05-11 12:31:02 -07:00
Earle F. Philhower, III a259eb7396 Clean up directory organization, libpico build (#129)
Also add a README.md to the tools directory.
2021-05-11 12:30:14 -07:00
Earle F. Philhower, III 7f8f0cc137 Clean up platform.txt, libpico build (#128)
Add -fno-exceptions and -fno-rtti where possible.
Move insanely long strings to @files to shrink platform.txt and make
build command line shorter.
2021-05-10 17:57:24 -07:00
Earle F. Philhower, III d776ec2f56 Fix memory leak in tone/noTone calls (#125)
Was never deleting the tone object on noTone, so eventually the leaked
objects would fill up heap and cause a crash.

Fixes #121
2021-05-08 11:19:32 -07:00
Earle F. Philhower, III 8ae69a3463 Minor keyword and mutex fixes for multicore 2021-05-08 11:13:26 -07:00
Earle F. Philhower, III 763846aee8 Additional multicore fixes, BOOTSEL and PIO (#123)
BOOTSEL needs to be multicore protected, too.
Reading BOOTSEL required disabling the flash interface, so the other
core needs to be idles while this runs.

Make the PIO program object multicore safe, too, so that if both cores
try to load a program they won't step on each other.
2021-05-07 16:03:21 -07:00
Earle F. Philhower, III 2da190f5b4 Update README.md 2021-05-06 20:57:51 -07:00
Earle F. Philhower, III 9b2f40c06a Update multicore.rst
Fix some typos
2021-05-06 20:48:06 -07:00
Earle F. Philhower, III f1e77995f5 Look for UF2 drives in additional spots on Linux (#37)
Fixes #28
2021-05-06 20:04:36 -07:00
Earle F. Philhower, III 70a30dc219 Add multicore safety, FIFO, update pico-sdk (#122)
Update pico-sdk to 1.1.2

Add methods to block the opposite core while doing flash updates.
Ensure opposite core is stopped in LittleFS and EEPROM while doing
flash updates.

Update documentation with new calls.
2021-05-06 19:57:21 -07:00
Earle F. Philhower, III 6cf0b30fdf Merge branch 'master' of https://github.com/earlephilhower/arduino-pico 2021-05-06 08:28:35 -07:00
Earle F. Philhower, III a62075d8f1 Add HWSerial redirect
Fixes #120
2021-05-06 08:28:08 -07:00
Oğuzhan Başer 47915df2da PWM functions definitions missing (#114)
* add keywords file

* Add PWM function definitions
2021-04-27 07:11:02 -07:00
Earle F. Philhower, III 1815c45f92 Add multicore support with setup1/loop1 (#113)
Support running code on the second core by adding a setup1() and/or
a loop1() routine to a sketch.  These functions operate exactly like
the normal Arduino ones, and anything they call will be run on
the second core automatically.

Add a simple multicore example.
2021-04-24 11:40:29 -07:00
Earle F. Philhower, III 2d58f08bf2 Update README.md 2021-04-22 10:39:29 -07:00
Earle F. Philhower, III 6e51516d6c Set default pins for peripherals per datasheet (#103)
Using the official Raspberry Pi Pico datasheet and the Adafruit Feather
RP2040 schematic, set the default pins for peripherals to match.

Fixes #92
2021-04-16 10:23:43 -07:00
Earle F. Philhower, III 011ecdb5a6 More multicore safety plumbing, IRQs, analogXXX (#107)
Keep a per-core IRQ stack for noInterrupts since each core has its own
enable/disable.

Make analogRead/analogWrite multicore safe
2021-04-15 17:16:13 -07:00
Earle F. Philhower, III b793ad5533 Make Tone multicore safe (#106)
Add a mutex around the Tone mapping for multicore safety.
2021-04-15 16:21:47 -07:00
Earle F. Philhower, III b5aeb84cb3 Add NOT_AN_INTERRUPT define (#105)
Fix #104
2021-04-15 12:50:35 -07:00
Earle F. Philhower, III d490499c86 Add note about Win7 driver installation (#102)
Fixes #96
2021-04-13 18:11:48 -07:00
Earle F. Philhower, III 9e0e266b4f Add hardware_dma include path (#101)
Fix #100
2021-04-13 15:44:27 -07:00
Earle F. Philhower, III 47c12047da Remove api from include path, add redirects
Can't have cores/rp2040/api in the include path because the Arduino API
dir has a "String.h" file.  On Windows, because it is case-insensitive
normally, this overrides the POSIX "string.h" header leading to bad
stuff.

Add manual redirect includes for commonly accessed headers in the
cores/rp2040 path instead.
2021-04-09 05:38:35 -07:00
201 changed files with 15409 additions and 2721 deletions
+186
View File
@@ -0,0 +1,186 @@
# Run whenever a PR is generated or updated.
name: Arduino-Pico CI
on:
pull_request:
jobs:
# Me no spell so good
code-spell:
name: Check spelling
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Run codespell
uses: codespell-project/actions-codespell@master
with:
skip: ./pico-extras,./ArduinoCore-API,./libraries/SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api
ignore_words_list: ser,DOUT
# Consistent style
astyle:
name: Style, Boards, Package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: false
- name: Check package references
run: |
./tests/ci/pkgrefs_test.sh
- name: Check boards.txt was not edited after makeboards.py
run: |
./tools/makeboards.py > boards.txt
- name: Run astyle on all code/examples
run: |
sudo apt update
sudo apt install astyle
./tests/restyle.sh
# If anything changed, GIT should return an error and fail the test
git diff --exit-code
- name: Check Arduino API copy is clean
run: |
git submodule update --init ./ArduinoCore-API
diff -r ./cores/rp2040/api ./ArduinoCore-API/api
# Build all examples on linux (core and Arduino IDE)
build-linux:
name: Build ${{ matrix.chunk }}
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1, 2, 3]
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v2
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketches
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
BUILD_PARITY: custom
mod: 4
rem: ${{ matrix.chunk }}
run: |
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init
cd ..
bash ./tests/build.sh
# Build TinyUSB examples, requires custom build command line
build-tinyusb:
name: Build TinyUSB Examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v2
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketches
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
BUILD_PARITY: custom
run: |
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init
cd ..
bash ./tests/build-tinyusb.sh
# Single build under Windows to ensure the Win toolchain is good.
build-windows:
name: Windows
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache Windows toolchain
id: cache-windows
uses: actions/cache@v2
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketch
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
WINDOWS: 1
BUILD_PARITY: custom
mod: 500
rem: 1
run: |
# Windows has python3 already installed, but it's called "python".
# Copy python.exe to the proper name so scripts "just work".
try { Get-Command python3 } catch { copy (get-command python).source (get-command python).source.Replace("python.exe", "python3.exe") }
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init
cd ..
bash ./tests/build.sh
# Single build under macOS to ensure the Mac toolchain is good.
build-mac:
name: Mac
runs-on: macOS-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Cache Mac toolchain
id: cache-mac
uses: actions/cache@v2
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketch
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
MACOSX: 1
BUILD_PARITY: custom
mod: 500
rem: 1
run: |
cd pico-sdk
git submodule update --init
cd ../pico-extras
git submodule update --init
cd ..
bash ./tests/build.sh
+27
View File
@@ -0,0 +1,27 @@
name: Arduino-Pico Release Publisher
on:
release:
types: [published]
jobs:
package:
name: Update master JSON file
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Deploy updated JSON
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
BUILD_TYPE: package
CI_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
run: |
pip3 install PyGithub
TAG=$(git describe --exact-match --tags)
curl -L -o package_rp2040_index.json "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/$TAG/package_rp2040_index.json"
./package/update_release.py --token ${CI_GITHUB_API_KEY} --repo "$GITHUB_REPOSITORY" --tag global package_rp2040_index.json
@@ -0,0 +1,43 @@
# Whenever a tag of the form #.xxxx is pushed against master, generate a
# draft release and upload the ZIP and JSON file to it. Maintainers then
# will manually add the changelist and publish it.
name: Arduino-Pico Draft Release
on:
push:
tags:
# Run for tags of the x.x.x* form (i.e. 3.0.0, 3.0.0-beta, etc.).
- '[0-9]+.[0-9]+.[0-9]+*'
jobs:
package:
name: Package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: true
fetch-depth: 0
- uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Build package JSON
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
BUILD_TYPE: package
CI_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
run: |
(cd pico-sdk && git submodule update --init)
(cd pico-extras && git submodule update --init)
(cd ./package && bash ./build_boards_manager_package.sh)
pip3 install PyGithub
# Create a draft release and upload the ZIP and JSON files.
# This draft is not visible to normal users and needs to be
# updated manually with release notes and published from the
# GitHub web interface.
json=$(find ./package/versions -name package_rp2040_index.json)
log=$(find ./package/versions -name package_rp2040_index.log)
zip=$(find ./package/versions -name rp2040*zip)
tag=$(find ./package/versions -name package_rp2040_index.tag -exec cat \{\} \;)
python3 ./package/upload_release.py --repo "$GITHUB_REPOSITORY" --token "$CI_GITHUB_API_KEY" --tag "$tag" --name "Release $tag" --msg "@$log" "$zip" "$json"
-2
View File
@@ -1,5 +1,3 @@
.DS_Store
system
tools/dist
cores/rp2040/api
+9
View File
@@ -16,3 +16,12 @@
[submodule "pico-extras"]
path = pico-extras
url = https://github.com/raspberrypi/pico-extras.git
[submodule "libraries/Keyboard"]
path = libraries/Keyboard
url = https://github.com/earlephilhower/Keyboard
[submodule "libraries/Mouse"]
path = libraries/Mouse
url = https://github.com/earlephilhower/Mouse
[submodule "libraries/Adafruit_TinyUSB_Arduino"]
path = libraries/Adafruit_TinyUSB_Arduino
url = https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
+46 -28
View File
@@ -1,15 +1,25 @@
# Arduino-Pico [![Join the chat at https://gitter.im/arduino-pico/community](https://badges.gitter.im/arduino-pico/community.svg)](https://gitter.im/arduino-pico/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# Arduino-Pico
[![Release](https://img.shields.io/github/v/release/earlephilhower/arduino-pico?style=plastic)](https://github.com/earlephilhower/arduino-pico/releases)
[![Gitter](https://img.shields.io/gitter/room/earlephilhower/arduino-pico?style=plastic)](https://gitter.im/arduino-pico/community)
Raspberry Pi Pico Arduino core, for all RP2040 boards
This is a port of the RP2040 (Raspberry Pi Pico processor) to the Arduino ecosystem.
This is a port of the RP2040 (Raspberry Pi Pico processor) to the Arduino ecosystem. It uses the bare Raspberry Pi Pico SDK and a custom GCC 10.3/Newlib 4.0 toolchain.
It uses a custom toolset with GCC 10.2 and Newlib 4.0.0, not depending on system-installed prerequisites. https://github.com/earlephilhower/pico-quick-toolchain
# Documentation
See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for more detailed usage information.
There is automated discovery of boards in bootloader mode, so they show up in the IDE, and the upload command works using the Microsoft UF2 tool (included).
# Detailed Documentation
Refer to the examples and https://arduino-pico.readthedocs.io/en/latest/ for more detailed usage information.
# Supported Boards
* Raspberry Pi Pico
* Adafruit Feather RP2040
* Adafruit ItsyBitsy RP2040
* Adafruit Macropad RP2040
* Adafruit QTPy RP2040
* Adafruit STEMMA Friend RP2040
* Adafruit Trinkey RP2040 QT
* Arduino Nano RP2040 Connect (preliminary)
* SparkFun ProMicro RP2040
* Generic (configurable flash, I/O pins)
# Installing via Arduino Boards Manager
**Windows Users**: Please do not use the Windows Store version of the actual Arduino application
@@ -19,7 +29,6 @@ drivers it suggests. Otherwise the Pico board may not be detected. Also, if tr
2.0 beta Arduino please install the release 1.8 version beforehand to ensure needed device drivers
are present. (See #20 for more details.)
Open up the Arduino IDE and go to File->Preferences.
In the dialog that pops up, enter the following URL in the "Additional Boards Manager URLs" field:
@@ -45,7 +54,7 @@ cd ~/Arduino/hardware/pico/rp2040
git submodule update --init
cd pico-sdk
git submodule update --init
cd pico-extras
cd ../pico-extras
git submodule update --init
cd ../tools
python3 ./get.py
@@ -93,25 +102,34 @@ The first line creates a file with the USB vendor and ID of the Picoprobe and te
Once Picoprobe permissions are set up properly, then select the board "Raspberry Pi Pico (Picoprobe)" in the Tools menu and upload as normal.
# Debugging with Picoprobe, OpenOCD, and GDB
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation.
# Uploading Sketches with pico-debug
[pico-debug](https://github.com/majbthrd/pico-debug/) differs from Picoprobe in that pico-debug is a virtual debug pod that runs side-by-side on the same RP2040 that you run your code on; so, you only need one RP2040 board instead of two. pico-debug also differs from Picoprobe in that pico-debug is standards-based; it uses the CMSIS-DAP protocol, which means even software not specially written for the Raspberry Pi Pico can support it. pico-debug uses OpenOCD to handle your sketch uploads, and debugging can be accomplished with CMSIS-DAP capable debuggers including GDB.
# Status of Port
Relatively stable and very functional, but bug reports and PRs always accepted.
* digitalWrite/Read
* shiftIn/Out
* SPI master
* analogWrite/PWM
* tone/noTone
* Wire/I2C Master and Slave
* EEPROM
* USB Serial(ACM) w/automatic reboot-to-UF2 upload)
* Hardware UART
* Servo, glitchless
* Overclocking and underclocking from the menus
* analogRead and Pico chip temperature
Under Windows and macOS, any user should be able to access pico-debug automatically, but under Linux `udev` must be told about the device and to allow normal users access.
To set up user-level access to all CMSIS-DAP adapters on Ubuntu (and other OSes which use `udev`):
````
echo 'ATTRS{product}=="*CMSIS-DAP*", MODE="664", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-CMSIS-DAP.rules
sudo udevadm control --reload
````
The first line creates a file that recognizes all CMSIS-DAP adapters and tells UDEV to give users full access to it. The second causes `udev` to load this new rule. Note that you will need to unplug and re-plug in your device the first time you create this file, to allow udev to make the device node properly.
Once CMSIS-DAP permissions are set up properly, then select the board "Raspberry Pi Pico (pico-debug)" in the Tools menu.
When first connecting the USB port to your PC, you must copy [pico-debug-gimmecache.uf2](https://github.com/majbthrd/pico-debug/releases/) to the Pi Pico to load pico-debug into RAM; after this, upload as normal.
# Debugging with Picoprobe/pico-debug, OpenOCD, and GDB
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation. For [pico-debug](https://github.com/majbthrd/pico-debug/), replace the raspberrypi-swd and picoprobe example OpenOCD arguments of "-f interface/raspberrypi-swd.cfg -f target/rp2040.cfg" or "-f interface/picoprobe.cfg -f target/rp2040.cfg" respectively in the Pico Getting Started manual with "-f board/pico-debug.cfg".
# Features
* Adafruit TinyUSB Arduino (USB mouse, keyboard, flash drive, generic HID, CDC Serial, MIDI, WebUSB, others)
* Generic Arduino USB Serial, Keyboard, and Mouse emulation
* Filesystems (LittleFS and SD/SDFS)
* I2S audio output
* Multicore support (setup1() and loop1())
* Overclocking and underclocking from the menus
* digitalWrite/Read, shiftIn/Out, tone, analogWrite(PWM)/Read, temperature
* Peripherals: SPI master, Wire(I2C) master/slave, dual UART, emulated EEPROM, I2S audio output, Servo
* printf (i.e. debug) output over USB serial
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
@@ -134,9 +152,9 @@ If you want to contribute or have bugfixes, drop me a note at <earlephilhower@ya
* The [Arduino IDE and ArduinoCore-API](https://arduino.cc) are developed and maintained by the Arduino team. The IDE is licensed under GPL.
* The [RP2040 GCC-based toolchain](https://github.com/earlephilhower/pico-quick-toolchain) is licensed under under the GPL.
* The [Pico-SDK](https://github.com/raspberrypi/pico-sdk) and [Pico-Extras](https://github.com/raspberrypi/pico-extras) are by Raspberry Pi (Trading) Ltd and licensed under the BSD 3-Clause license.
* [Arduino-Pico](https://github.com/earlephilhower/arduino-pico) core files are licenses under the LGPL.
* [Arduino-Pico](https://github.com/earlephilhower/arduino-pico) core files are licensed under the LGPL.
* [LittleFS](https://github.com/ARMmbed/littlefs) library written by ARM Limited and released under the [BSD 3-clause license](https://github.com/ARMmbed/littlefs/blob/master/LICENSE.md).
* [UF2CONV.PY](https://github.com/microsoft/uf2) is by Microsoft Corporatio and licensed under the MIT license.
* [UF2CONV.PY](https://github.com/microsoft/uf2) is by Microsoft Corporation and licensed under the MIT license.
* Some filesystem code taken from the [ESP8266 Arduino Core](https://github.com/esp8266/Arduino) and licensed under the LGPL.
-Earle F. Philhower, III
-315
View File
@@ -1,315 +0,0 @@
/*
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "hardware/regs/m0plus.h"
#include "hardware/platform_defs.h"
#include "hardware/regs/addressmap.h"
#include "hardware/regs/sio.h"
#include "pico/binary_info/defs.h"
#ifdef NDEBUG
#ifndef COLLAPSE_IRQS
#define COLLAPSE_IRQS
#endif
#endif
.syntax unified
.cpu cortex-m0plus
.thumb
.section .vectors, "ax"
.align 2
.global __vectors
__vectors:
.word __StackTop
.word _reset_handler
.word isr_nmi
.word isr_hardfault
.word isr_invalid // Reserved, should never fire
.word isr_invalid // Reserved, should never fire
.word isr_invalid // Reserved, should never fire
.word isr_invalid // Reserved, should never fire
.word isr_invalid // Reserved, should never fire
.word isr_invalid // Reserved, should never fire
.word isr_invalid // Reserved, should never fire
.word isr_svcall
.word isr_invalid // Reserved, should never fire
.word isr_invalid // Reserved, should never fire
.word isr_pendsv
.word isr_systick
.word isr_irq0
.word isr_irq1
.word isr_irq2
.word isr_irq3
.word isr_irq4
.word isr_irq5
.word isr_irq6
.word isr_irq7
.word isr_irq8
.word isr_irq9
.word isr_irq10
.word isr_irq11
.word isr_irq12
.word isr_irq13
.word isr_irq14
.word isr_irq15
.word isr_irq16
.word isr_irq17
.word isr_irq18
.word isr_irq19
.word isr_irq20
.word isr_irq21
.word isr_irq22
.word isr_irq23
.word isr_irq24
.word isr_irq25
.word isr_irq26
.word isr_irq27
.word isr_irq28
.word isr_irq29
.word isr_irq30
.word isr_irq31
// Declare a weak symbol for each ISR.
// By default, they will fall through to the undefined IRQ handler below (breakpoint),
// but can be overridden by C functions with correct name.
.macro decl_isr_bkpt name
.weak \name
.type \name,%function
.thumb_func
\name:
bkpt #0
.endm
// these are separated out for clarity
decl_isr_bkpt isr_invalid
decl_isr_bkpt isr_nmi
decl_isr_bkpt isr_hardfault
decl_isr_bkpt isr_svcall
decl_isr_bkpt isr_pendsv
decl_isr_bkpt isr_systick
.macro decl_isr name
.weak \name
.type \name,%function
.thumb_func
\name:
.endm
decl_isr isr_irq0
decl_isr isr_irq1
decl_isr isr_irq2
decl_isr isr_irq3
decl_isr isr_irq4
decl_isr isr_irq5
decl_isr isr_irq6
decl_isr isr_irq7
decl_isr isr_irq8
decl_isr isr_irq9
decl_isr isr_irq10
decl_isr isr_irq11
decl_isr isr_irq12
decl_isr isr_irq13
decl_isr isr_irq14
decl_isr isr_irq15
decl_isr isr_irq16
decl_isr isr_irq17
decl_isr isr_irq18
decl_isr isr_irq19
decl_isr isr_irq20
decl_isr isr_irq21
decl_isr isr_irq22
decl_isr isr_irq23
decl_isr isr_irq24
decl_isr isr_irq25
decl_isr isr_irq26
decl_isr isr_irq27
decl_isr isr_irq28
decl_isr isr_irq29
decl_isr isr_irq30
decl_isr isr_irq31
// All unhandled USER IRQs fall through to here
.global __unhandled_user_irq
.thumb_func
__unhandled_user_irq:
bl __get_current_exception
subs r0, #16
.global unhandled_user_irq_num_in_r0
unhandled_user_irq_num_in_r0:
bkpt #0
.section .reset, "ax"
// This is the beginning of the image, which is entered from stage2 or bootrom USB MSD watchdog reboot
// note if we are NO_FLASH then start: below is currently identical anyway, so save 4 bytes
#if !PICO_NO_FLASH
// We simply install our own vector table and redirect through it
ldr r0, =__vectors
b __vector_entry
#endif
// ELF entry point generally called when we load an ELF via debugger
.type _entry_point,%function
.thumb_func
.global _entry_point
_entry_point:
#if PICO_NO_FLASH
// non flash
ldr r0, =__vectors
#else
// todo clear watchdog?
// When using flash, we install and use the ROM vector table to go thru regular bootrom/stage2 flash sequence
movs r0, #0
#endif
__vector_entry:
ldr r1, =(PPB_BASE + M0PLUS_CPUID_OFFSET)
str r0, [r1, #8]
ldmia r0!, {r1, r2}
msr msp, r1
bx r2
// ----------------------------------------------------------------------------
// Reset handler:
// - initialises .data
// - clears .bss
// - calls runtime_init
// - calls main
// - calls exit (which should eventually hang the processor via _exit)
.type _reset_handler,%function
.thumb_func
_reset_handler:
// Hang all cores except core 0
ldr r0, =(SIO_BASE + SIO_CPUID_OFFSET)
ldr r0, [r0]
cmp r0, #0
bne wait_for_vector
adr r4, data_cpy_table
// assume there is at least one entry
1:
ldmia r4!, {r1-r3}
cmp r1, #0
beq 2f
bl data_cpy
b 1b
2:
// Zero out the BSS
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, #0
b bss_fill_test
bss_fill_loop:
stm r1!, {r0}
bss_fill_test:
cmp r1, r2
bne bss_fill_loop
platform_entry: // symbol for stack traces
// Use 32-bit jumps, in case these symbols are moved out of branch range
// (e.g. if main is in SRAM and crt0 in flash)
ldr r1, =runtime_init
blx r1
ldr r1, =main
blx r1
ldr r1, =exit
blx r1
// exit should not return. If it does, hang the core.
// (fall thru into our hang _exit impl
.weak _exit
.type _exit,%function
.thumb_func
_exit:
1: // separate label because _exit can be moved out of branch range
bkpt #0
b 1b
data_cpy_loop:
ldm r1!, {r0}
stm r2!, {r0}
data_cpy:
cmp r2, r3
blo data_cpy_loop
bx lr
#if !PICO_NO_BINARY_INFO
binary_info_header:
.word BINARY_INFO_MARKER_START
.word __binary_info_start
.word __binary_info_end
.word data_cpy_table // we may need to decode pointers that are in RAM at runtime.
.word BINARY_INFO_MARKER_END
#endif
.align 2
data_cpy_table:
#if PICO_COPY_TO_RAM
.word __ram_text_source__
.word __ram_text_start__
.word __ram_text_end__
#endif
.word __etext
.word __data_start__
.word __data_end__
.word __scratch_x_source__
.word __scratch_x_start__
.word __scratch_x_end__
.word __scratch_y_source__
.word __scratch_y_start__
.word __scratch_y_end__
.word 0 // null terminator
// ----------------------------------------------------------------------------
// Provide safe defaults for _exit and runtime_init
// Full implementations usually provided by platform.c
.weak runtime_init
.type runtime_init,%function
.thumb_func
runtime_init:
bx lr
// ----------------------------------------------------------------------------
// In case core 1's VTOR has already been moved into flash, we need to handle
// core 1 reset. However, we do so by just jumping back into bootrom version of
// wait_for_vector
wait_for_vector:
ldr r0, = 'W' | ('V' << 8)
bl rom_func_lookup
bx r0
.global __get_current_exception
.thumb_func
__get_current_exception:
mrs r0, ipsr
uxtb r0, r0
bx lr
// ----------------------------------------------------------------------------
// Stack/heap dummies to set size
.section .stack
// align to allow for memory protection (although this alignment is pretty much ignored by linker script)
.align 5
.equ StackSize, PICO_STACK_SIZE
.space StackSize
.section .heap
.align 2
.equ HeapSize, PICO_HEAP_SIZE
.space HeapSize
+4103 -272
View File
File diff suppressed because it is too large Load Diff
+57 -51
View File
@@ -1,22 +1,22 @@
/*
* Arduino header for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Arduino header for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 Arduino_h
#define Arduino_h
@@ -24,54 +24,57 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "stdlib_noniso.h" // Wacky deprecated AVR compatibility functions
#include "api/ArduinoAPI.h"
#include "api/itoa.h" // ARM toolchain doesn't provide itoa etc, provide them
#include <pins_arduino.h>
// Required for the port*Register macros
#include "hardware/gpio.h"
#include "hardware/gpio.h" // Required for the port*Register macros
#include "debug_internal.h"
// Try and make the best of the old Arduino abs() macro. When in C++, use
// the sane std::abs() call, but for C code use their macro since stdlib abs()
// is int but their macro "works" for everything (with potential side effects)
#ifdef abs
#undef abs
#endif // abs
#ifdef __cplusplus
extern "C"{
using std::abs;
using std::round;
#else
#define abs(x) ({ __typeof__(x) _x = (x); _x >= 0 ? _x : -_x; })
#define round(x) ({ __typeof__(x) _x = (x); _x >= 0 ? (long)(_x + 0.5) : (long)(_x - 0.5); })
#endif
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Disable/reenable all interrupts. Safely handles nested disables
// For compatibility to many platforms and libraries
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
// Disable/re-enable all interrupts. Safely handles nested disables
void interrupts();
void noInterrupts();
// GPIO change/value interrupts
void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus mode);
void detachInterrupt(pin_size_t pin);
// AVR compatibilty macros...naughty and accesses the HW directly
// AVR compatibility macros...naughty and accesses the HW directly
#define digitalPinToPort(pin) (0)
#define digitalPinToBitMask(pin) (1UL << (pin))
#define digitalPinToTimer(pin) (0)
#define digitalPinToInterrupt(pin) (pin)
#define NOT_AN_INTERRUPT (-1)
#define portOutputRegister(port) ((volatile uint32_t*) sio_hw->gpio_out)
#define portInputRegister(port) ((volatile uint32_t*) sio_hw->gpio_in)
#define portModeRegister(port) ((volatile uint32_t*) sio_hw->gpio_oe)
// IO config
void pinMode(pin_size_t pinNumber, PinMode pinMode);
// SIO (GPIO)
void digitalWrite(pin_size_t pinNumber, PinStatus status);
PinStatus digitalRead(pin_size_t pinNumber);
// ADC
int analogRead(pin_size_t pinNumber);
// ADC RP2040-specific calls
float analogReadTemp(); // Returns core temp in Centigrade
// PWM
void analogWrite(pin_size_t pinNumber, int value);
// Timing
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long millis();
// PWM RP2040-specific calls
void analogWriteFreq(uint32_t freq);
void analogWriteRange(uint32_t range);
void analogWriteResolution(int res);
#ifdef __cplusplus
} // extern "C"
@@ -83,7 +86,14 @@ unsigned long millis();
#define HAVE_HWSERIAL2
#ifdef __cplusplus
#ifdef USE_TINYUSB
// Needed for declaring Serial
#include "Adafruit_USBD_CDC.h"
#else
#include "SerialUSB.h"
#endif
#include "SerialUART.h"
#include "RP2040.h"
#include "Bootsel.h"
@@ -92,12 +102,8 @@ unsigned long millis();
// with the specified bits set.
template <size_t N>
constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) {
return i < N ? (1L << a[i]) | __bitset(a, i+1) : 0;
return i < N ? (1L << a[i]) | __bitset(a, i + 1) : 0;
}
#endif
// ARM toolchain doesn't provide itoa etc, provide them
#include "api/itoa.h"
#endif // Arduino_h
+8 -6
View File
@@ -1,8 +1,8 @@
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
SPDX-License-Identifier: BSD-3-Clause
*/
#include <Arduino.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
@@ -26,7 +26,8 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
// Must disable interrupts, as interrupt handlers may be in flash, and we
// are about to temporarily disable flash access!
uint32_t flags = save_and_disable_interrupts();
noInterrupts();
rp2040.idleOtherCore();
// Set chip select to Hi-Z
hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl,
@@ -46,7 +47,8 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB,
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
restore_interrupts(flags);
interrupts();
rp2040.resumeOtherCore();
return button_state;
}
+18 -18
View File
@@ -1,22 +1,22 @@
/*
* Simple BOOTSEL reader object
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Simple BOOTSEL reader object
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
+1
View File
@@ -0,0 +1 @@
#include "api/Client.h"
+22 -21
View File
@@ -1,25 +1,25 @@
/*
* CoreMutex for the Raspberry Pi Pico RP2040
*
* Implements a deadlock-safe multicore mutex for sharing things like the
* USB or UARTs.
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
CoreMutex for the Raspberry Pi Pico RP2040
Implements a deadlock-safe multicore mutex for sharing things like the
USB or UARTs.
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
@@ -33,6 +33,7 @@ public:
_acquired = false;
if (!mutex_try_enter(_mutex, &owner)) {
if (owner == get_core_num()) { // Deadlock!
DEBUGCORE("CoreMutex - Deadlock detected!\n");
return;
}
mutex_enter_blocking(_mutex);
+99 -75
View File
@@ -1,22 +1,22 @@
/*
FS.cpp - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
FS.cpp - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
You should have received a copy of the GNU Lesser General Public
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 "FS.h"
#include "FSImpl.h"
@@ -26,37 +26,42 @@ using namespace fs;
static bool sflags(const char* mode, OpenMode& om, AccessMode& am);
size_t File::write(uint8_t c) {
if (!_p)
if (!_p) {
return 0;
}
return _p->write(&c, 1);
}
size_t File::write(const uint8_t *buf, size_t size) {
if (!_p)
if (!_p) {
return 0;
}
return _p->write(buf, size);
}
int File::available() {
if (!_p)
if (!_p) {
return false;
}
return _p->size() - _p->position();
}
int File::availableForWrite() {
if (!_p)
if (!_p) {
return false;
}
return _p->availableForWrite();
}
int File::read() {
if (!_p)
if (!_p) {
return -1;
}
uint8_t result;
if (_p->read(&result, 1) != 1) {
@@ -67,15 +72,17 @@ int File::read() {
}
int File::read(uint8_t* buf, size_t size) {
if (!_p)
if (!_p) {
return 0;
}
return _p->read(buf, size);
}
int File::peek() {
if (!_p)
if (!_p) {
return -1;
}
size_t curPos = _p->position();
int result = read();
@@ -84,29 +91,33 @@ int File::peek() {
}
void File::flush() {
if (!_p)
if (!_p) {
return;
}
_p->flush();
}
bool File::seek(uint32_t pos, SeekMode mode) {
if (!_p)
if (!_p) {
return false;
}
return _p->seek(pos, mode);
}
size_t File::position() const {
if (!_p)
if (!_p) {
return 0;
}
return _p->position();
}
size_t File::size() const {
if (!_p)
if (!_p) {
return 0;
}
return _p->size();
}
@@ -123,36 +134,41 @@ File::operator bool() const {
}
bool File::truncate(uint32_t size) {
if (!_p)
if (!_p) {
return false;
}
return _p->truncate(size);
}
const char* File::name() const {
if (!_p)
if (!_p) {
return nullptr;
}
return _p->name();
}
const char* File::fullName() const {
if (!_p)
if (!_p) {
return nullptr;
}
return _p->fullName();
}
bool File::isFile() const {
if (!_p)
if (!_p) {
return false;
}
return _p->isFile();
}
bool File::isDirectory() const {
if (!_p)
if (!_p) {
return false;
}
return _p->isDirectory();
}
@@ -162,7 +178,7 @@ void File::rewindDirectory() {
_fakeDir = std::make_shared<Dir>(_baseFS->openDir(fullName()));
} else {
_fakeDir->rewind();
}
}
}
File File::openNextFile() {
@@ -173,38 +189,39 @@ File File::openNextFile() {
return _fakeDir->openFile("r");
}
String File::readString()
{
String File::readString() {
String ret;
ret.reserve(size() - position());
char temp[256+1];
int countRead = readBytes(temp, sizeof(temp)-1);
while (countRead > 0)
{
char temp[256 + 1];
int countRead = readBytes(temp, sizeof(temp) - 1);
while (countRead > 0) {
temp[countRead] = 0;
ret += temp;
countRead = readBytes(temp, sizeof(temp)-1);
countRead = readBytes(temp, sizeof(temp) - 1);
}
return ret;
}
time_t File::getLastWrite() {
if (!_p)
if (!_p) {
return 0;
}
return _p->getLastWrite();
}
time_t File::getCreationTime() {
if (!_p)
if (!_p) {
return 0;
}
return _p->getCreationTime();
}
void File::setTimeCallback(time_t (*cb)(void)) {
if (!_p)
if (!_p) {
return;
}
_p->setTimeCallback(cb);
_timeCallback = cb;
}
@@ -235,14 +252,16 @@ String Dir::fileName() {
}
time_t Dir::fileTime() {
if (!_impl)
if (!_impl) {
return 0;
}
return _impl->fileTime();
}
time_t Dir::fileCreationTime() {
if (!_impl)
if (!_impl) {
return 0;
}
return _impl->fileCreationTime();
}
@@ -255,15 +274,17 @@ size_t Dir::fileSize() {
}
bool Dir::isFile() const {
if (!_impl)
if (!_impl) {
return false;
}
return _impl->isFile();
}
bool Dir::isDirectory() const {
if (!_impl)
if (!_impl) {
return false;
}
return _impl->isDirectory();
}
@@ -285,8 +306,9 @@ bool Dir::rewind() {
}
void Dir::setTimeCallback(time_t (*cb)(void)) {
if (!_impl)
if (!_impl) {
return;
}
_impl->setTimeCallback(cb);
_timeCallback = cb;
}
@@ -307,7 +329,7 @@ bool FS::begin() {
}
_impl->setTimeCallback(_timeCallback);
bool ret = _impl->begin();
DEBUGV("%s\n", ret? "": "#error: FS could not start");
DEBUGV("%s\n", ret ? "" : "#error: FS could not start");
return ret;
}
@@ -338,14 +360,14 @@ bool FS::format() {
return _impl->format();
}
bool FS::info(FSInfo& info){
bool FS::info(FSInfo& info) {
if (!_impl) {
return false;
}
return _impl->info(info);
}
bool FS::info64(FSInfo64& info){
bool FS::info64(FSInfo64& info) {
if (!_impl) {
return false;
}
@@ -449,8 +471,9 @@ time_t FS::getCreationTime() {
}
void FS::setTimeCallback(time_t (*cb)(void)) {
if (!_impl)
if (!_impl) {
return;
}
_impl->setTimeCallback(cb);
_timeCallback = cb;
}
@@ -458,29 +481,29 @@ void FS::setTimeCallback(time_t (*cb)(void)) {
static bool sflags(const char* mode, OpenMode& om, AccessMode& am) {
switch (mode[0]) {
case 'r':
am = AM_READ;
om = OM_DEFAULT;
break;
case 'w':
am = AM_WRITE;
om = (OpenMode) (OM_CREATE | OM_TRUNCATE);
break;
case 'a':
am = AM_WRITE;
om = (OpenMode) (OM_CREATE | OM_APPEND);
break;
default:
return false;
case 'r':
am = AM_READ;
om = OM_DEFAULT;
break;
case 'w':
am = AM_WRITE;
om = (OpenMode)(OM_CREATE | OM_TRUNCATE);
break;
case 'a':
am = AM_WRITE;
om = (OpenMode)(OM_CREATE | OM_APPEND);
break;
default:
return false;
}
switch(mode[1]) {
case '+':
am = (AccessMode) (AM_WRITE | AM_READ);
break;
case 0:
break;
default:
return false;
switch (mode[1]) {
case '+':
am = (AccessMode)(AM_WRITE | AM_READ);
break;
case 0:
break;
default:
return false;
}
return true;
}
@@ -489,7 +512,7 @@ static bool sflags(const char* mode, OpenMode& om, AccessMode& am) {
#if defined(FS_FREESTANDING_FUNCTIONS)
/*
TODO: move these functions to public API:
TODO: move these functions to public API:
*/
File open(const char* path, const char* mode);
File open(String& path, const char* mode);
@@ -545,8 +568,9 @@ File open(const char* path, const char* mode) {
size_t offset = entry->path.length();
if (strstr(path, entry->path.c_str())) {
File result = entry->fs->open(path + offset);
if (result)
if (result) {
return result;
}
}
}
+51 -47
View File
@@ -1,22 +1,22 @@
/*
FS.h - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
FS.h - file system wrapper
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
You should have received a copy of the GNU Lesser General Public
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 FS_H
#define FS_H
@@ -49,8 +49,7 @@ enum SeekMode {
SeekEnd = 2
};
class File : public Stream
{
class File : public Stream {
public:
File(FileImplPtr p = FileImplPtr(), FS *baseFS = nullptr) : _p(p), _fakeDir(nullptr), _baseFS(baseFS) { }
@@ -74,7 +73,9 @@ public:
}
size_t position() const;
size_t size() const;
virtual ssize_t streamRemaining() { return (ssize_t)size() - (ssize_t)position(); }
virtual ssize_t streamRemaining() {
return (ssize_t)size() - (ssize_t)position();
}
void close();
operator bool() const;
const char* name() const;
@@ -86,26 +87,26 @@ public:
// Arduino "class SD" methods for compatibility
//TODO use stream::send / check read(buf,size) result
template<typename T> size_t write(T &src){
uint8_t obuf[256];
size_t doneLen = 0;
size_t sentLen;
int i;
template<typename T> size_t write(T &src) {
uint8_t obuf[256];
size_t doneLen = 0;
size_t sentLen;
int i;
while (src.available() > sizeof(obuf)){
src.read(obuf, sizeof(obuf));
sentLen = write(obuf, sizeof(obuf));
doneLen = doneLen + sentLen;
if(sentLen != sizeof(obuf)){
return doneLen;
while (src.available() > sizeof(obuf)) {
src.read(obuf, sizeof(obuf));
sentLen = write(obuf, sizeof(obuf));
doneLen = doneLen + sentLen;
if (sentLen != sizeof(obuf)) {
return doneLen;
}
}
}
size_t leftLen = src.available();
src.read(obuf, leftLen);
sentLen = write(obuf, leftLen);
doneLen = doneLen + sentLen;
return doneLen;
size_t leftLen = src.available();
src.read(obuf, leftLen);
sentLen = write(obuf, leftLen);
doneLen = doneLen + sentLen;
return doneLen;
}
using Print::write;
@@ -172,8 +173,7 @@ struct FSInfo64 {
};
class FSConfig
{
class FSConfig {
public:
static constexpr uint32_t FSId = 0x00000000;
@@ -188,8 +188,7 @@ public:
bool _autoFormat;
};
class SPIFFSConfig : public FSConfig
{
class SPIFFSConfig : public FSConfig {
public:
static constexpr uint32_t FSId = 0x53504946;
SPIFFSConfig(bool autoFormat = true) : FSConfig(FSId, autoFormat) { }
@@ -198,10 +197,11 @@ public:
// nothing yet, enableTime TBD when SPIFFS has metadate
};
class FS
{
class FS {
public:
FS(FSImplPtr impl) : _impl(impl) { _timeCallback = _defaultTimeCB; }
FS(FSImplPtr impl) : _impl(impl) {
_timeCallback = _defaultTimeCB;
}
bool setConfig(const FSConfig &cfg);
@@ -244,18 +244,22 @@ public:
friend class ::SDClass; // More of a frenemy, but SD needs internal implementation to get private FAT bits
protected:
FSImplPtr _impl;
FSImplPtr getImpl() { return _impl; }
FSImplPtr getImpl() {
return _impl;
}
time_t (*_timeCallback)(void) = nullptr;
static time_t _defaultTimeCB(void) { return time(NULL); }
static time_t _defaultTimeCB(void) {
return time(NULL);
}
};
} // namespace fs
extern "C"
{
void close_all_fs(void);
void littlefs_request_end(void);
void spiffs_request_end(void);
void close_all_fs(void);
void littlefs_request_end(void);
void spiffs_request_end(void);
}
#ifndef FS_NO_GLOBALS
+49 -27
View File
@@ -1,22 +1,22 @@
/*
FSImpl.h - base file system interface
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
FSImpl.h - base file system interface
Copyright (c) 2015 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
You should have received a copy of the GNU Lesser General Public
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 FSIMPL_H
#define FSIMPL_H
@@ -35,7 +35,9 @@ public:
virtual bool seek(uint32_t pos, SeekMode mode) = 0;
virtual size_t position() const = 0;
virtual size_t size() const = 0;
virtual int availableForWrite() { return 0; }
virtual int availableForWrite() {
return 0;
}
virtual bool truncate(uint32_t size) = 0;
virtual void close() = 0;
virtual const char* name() const = 0;
@@ -46,14 +48,20 @@ public:
// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for *this specific* file (as opposed to the FSImpl call of the
// same name. The default implementation simply returns time(null)
virtual void setTimeCallback(time_t (*cb)(void)) { _timeCallback = cb; }
virtual void setTimeCallback(time_t (*cb)(void)) {
_timeCallback = cb;
}
// Return the last written time for a file. Undefined when called on a writable file
// as the FS is allowed to return either the time of the last write() operation or the
// time present in the filesystem metadata (often the last time the file was closed)
virtual time_t getLastWrite() { return 0; } // Default is to not support timestamps
virtual time_t getLastWrite() {
return 0; // Default is to not support timestamps
}
// Same for creation time.
virtual time_t getCreationTime() { return 0; } // Default is to not support timestamps
virtual time_t getCreationTime() {
return 0; // Default is to not support timestamps
}
protected:
time_t (*_timeCallback)(void) = nullptr;
@@ -81,8 +89,12 @@ public:
// Return the last written time for a file. Undefined when called on a writable file
// as the FS is allowed to return either the time of the last write() operation or the
// time present in the filesystem metadata (often the last time the file was closed)
virtual time_t fileTime() { return 0; } // By default, FS doesn't report file times
virtual time_t fileCreationTime() { return 0; } // By default, FS doesn't report file times
virtual time_t fileTime() {
return 0; // By default, FS doesn't report file times
}
virtual time_t fileCreationTime() {
return 0; // By default, FS doesn't report file times
}
virtual bool isFile() const = 0;
virtual bool isDirectory() const = 0;
virtual bool next() = 0;
@@ -91,7 +103,9 @@ public:
// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for *this specific* file (as opposed to the FSImpl call of the
// same name. The default implementation simply returns time(null)
virtual void setTimeCallback(time_t (*cb)(void)) { _timeCallback = cb; }
virtual void setTimeCallback(time_t (*cb)(void)) {
_timeCallback = cb;
}
protected:
time_t (*_timeCallback)(void) = nullptr;
@@ -99,7 +113,7 @@ protected:
class FSImpl {
public:
virtual ~FSImpl () { }
virtual ~FSImpl() { }
virtual bool setConfig(const FSConfig &cfg) = 0;
virtual bool begin() = 0;
virtual void end() = 0;
@@ -113,14 +127,22 @@ public:
virtual bool remove(const char* path) = 0;
virtual bool mkdir(const char* path) = 0;
virtual bool rmdir(const char* path) = 0;
virtual bool gc() { return true; } // May not be implemented in all file systems.
virtual bool check() { return true; } // May not be implemented in all file systems.
virtual time_t getCreationTime() { return 0; } // May not be implemented in all file systems.
virtual bool gc() {
return true; // May not be implemented in all file systems.
}
virtual bool check() {
return true; // May not be implemented in all file systems.
}
virtual time_t getCreationTime() {
return 0; // May not be implemented in all file systems.
}
// Filesystems *may* support a timestamp per-file, so allow the user to override with
// their own callback for all files on this FS. The default implementation simply
// returns the present time as reported by time(null)
virtual void setTimeCallback(time_t (*cb)(void)) { _timeCallback = cb; }
virtual void setTimeCallback(time_t (*cb)(void)) {
_timeCallback = cb;
}
protected:
time_t (*_timeCallback)(void) = nullptr;
+1
View File
@@ -0,0 +1 @@
#include "api/HardwareSerial.h"
+1
View File
@@ -0,0 +1 @@
#include "api/IPAddress.h"
+1
View File
@@ -0,0 +1 @@
#include "api/Interrupts.h"
+1
View File
@@ -0,0 +1 @@
#include "api/Print.h"
+1
View File
@@ -0,0 +1 @@
#include "api/Printable.h"
+178 -25
View File
@@ -1,55 +1,208 @@
/*
* RP2040 utility class
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
RP2040 utility class
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <hardware/pio.h>
#include <hardware/clocks.h>
#include <hardware/irq.h>
#include <hardware/pio.h>
#include <hardware/exception.h>
#include <hardware/structs/systick.h>
#include <pico/multicore.h>
#include <pico/util/queue.h>
#include <CoreMutex.h>
class _MFIFO {
public:
_MFIFO() { /* noop */ };
~_MFIFO() { /* noop */ };
void begin(int cores) {
constexpr int FIFOCNT = 8;
if (cores == 1) {
_multicore = false;
return;
}
mutex_init(&_idleMutex);
queue_init(&_queue[0], sizeof(uint32_t), FIFOCNT);
queue_init(&_queue[1], sizeof(uint32_t), FIFOCNT);
_multicore = true;
}
void registerCore() {
multicore_fifo_clear_irq();
irq_set_exclusive_handler(SIO_IRQ_PROC0 + get_core_num(), _irq);
irq_set_enabled(SIO_IRQ_PROC0 + get_core_num(), true);
}
void push(uint32_t val) {
while (!push_nb(val)) { /* noop */ }
}
bool push_nb(uint32_t val) {
// Push to the other FIFO
return queue_try_add(&_queue[get_core_num() ^ 1], &val);
}
uint32_t pop() {
uint32_t ret;
while (!pop_nb(&ret)) { /* noop */ }
return ret;
}
bool pop_nb(uint32_t *val) {
// Pop from my own FIFO
return queue_try_remove(&_queue[get_core_num()], val);
}
int available() {
return queue_get_level(&_queue[get_core_num()]);
}
void idleOtherCore() {
if (!_multicore) {
return;
}
mutex_enter_blocking(&_idleMutex);
_otherIdled = false;
multicore_fifo_push_blocking(_GOTOSLEEP);
while (!_otherIdled) { /* noop */ }
}
void resumeOtherCore() {
if (!_multicore) {
return;
}
mutex_exit(&_idleMutex);
_otherIdled = false;
// Other core will exit busy-loop and return to operation
// once otherIdled == false.
}
private:
static void __no_inline_not_in_flash_func(_irq)() {
multicore_fifo_clear_irq();
noInterrupts(); // We need total control, can't run anything
while (multicore_fifo_rvalid()) {
if (_GOTOSLEEP == multicore_fifo_pop_blocking()) {
_otherIdled = true;
while (_otherIdled) { /* noop */ }
break;
}
}
interrupts();
}
bool _multicore = false;
mutex_t _idleMutex;
static volatile bool _otherIdled;
queue_t _queue[2];
static constexpr int _GOTOSLEEP = 0x66666666;
};
class RP2040;
extern RP2040 rp2040;
class RP2040 {
public:
RP2040() {
_epoch = 0;
// Enable SYSTICK exception
exception_set_exclusive_handler(SYSTICK_EXCEPTION, _SystickHandler);
systick_hw->csr = 0x7;
systick_hw->rvr = 0x00FFFFFF;
}
~RP2040() { /* noop */ }
// Convert from microseconds to PIO clock cycles
static int usToPIOCycles(int us) {
// Parenthesis needed to guarantee order of operations to avoid 32bit overflow
return (us * ( clock_get_hz(clk_sys) / 1000000 ));
return (us * (clock_get_hz(clk_sys) / 1000000));
}
// Get current clock frequency
static int f_cpu() {
return clock_get_hz(clk_sys);
}
// Get CPU cycle count. Needs to do magic to extens 24b HW to something longer
volatile uint64_t _epoch = 0;
inline uint32_t getCycleCount() {
uint32_t epoch;
uint32_t ctr;
do {
epoch = (uint32_t)_epoch;
ctr = systick_hw->cvr;
} while (epoch != (uint32_t)_epoch);
return epoch + (1 << 24) - ctr; /* CTR counts down from 1<<24-1 */
}
inline uint64_t getCycleCount64() {
uint64_t epoch;
uint64_t ctr;
do {
epoch = _epoch;
ctr = systick_hw->cvr;
} while (epoch != _epoch);
return epoch + (1LL << 24) - ctr;
}
void idleOtherCore() {
fifo.idleOtherCore();
}
void resumeOtherCore() {
fifo.resumeOtherCore();
}
// Multicore comms FIFO
_MFIFO fifo;
private:
static void _SystickHandler() {
rp2040._epoch += 1LL << 24;
}
};
// Wrapper class for PIO programs, abstracting common operations out
// TODO - Make dualcore safe
// TODO - Add unload/destructor
class PIOProgram {
public:
PIOProgram(const pio_program_t *pgm) { _pgm = pgm; }
PIOProgram(const pio_program_t *pgm) {
_pgm = pgm;
}
// Possibly load into a PIO and allocate a SM
bool prepare(PIO *pio, int *sm, int *offset) {
extern mutex_t _pioMutex;
CoreMutex m(&_pioMutex);
// Is there an open slot to run in, first?
if (!_findFreeSM(pio, sm)) return false;
// Is it loaded on that PIO?
if (!_findFreeSM(pio, sm)) {
return false;
}
// Is it loaded on that PIO?
if (_offset[pio_get_index(*pio)] < 0) {
// Nope, need to load it
if (!pio_can_add_program(*pio, _pgm)) return false;
if (!pio_can_add_program(*pio, _pgm)) {
return false;
}
_offset[pio_get_index(*pio)] = pio_add_program(*pio, _pgm);
}
// Here it's guaranteed loaded, return values
+314
View File
@@ -0,0 +1,314 @@
/*
Shared USB for the Raspberry Pi Pico RP2040
Allows for multiple endpoints to share the USB controller
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(USE_TINYUSB) && !defined(NO_USB)
#include <Arduino.h>
#include "CoreMutex.h"
#include "RP2040USB.h"
#include "tusb.h"
#include "class/hid/hid_device.h"
#include "class/audio/audio.h"
#include "class/midi/midi.h"
#include "pico/time.h"
#include "hardware/irq.h"
#include "pico/mutex.h"
#include "pico/unique_id.h"
// Big, global USB mutex, shared with all USB devices to make sure we don't
// have multiple cores updating the TUSB state in parallel
mutex_t __usb_mutex;
// USB processing will be a periodic timer task
#define USB_TASK_INTERVAL 1000
#define USB_TASK_IRQ 31
// USB VID/PID (note that PID can change depending on the add'l interfaces)
#define USBD_VID (0x2E8A) // Raspberry Pi
#ifdef SERIALUSB_PID
#define USBD_PID (SERIALUSB_PID)
#else
#define USBD_PID (0x000a) // Raspberry Pi Pico SDK CDC
#endif
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
#define USBD_MAX_POWER_MA (250)
#define USBD_ITF_CDC (0) // needs 2 interfaces
#define USBD_ITF_MAX (2)
#define USBD_CDC_EP_CMD (0x81)
#define USBD_CDC_EP_OUT (0x02)
#define USBD_CDC_EP_IN (0x82)
#define USBD_CDC_CMD_MAX_SIZE (8)
#define USBD_CDC_IN_OUT_MAX_SIZE (64)
#define USBD_STR_0 (0x00)
#define USBD_STR_MANUF (0x01)
#define USBD_STR_PRODUCT (0x02)
#define USBD_STR_SERIAL (0x03)
#define USBD_STR_CDC (0x04)
#define EPNUM_HID 0x83
#define EPNUM_MIDI 0x01
const uint8_t *tud_descriptor_device_cb(void) {
static tusb_desc_device_t usbd_desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_CDC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USBD_VID,
.idProduct = USBD_PID,
.bcdDevice = 0x0100,
.iManufacturer = USBD_STR_MANUF,
.iProduct = USBD_STR_PRODUCT,
.iSerialNumber = USBD_STR_SERIAL,
.bNumConfigurations = 1
};
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallMIDI) {
// Can use as-is, this is the default USB case
return (const uint8_t *)&usbd_desc_device;
}
// Need a multi-endpoint config which will require changing the PID to help Windows not barf
if (__USBInstallKeyboard) {
usbd_desc_device.idProduct |= 0x8000;
}
if (__USBInstallMouse) {
usbd_desc_device.idProduct |= 0x4000;
}
if (__USBInstallMIDI) {
usbd_desc_device.idProduct |= 0x2000;
}
// Set the device class to 0 to indicate multiple device classes
usbd_desc_device.bDeviceClass = 0;
usbd_desc_device.bDeviceSubClass = 0;
usbd_desc_device.bDeviceProtocol = 0;
return (const uint8_t *)&usbd_desc_device;
}
int __USBGetKeyboardReportID() {
return 1;
}
int __USBGetMouseReportID() {
return __USBInstallKeyboard ? 2 : 1;
}
static uint8_t *GetDescHIDReport(int *len) {
if (__USBInstallKeyboard && __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)),
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(2))
};
if (len) {
*len = sizeof(desc_hid_report);
}
return desc_hid_report;
} else if (__USBInstallKeyboard && ! __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1))
};
if (len) {
*len = sizeof(desc_hid_report);
}
return desc_hid_report;
} else { // if (!__USBInstallKeyboard && __USBInstallMouse) {
static uint8_t desc_hid_report[] = {
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(1))
};
if (len) {
*len = sizeof(desc_hid_report);
}
return desc_hid_report;
}
}
// Invoked when received GET HID REPORT DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance) {
(void) instance;
return GetDescHIDReport(nullptr);
}
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
(void)index;
static uint8_t *usbd_desc_cfg = NULL;
if (!usbd_desc_cfg) {
bool hasHID = __USBInstallKeyboard || __USBInstallMouse;
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0) + (__USBInstallMIDI ? 2 : 0);
static uint8_t cdc_desc[TUD_CDC_DESC_LEN] = {
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD, USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE)
};
int hid_report_len;
GetDescHIDReport(&hid_report_len);
uint8_t hid_itf = __USBInstallSerial ? 2 : 0;
static uint8_t hid_desc[TUD_HID_DESC_LEN] = {
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
TUD_HID_DESCRIPTOR(hid_itf, 0, HID_ITF_PROTOCOL_NONE, hid_report_len, EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 10)
};
uint8_t midi_itf = hid_itf + (hasHID ? 1 : 0);
static uint8_t midi_desc[TUD_MIDI_DESC_LEN] = {
// Interface number, string index, EP Out & EP In address, EP size
TUD_MIDI_DESCRIPTOR(midi_itf, 0, EPNUM_MIDI, 0x80 | EPNUM_MIDI, 64)
};
int usbd_desc_len = TUD_CONFIG_DESC_LEN + (__USBInstallSerial ? sizeof(cdc_desc) : 0) + (hasHID ? sizeof(hid_desc) : 0) + (__USBInstallMIDI ? sizeof(midi_desc) : 0);
static uint8_t tud_cfg_desc[TUD_CONFIG_DESC_LEN] = {
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, interface_count, USBD_STR_0, usbd_desc_len, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA)
};
// Combine to one descriptor
usbd_desc_cfg = (uint8_t *)malloc(usbd_desc_len);
bzero(usbd_desc_cfg, usbd_desc_len);
uint8_t *ptr = usbd_desc_cfg;
memcpy(ptr, tud_cfg_desc, sizeof(tud_cfg_desc));
ptr += sizeof(tud_cfg_desc);
if (__USBInstallSerial) {
memcpy(ptr, cdc_desc, sizeof(cdc_desc));
ptr += sizeof(cdc_desc);
}
if (hasHID) {
memcpy(ptr, hid_desc, sizeof(hid_desc));
ptr += sizeof(hid_desc);
}
if (__USBInstallMIDI) {
memcpy(ptr, midi_desc, sizeof(midi_desc));
}
}
return usbd_desc_cfg;
}
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
(void) langid;
#define DESC_STR_MAX (20)
static uint16_t desc_str[DESC_STR_MAX];
static char idString[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1];
static const char *const usbd_desc_str[] = {
[USBD_STR_0] = "",
[USBD_STR_MANUF] = "Raspberry Pi",
[USBD_STR_PRODUCT] = "PicoArduino",
[USBD_STR_SERIAL] = idString,
[USBD_STR_CDC] = "Board CDC",
};
if (!idString[0]) {
pico_get_unique_board_id_string(idString, sizeof(idString));
}
uint8_t len;
if (index == 0) {
desc_str[1] = 0x0409; // supported language is English
len = 1;
} else {
if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) {
return NULL;
}
const char *str = usbd_desc_str[index];
for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) {
desc_str[1 + len] = str[len];
}
}
// first byte is length (including header), second byte is string type
desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * len + 2);
return desc_str;
}
static void usb_irq() {
// if the mutex is already owned, then we are in user code
// in this file which will do a tud_task itself, so we'll just do nothing
// until the next tick; we won't starve
if (mutex_try_enter(&__usb_mutex, NULL)) {
tud_task();
mutex_exit(&__usb_mutex);
}
}
static int64_t timer_task(__unused alarm_id_t id, __unused void *user_data) {
irq_set_pending(USB_TASK_IRQ);
return USB_TASK_INTERVAL;
}
void __USBStart() {
if (tusb_inited()) {
// Already called
return;
}
mutex_init(&__usb_mutex);
tusb_init();
irq_set_exclusive_handler(USB_TASK_IRQ, usb_irq);
irq_set_enabled(USB_TASK_IRQ, true);
add_alarm_in_us(USB_TASK_INTERVAL, timer_task, NULL, true);
}
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request
extern "C" uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
// TODO not implemented
(void) instance;
(void) report_id;
(void) report_type;
(void) buffer;
(void) reqlen;
return 0;
}
// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
extern "C" void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
// TODO set LED based on CAPLOCK, NUMLOCK etc...
(void) instance;
(void) report_id;
(void) report_type;
(void) buffer;
(void) bufsize;
}
#endif
+39
View File
@@ -0,0 +1,39 @@
/*
Shared USB for the Raspberry Pi Pico RP2040
Allows for multiple endpoints to share the USB controller
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 "pico/mutex.h"
// Weak function definitions for each type of endpoint
extern void __USBInstallSerial() __attribute__((weak));
extern void __USBInstallKeyboard() __attribute__((weak));
extern void __USBInstallMouse() __attribute__((weak));
extern void __USBInstallMIDI() __attribute__((weak));
// Big, global USB mutex, shared with all USB devices to make sure we don't
// have multiple cores updating the TUSB state in parallel
extern mutex_t __usb_mutex;
// HID report ID inquiry (report ID will vary depending on the number/type of other HID)
int __USBGetKeyboardReportID();
int __USBGetMouseReportID();
// Called by main() to init the USB HW/SW.
void __USBStart();
+67 -55
View File
@@ -1,22 +1,22 @@
/*
* Serial-over-UART for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Serial-over-UART for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 "SerialUART.h"
#include "CoreMutex.h"
@@ -31,34 +31,38 @@
extern void serialEvent1() __attribute__((weak));
extern void serialEvent2() __attribute__((weak));
bool SerialUART::setRX(pin_size_t rx) {
bool SerialUART::setRX(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({1, 13, 17, 29}) /* UART0 */,
__bitset({5, 9, 21, 25}) /* UART1 */};
if (_running) {
DEBUGCORE("ERROR: SerialUART setRX while running\n");
return false;
} else if ((1 << rx) & valid[uart_get_index(_uart)]) {
_rx = rx;
__bitset({5, 9, 21, 25}) /* UART1 */
};
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
_rx = pin;
return true;
} else {
DEBUGCORE("ERROR: SerialUART setRX illegal pin (%d)\n", rx);
return false;
}
if (_running) {
panic("FATAL: Attempting to set Serial%d.RX while running", uart_get_index(_uart) + 1);
} else {
panic("FATAL: Attempting to set Serial%d.RX to illegal pin %d", uart_get_index(_uart) + 1, pin);
}
return false;
}
bool SerialUART::setTX(pin_size_t tx) {
bool SerialUART::setTX(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({0, 12, 16, 28}) /* UART0 */,
__bitset({4, 8, 20, 24}) /* UART1 */};
if (_running) {
DEBUGCORE("ERROR: SerialUART setTX while running\n");
return false;
} else if ((1 << tx) & valid[uart_get_index(_uart)]) {
_tx = tx;
__bitset({4, 8, 20, 24}) /* UART1 */
};
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
_tx = pin;
return true;
} else {
DEBUGCORE("ERROR: SerialUART setTX illegal pin (%d)\n", tx);
return false;
}
if (_running) {
panic("FATAL: Attempting to set Serial%d.TX while running", uart_get_index(_uart) + 1);
} else {
panic("FATAL: Attempting to set Serial%d.TX to illegal pin %d", uart_get_index(_uart) + 1, pin);
}
return false;
}
SerialUART::SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx) {
@@ -74,19 +78,19 @@ void SerialUART::begin(unsigned long baud, uint16_t config) {
int bits, stop;
uart_parity_t parity;
switch (config & SERIAL_PARITY_MASK) {
case SERIAL_PARITY_EVEN: parity = UART_PARITY_EVEN; break;
case SERIAL_PARITY_ODD: parity = UART_PARITY_ODD; break;
default: parity = UART_PARITY_NONE; break;
case SERIAL_PARITY_EVEN: parity = UART_PARITY_EVEN; break;
case SERIAL_PARITY_ODD: parity = UART_PARITY_ODD; break;
default: parity = UART_PARITY_NONE; break;
}
switch ( config & SERIAL_STOP_BIT_MASK) {
case SERIAL_STOP_BIT_1: stop = 1; break;
default: stop = 2; break;
switch (config & SERIAL_STOP_BIT_MASK) {
case SERIAL_STOP_BIT_1: stop = 1; break;
default: stop = 2; break;
}
switch (config & SERIAL_DATA_MASK) {
case SERIAL_DATA_5: bits = 5; break;
case SERIAL_DATA_6: bits = 6; break;
case SERIAL_DATA_7: bits = 7; break;
default: bits = 8; break;
case SERIAL_DATA_5: bits = 5; break;
case SERIAL_DATA_6: bits = 6; break;
case SERIAL_DATA_7: bits = 7; break;
default: bits = 8; break;
}
uart_set_format(_uart, bits, stop, parity);
gpio_set_function(_tx, GPIO_FUNC_UART);
@@ -111,7 +115,11 @@ int SerialUART::peek() {
if (_peek >= 0) {
return _peek;
}
_peek = uart_getc(_uart);
if (uart_is_readable_within_us(_uart, _timeout * 1000)) {
_peek = uart_getc(_uart);
} else {
_peek = -1; // Timeout
}
return _peek;
}
@@ -125,7 +133,11 @@ int SerialUART::read() {
_peek = -1;
return ret;
}
return uart_getc(_uart);
if (uart_is_readable_within_us(_uart, _timeout * 1000)) {
return uart_getc(_uart);
} else {
return -1; // Timeout
}
}
int SerialUART::available() {
@@ -149,7 +161,7 @@ void SerialUART::flush() {
if (!_running || !m) {
return;
}
uart_default_tx_wait_blocking();
uart_tx_wait_blocking(_uart);
}
size_t SerialUART::write(uint8_t c) {
@@ -179,17 +191,17 @@ SerialUART::operator bool() {
return _running;
}
SerialUART Serial1(uart0, 0, 1);
SerialUART Serial2(uart1, 4, 5);
SerialUART Serial1(uart0, PIN_SERIAL1_TX, PIN_SERIAL1_RX);
SerialUART Serial2(uart1, PIN_SERIAL2_TX, PIN_SERIAL2_RX);
void arduino::serialEvent1Run(void) {
if (serialEvent1 && Serial1.available()) {
serialEvent1();
serialEvent1();
}
}
void arduino::serialEvent2Run(void) {
if (serialEvent2 && Serial2.available()) {
serialEvent2();
serialEvent2();
}
}
+30 -27
View File
@@ -1,25 +1,24 @@
/*
* Serial-over-UART for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Serial-over-UART for the Raspberry Pi Pico RP2040
#ifndef __SERIALUART_H__
#define __SERIALUART_H__
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <Arduino.h>
#include "api/HardwareSerial.h"
@@ -31,13 +30,19 @@ extern "C" typedef struct uart_inst uart_inst_t;
class SerialUART : public HardwareSerial {
public:
SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx);
// Select the pinout. Call before .begin()
bool setRX(pin_size_t pin);
bool setTX(pin_size_t pin);
bool setPinout(pin_size_t tx, pin_size_t rx) { bool ret = setRX(rx); ret &= setTX(tx); return ret; }
bool setPinout(pin_size_t tx, pin_size_t rx) {
bool ret = setRX(rx);
ret &= setTX(tx);
return ret;
}
void begin(unsigned long baud = 115200) override { begin(baud, SERIAL_8N1); };
void begin(unsigned long baud = 115200) override {
begin(baud, SERIAL_8N1);
};
void begin(unsigned long baud, uint16_t config) override;
void end() override;
@@ -64,8 +69,6 @@ extern SerialUART Serial1; // HW UART 0
extern SerialUART Serial2; // HW UART 1
namespace arduino {
extern void serialEvent1Run(void) __attribute__((weak));
extern void serialEvent2Run(void) __attribute__((weak));
extern void serialEvent1Run(void) __attribute__((weak));
extern void serialEvent2Run(void) __attribute__((weak));
};
#endif
+49 -168
View File
@@ -1,24 +1,26 @@
/*
* Serial-Over-USB for the Raspberry Pi Pico RP2040
* Implements an ACM which will reboot into UF2 mode on a 1200bps DTR toggle.
* Much of this was modified from the Raspberry Pi Pico SDK stdio_usb.c file.
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Serial-Over-USB for the Raspberry Pi Pico RP2040
Implements an ACM which will reboot into UF2 mode on a 1200bps DTR toggle.
Much of this was modified from the Raspberry Pi Pico SDK stdio_usb.c file.
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(USE_TINYUSB) && !defined(NO_USB)
#include <Arduino.h>
#include "CoreMutex.h"
@@ -32,6 +34,11 @@
#include "hardware/watchdog.h"
#include "pico/unique_id.h"
#ifndef DISABLE_USB_SERIAL
// Ensure we are installed in the USB chain
void __USBInstallSerial() { /* noop */ }
#endif
// SerialEvent functions are weak, so when the user doesn't define them,
// the linker just sets their address to 0 (which is checked below).
// The Serialx_available is just a wrapper around Serialx.available(),
@@ -39,121 +46,8 @@
// HardwareSerial instance if the user doesn't also refer to it.
extern void serialEvent() __attribute__((weak));
#define PICO_STDIO_USB_TASK_INTERVAL_US 1000
#define PICO_STDIO_USB_LOW_PRIORITY_IRQ 31
#define USBD_VID (0x2E8A) // Raspberry Pi
#ifdef SERIALUSB_PID
#define USBD_PID (SERIALUSB_PID)
#else
#define USBD_PID (0x000a) // Raspberry Pi Pico SDK CDC
#endif
#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
#define USBD_MAX_POWER_MA (250)
#define USBD_ITF_CDC (0) // needs 2 interfaces
#define USBD_ITF_MAX (2)
#define USBD_CDC_EP_CMD (0x81)
#define USBD_CDC_EP_OUT (0x02)
#define USBD_CDC_EP_IN (0x82)
#define USBD_CDC_CMD_MAX_SIZE (8)
#define USBD_CDC_IN_OUT_MAX_SIZE (64)
#define USBD_STR_0 (0x00)
#define USBD_STR_MANUF (0x01)
#define USBD_STR_PRODUCT (0x02)
#define USBD_STR_SERIAL (0x03)
#define USBD_STR_CDC (0x04)
// Note: descriptors returned from callbacks must exist long enough for transfer to complete
static const tusb_desc_device_t usbd_desc_device = {
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = TUSB_CLASS_CDC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.idVendor = USBD_VID,
.idProduct = USBD_PID,
.bcdDevice = 0x0100,
.iManufacturer = USBD_STR_MANUF,
.iProduct = USBD_STR_PRODUCT,
.iSerialNumber = USBD_STR_SERIAL,
.bNumConfigurations = 1,
};
static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = {
TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_0, USBD_DESC_LEN,
TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA),
TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD,
USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE),
};
static char _idString[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1];
static const char *const usbd_desc_str[] = {
[USBD_STR_0] = "",
[USBD_STR_MANUF] = "Raspberry Pi",
[USBD_STR_PRODUCT] = "PicoArduino",
[USBD_STR_SERIAL] = _idString,
[USBD_STR_CDC] = "Board CDC",
};
const uint8_t *tud_descriptor_device_cb(void) {
return (const uint8_t *)&usbd_desc_device;
}
const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
(void)index;
return usbd_desc_cfg;
}
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
#define DESC_STR_MAX (20)
static uint16_t desc_str[DESC_STR_MAX];
uint8_t len;
if (index == 0) {
desc_str[1] = 0x0409; // supported language is English
len = 1;
} else {
if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) {
return NULL;
}
const char *str = usbd_desc_str[index];
for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) {
desc_str[1 + len] = str[len];
}
}
// first byte is length (including header), second byte is string type
desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * len + 2);
return desc_str;
}
static mutex_t usb_mutex;
static void low_priority_worker_irq() {
// if the mutex is already owned, then we are in user code
// in this file which will do a tud_task itself, so we'll just do nothing
// until the next tick; we won't starve
if (mutex_try_enter(&usb_mutex, NULL)) {
tud_task();
mutex_exit(&usb_mutex);
}
}
static int64_t timer_task(__unused alarm_id_t id, __unused void *user_data) {
irq_set_pending(PICO_STDIO_USB_LOW_PRIORITY_IRQ);
return PICO_STDIO_USB_TASK_INTERVAL_US;
}
extern mutex_t __usb_mutex;
void SerialUSB::begin(unsigned long baud) {
(void) baud; //ignored
@@ -162,24 +56,6 @@ void SerialUSB::begin(unsigned long baud) {
return;
}
// Get ID string into human readable serial number
pico_unique_board_id_t id;
pico_get_unique_board_id(&id);
_idString[0] = 0;
for (auto i = 0; i < PICO_UNIQUE_BOARD_ID_SIZE_BYTES; i++) {
char hx[3];
sprintf(hx, "%02X", id.id[i]);
strcat(_idString, hx);
}
tusb_init();
irq_set_exclusive_handler(PICO_STDIO_USB_LOW_PRIORITY_IRQ, low_priority_worker_irq);
irq_set_enabled(PICO_STDIO_USB_LOW_PRIORITY_IRQ, true);
mutex_init(&usb_mutex);
add_alarm_in_us(PICO_STDIO_USB_TASK_INTERVAL_US, timer_task, NULL, true);
_running = true;
}
@@ -188,17 +64,17 @@ void SerialUSB::end() {
}
int SerialUSB::peek() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return 0;
}
uint8_t c;
return tud_cdc_peek(0, &c) ? (int) c : -1;
return tud_cdc_peek(&c) ? (int) c : -1;
}
int SerialUSB::read() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return -1;
}
@@ -210,7 +86,7 @@ int SerialUSB::read() {
}
int SerialUSB::available() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return 0;
}
@@ -219,7 +95,7 @@ int SerialUSB::available() {
}
int SerialUSB::availableForWrite() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return 0;
}
@@ -228,7 +104,7 @@ int SerialUSB::availableForWrite() {
}
void SerialUSB::flush() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return;
}
@@ -241,7 +117,7 @@ size_t SerialUSB::write(uint8_t c) {
}
size_t SerialUSB::write(const uint8_t *buf, size_t length) {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return 0;
}
@@ -249,10 +125,12 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
static uint64_t last_avail_time;
int i = 0;
if (tud_cdc_connected()) {
for (int i = 0; i < length;) {
for (size_t i = 0; i < length;) {
int n = length - i;
int avail = tud_cdc_write_available();
if (n > avail) n = avail;
if (n > avail) {
n = avail;
}
if (n) {
int n2 = tud_cdc_write(buf + i, n);
tud_task();
@@ -263,7 +141,7 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
tud_task();
tud_cdc_write_flush();
if (!tud_cdc_connected() ||
(!tud_cdc_write_available() && time_us_64() > last_avail_time + 1000000 /* 1 second */)) {
(!tud_cdc_write_available() && time_us_64() > last_avail_time + 1000000 /* 1 second */)) {
break;
}
}
@@ -276,7 +154,7 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
}
SerialUSB::operator bool() {
CoreMutex m(&usb_mutex);
CoreMutex m(&__usb_mutex);
if (!_running || !m) {
return false;
}
@@ -291,27 +169,30 @@ static bool _rts = false;
static int _bps = 115200;
static void CheckSerialReset() {
if ((_bps == 1200) && (!_dtr)) {
reset_usb_boot(0,0);
while (1); // WDT will fire here
reset_usb_boot(0, 0);
while (1); // WDT will fire here
}
}
extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
(void) itf;
_dtr = dtr ? true : false;
_rts = rts ? true : false;
CheckSerialReset();
}
extern "C" void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) {
(void) itf;
_bps = p_line_coding->bit_rate;
CheckSerialReset();
}
SerialUSB Serial;
void arduino::serialEventRun(void)
{
void arduino::serialEventRun(void) {
if (serialEvent && Serial.available()) {
serialEvent();
serialEvent();
}
}
#endif
+23 -20
View File
@@ -1,22 +1,22 @@
/*
* Serial-over-USB for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Serial-over-USB for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 __SERIALUSB_H__
#define __SERIALUSB_H__
@@ -29,7 +29,10 @@ class SerialUSB : public HardwareSerial {
public:
SerialUSB() { }
void begin(unsigned long baud = 115200) override;
void begin(unsigned long baud, uint16_t config) override { begin(baud); };
void begin(unsigned long baud, uint16_t config) override {
(void) config;
begin(baud);
};
void end() override;
virtual int peek() override;
@@ -49,7 +52,7 @@ private:
extern SerialUSB Serial;
namespace arduino {
extern void serialEventRun(void) __attribute__((weak));
extern void serialEventRun(void) __attribute__((weak));
};
#endif
+1
View File
@@ -0,0 +1 @@
#include "api/Server.h"
+1
View File
@@ -0,0 +1 @@
#include "api/Stream.h"
+80 -43
View File
@@ -1,24 +1,25 @@
/*
* Tone for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Tone for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <Arduino.h>
#include "CoreMutex.h"
#include <hardware/gpio.h>
#include <pico/time.h>
#include <map>
@@ -27,15 +28,26 @@ typedef struct {
pin_size_t pin;
PIO pio;
int sm;
alarm_id_t alarm;
} Tone;
#include "tone.pio.h"
static PIOProgram _tonePgm(&tone_program);
// Keep std::map safe for multicore use
auto_init_mutex(_toneMutex);
#include "tone2.pio.h"
static PIOProgram _tone2Pgm(&tone2_program);
static std::map<pin_size_t, Tone *> _toneMap;
int64_t _stopTonePIO(alarm_id_t id, void *user_data) {
(void) id;
Tone *tone = (Tone *)user_data;
tone->alarm = 0;
pio_sm_set_enabled(tone->pio, tone->sm, false);
return 0;
}
void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
if ((pin < 0) || (pin > 29)) {
if (pin > 29) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return;
}
@@ -43,47 +55,72 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
noTone(pin);
return;
}
// Ensure only 1 core can start or stop at a time
CoreMutex m(&_toneMutex);
if (!m) {
return; // Weird deadlock case
}
int us = 1000000 / frequency / 2;
if (us < 5) {
us = 5;
}
// Even phases run forever, odd phases end after count...so ensure its odd
int phases = duration ? (duration * 1000 / us) | 1 : 2;
auto entry = _toneMap.find(pin);
if (entry != _toneMap.end()) {
noTone(pin);
Tone *newTone;
if (entry == _toneMap.end()) {
newTone = new Tone();
newTone->pin = pin;
pinMode(pin, OUTPUT);
int off;
if (!_tone2Pgm.prepare(&newTone->pio, &newTone->sm, &off)) {
DEBUGCORE("ERROR: tone unable to start, out of PIO resources\n");
// ERROR, no free slots
delete newTone;
return;
}
tone2_program_init(newTone->pio, newTone->sm, off, pin);
newTone->alarm = 0;
} else {
newTone = entry->second;
if (newTone->alarm) {
cancel_alarm(newTone->alarm);
newTone->alarm = 0;
}
}
auto newTone = new Tone();
newTone->pin = pin;
pinMode(pin, OUTPUT);
int off;
if (!_tonePgm.prepare(&newTone->pio, &newTone->sm, &off)) {
DEBUGCORE("ERROR: tone unable to start, out of PIO resources\n");
// ERROR, no free slots
delete newTone;
return;
}
tone_program_init(newTone->pio, newTone->sm, off, pin);
pio_sm_set_enabled(newTone->pio, newTone->sm, false);
pio_sm_clear_fifos(newTone->pio, newTone->sm); // Remove any old updates that haven't yet taken effect
pio_sm_put_blocking(newTone->pio, newTone->sm, RP2040::usToPIOCycles(us));
pio_sm_exec(newTone->pio, newTone->sm, pio_encode_pull(false, false));
pio_sm_exec(newTone->pio, newTone->sm, pio_encode_out(pio_isr, 32));
pio_sm_set_enabled(newTone->pio, newTone->sm, true);
pio_sm_put_blocking(newTone->pio, newTone->sm, phases);
_toneMap.insert({pin, newTone});
if (duration) {
auto ret = add_alarm_in_ms(duration, _stopTonePIO, (void *)newTone, true);
if (ret > 0) {
newTone->alarm = ret;
} else {
DEBUGCORE("ERROR: Unable to allocate timer for tone(%d, %d, %d)\n",
pin, frequency, duration);
}
}
}
void noTone(uint8_t pin) {
if ((pin < 0) || (pin > 29)) {
CoreMutex m(&_toneMutex);
if ((pin > 29) || !m) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return;
}
auto entry = _toneMap.find(pin);
if (entry != _toneMap.end()) {
if (entry->second->alarm) {
cancel_alarm(entry->second->alarm);
entry->second->alarm = 0;
}
pio_sm_set_enabled(entry->second->pio, entry->second->sm, false);
pio_sm_unclaim(entry->second->pio, entry->second->sm);
pio_sm_unclaim(entry->second->pio, entry->second->sm);
delete entry->second;
_toneMap.erase(entry);
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
+1
View File
@@ -0,0 +1 @@
#include "api/Udp.h"
+27 -27
View File
@@ -1,44 +1,44 @@
/*
Copyright (c) 2014 Arduino. All right reserved.
Copyright (c) 2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU Lesser General Public
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 "stdlib.h"
#include "stdint.h"
void randomSeed( uint32_t dwSeed ) {
if ( dwSeed != 0 ) {
srand( dwSeed ) ;
}
void randomSeed(uint32_t dwSeed) {
if (dwSeed != 0) {
srand(dwSeed) ;
}
}
long random( long howbig ) {
if ( howbig == 0 ) {
return 0 ;
}
long random(long howbig) {
if (howbig == 0) {
return 0 ;
}
return rand() % howbig;
return rand() % howbig;
}
long random( long howsmall, long howbig ) {
if (howsmall >= howbig) {
return howsmall;
}
long random(long howsmall, long howbig) {
if (howsmall >= howbig) {
return howsmall;
}
long diff = howbig - howsmall;
long diff = howbig - howsmall;
return random(diff) + howsmall;
return random(diff) + howsmall;
}
-1
View File
@@ -1 +0,0 @@
../../ArduinoCore-API/api/
+57
View File
@@ -0,0 +1,57 @@
/*
Arduino API main include
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef ARDUINO_API_H
#define ARDUINO_API_H
// version 1.2.0
#define ARDUINO_API_VERSION 10200
#include "Binary.h"
#ifdef __cplusplus
#include "Interrupts.h"
#include "IPAddress.h"
#include "Print.h"
#include "Printable.h"
#include "PluggableUSB.h"
#include "Server.h"
#include "String.h"
#include "Stream.h"
#include "Udp.h"
#include "USBAPI.h"
#include "WCharacter.h"
#endif
/* Standard C library includes */
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
// Misc Arduino core functions
#include "Common.h"
#ifdef __cplusplus
// Compatibility layer for older code
#include "Compat.h"
#endif
#endif
+552
View File
@@ -0,0 +1,552 @@
/*
binary.h - Definitions for binary constants
Deprecated -- use 0b binary literals instead
Copyright (c) 2006 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 Binary_h
#define Binary_h
/* If supported, 0b binary literals are preferable to these constants.
* In that case, warn the user about these being deprecated (if possible). */
#if __cplusplus >= 201402L
/* C++14 introduces binary literals; C++11 introduces [[deprecated()]] */
#define DEPRECATED(x) [[deprecated("use " #x " instead")]]
#elif __GNUC__ >= 6
/* GCC 4.3 supports binary literals; GCC 6 supports __deprecated__ on enums*/
#define DEPRECATED(x) __attribute__ ((__deprecated__ ("use " #x " instead")))
#else
/* binary literals not supported, or "deprecated" warning not displayable */
#define DEPRECATED(x)
#endif
enum {
B0 DEPRECATED(0b0 ) = 0,
B00 DEPRECATED(0b00 ) = 0,
B000 DEPRECATED(0b000 ) = 0,
B0000 DEPRECATED(0b0000 ) = 0,
B00000 DEPRECATED(0b00000 ) = 0,
B000000 DEPRECATED(0b000000 ) = 0,
B0000000 DEPRECATED(0b0000000 ) = 0,
B00000000 DEPRECATED(0b00000000) = 0,
B1 DEPRECATED(0b1 ) = 1,
B01 DEPRECATED(0b01 ) = 1,
B001 DEPRECATED(0b001 ) = 1,
B0001 DEPRECATED(0b0001 ) = 1,
B00001 DEPRECATED(0b00001 ) = 1,
B000001 DEPRECATED(0b000001 ) = 1,
B0000001 DEPRECATED(0b0000001 ) = 1,
B00000001 DEPRECATED(0b00000001) = 1,
B10 DEPRECATED(0b10 ) = 2,
B010 DEPRECATED(0b010 ) = 2,
B0010 DEPRECATED(0b0010 ) = 2,
B00010 DEPRECATED(0b00010 ) = 2,
B000010 DEPRECATED(0b000010 ) = 2,
B0000010 DEPRECATED(0b0000010 ) = 2,
B00000010 DEPRECATED(0b00000010) = 2,
B11 DEPRECATED(0b11 ) = 3,
B011 DEPRECATED(0b011 ) = 3,
B0011 DEPRECATED(0b0011 ) = 3,
B00011 DEPRECATED(0b00011 ) = 3,
B000011 DEPRECATED(0b000011 ) = 3,
B0000011 DEPRECATED(0b0000011 ) = 3,
B00000011 DEPRECATED(0b00000011) = 3,
B100 DEPRECATED(0b100 ) = 4,
B0100 DEPRECATED(0b0100 ) = 4,
B00100 DEPRECATED(0b00100 ) = 4,
B000100 DEPRECATED(0b000100 ) = 4,
B0000100 DEPRECATED(0b0000100 ) = 4,
B00000100 DEPRECATED(0b00000100) = 4,
B101 DEPRECATED(0b101 ) = 5,
B0101 DEPRECATED(0b0101 ) = 5,
B00101 DEPRECATED(0b00101 ) = 5,
B000101 DEPRECATED(0b000101 ) = 5,
B0000101 DEPRECATED(0b0000101 ) = 5,
B00000101 DEPRECATED(0b00000101) = 5,
B110 DEPRECATED(0b110 ) = 6,
B0110 DEPRECATED(0b0110 ) = 6,
B00110 DEPRECATED(0b00110 ) = 6,
B000110 DEPRECATED(0b000110 ) = 6,
B0000110 DEPRECATED(0b0000110 ) = 6,
B00000110 DEPRECATED(0b00000110) = 6,
B111 DEPRECATED(0b111 ) = 7,
B0111 DEPRECATED(0b0111 ) = 7,
B00111 DEPRECATED(0b00111 ) = 7,
B000111 DEPRECATED(0b000111 ) = 7,
B0000111 DEPRECATED(0b0000111 ) = 7,
B00000111 DEPRECATED(0b00000111) = 7,
B1000 DEPRECATED(0b1000 ) = 8,
B01000 DEPRECATED(0b01000 ) = 8,
B001000 DEPRECATED(0b001000 ) = 8,
B0001000 DEPRECATED(0b0001000 ) = 8,
B00001000 DEPRECATED(0b00001000) = 8,
B1001 DEPRECATED(0b1001 ) = 9,
B01001 DEPRECATED(0b01001 ) = 9,
B001001 DEPRECATED(0b001001 ) = 9,
B0001001 DEPRECATED(0b0001001 ) = 9,
B00001001 DEPRECATED(0b00001001) = 9,
B1010 DEPRECATED(0b1010 ) = 10,
B01010 DEPRECATED(0b01010 ) = 10,
B001010 DEPRECATED(0b001010 ) = 10,
B0001010 DEPRECATED(0b0001010 ) = 10,
B00001010 DEPRECATED(0b00001010) = 10,
B1011 DEPRECATED(0b1011 ) = 11,
B01011 DEPRECATED(0b01011 ) = 11,
B001011 DEPRECATED(0b001011 ) = 11,
B0001011 DEPRECATED(0b0001011 ) = 11,
B00001011 DEPRECATED(0b00001011) = 11,
B1100 DEPRECATED(0b1100 ) = 12,
B01100 DEPRECATED(0b01100 ) = 12,
B001100 DEPRECATED(0b001100 ) = 12,
B0001100 DEPRECATED(0b0001100 ) = 12,
B00001100 DEPRECATED(0b00001100) = 12,
B1101 DEPRECATED(0b1101 ) = 13,
B01101 DEPRECATED(0b01101 ) = 13,
B001101 DEPRECATED(0b001101 ) = 13,
B0001101 DEPRECATED(0b0001101 ) = 13,
B00001101 DEPRECATED(0b00001101) = 13,
B1110 DEPRECATED(0b1110 ) = 14,
B01110 DEPRECATED(0b01110 ) = 14,
B001110 DEPRECATED(0b001110 ) = 14,
B0001110 DEPRECATED(0b0001110 ) = 14,
B00001110 DEPRECATED(0b00001110) = 14,
B1111 DEPRECATED(0b1111 ) = 15,
B01111 DEPRECATED(0b01111 ) = 15,
B001111 DEPRECATED(0b001111 ) = 15,
B0001111 DEPRECATED(0b0001111 ) = 15,
B00001111 DEPRECATED(0b00001111) = 15,
B10000 DEPRECATED(0b10000 ) = 16,
B010000 DEPRECATED(0b010000 ) = 16,
B0010000 DEPRECATED(0b0010000 ) = 16,
B00010000 DEPRECATED(0b00010000) = 16,
B10001 DEPRECATED(0b10001 ) = 17,
B010001 DEPRECATED(0b010001 ) = 17,
B0010001 DEPRECATED(0b0010001 ) = 17,
B00010001 DEPRECATED(0b00010001) = 17,
B10010 DEPRECATED(0b10010 ) = 18,
B010010 DEPRECATED(0b010010 ) = 18,
B0010010 DEPRECATED(0b0010010 ) = 18,
B00010010 DEPRECATED(0b00010010) = 18,
B10011 DEPRECATED(0b10011 ) = 19,
B010011 DEPRECATED(0b010011 ) = 19,
B0010011 DEPRECATED(0b0010011 ) = 19,
B00010011 DEPRECATED(0b00010011) = 19,
B10100 DEPRECATED(0b10100 ) = 20,
B010100 DEPRECATED(0b010100 ) = 20,
B0010100 DEPRECATED(0b0010100 ) = 20,
B00010100 DEPRECATED(0b00010100) = 20,
B10101 DEPRECATED(0b10101 ) = 21,
B010101 DEPRECATED(0b010101 ) = 21,
B0010101 DEPRECATED(0b0010101 ) = 21,
B00010101 DEPRECATED(0b00010101) = 21,
B10110 DEPRECATED(0b10110 ) = 22,
B010110 DEPRECATED(0b010110 ) = 22,
B0010110 DEPRECATED(0b0010110 ) = 22,
B00010110 DEPRECATED(0b00010110) = 22,
B10111 DEPRECATED(0b10111 ) = 23,
B010111 DEPRECATED(0b010111 ) = 23,
B0010111 DEPRECATED(0b0010111 ) = 23,
B00010111 DEPRECATED(0b00010111) = 23,
B11000 DEPRECATED(0b11000 ) = 24,
B011000 DEPRECATED(0b011000 ) = 24,
B0011000 DEPRECATED(0b0011000 ) = 24,
B00011000 DEPRECATED(0b00011000) = 24,
B11001 DEPRECATED(0b11001 ) = 25,
B011001 DEPRECATED(0b011001 ) = 25,
B0011001 DEPRECATED(0b0011001 ) = 25,
B00011001 DEPRECATED(0b00011001) = 25,
B11010 DEPRECATED(0b11010 ) = 26,
B011010 DEPRECATED(0b011010 ) = 26,
B0011010 DEPRECATED(0b0011010 ) = 26,
B00011010 DEPRECATED(0b00011010) = 26,
B11011 DEPRECATED(0b11011 ) = 27,
B011011 DEPRECATED(0b011011 ) = 27,
B0011011 DEPRECATED(0b0011011 ) = 27,
B00011011 DEPRECATED(0b00011011) = 27,
B11100 DEPRECATED(0b11100 ) = 28,
B011100 DEPRECATED(0b011100 ) = 28,
B0011100 DEPRECATED(0b0011100 ) = 28,
B00011100 DEPRECATED(0b00011100) = 28,
B11101 DEPRECATED(0b11101 ) = 29,
B011101 DEPRECATED(0b011101 ) = 29,
B0011101 DEPRECATED(0b0011101 ) = 29,
B00011101 DEPRECATED(0b00011101) = 29,
B11110 DEPRECATED(0b11110 ) = 30,
B011110 DEPRECATED(0b011110 ) = 30,
B0011110 DEPRECATED(0b0011110 ) = 30,
B00011110 DEPRECATED(0b00011110) = 30,
B11111 DEPRECATED(0b11111 ) = 31,
B011111 DEPRECATED(0b011111 ) = 31,
B0011111 DEPRECATED(0b0011111 ) = 31,
B00011111 DEPRECATED(0b00011111) = 31,
B100000 DEPRECATED(0b100000 ) = 32,
B0100000 DEPRECATED(0b0100000 ) = 32,
B00100000 DEPRECATED(0b00100000) = 32,
B100001 DEPRECATED(0b100001 ) = 33,
B0100001 DEPRECATED(0b0100001 ) = 33,
B00100001 DEPRECATED(0b00100001) = 33,
B100010 DEPRECATED(0b100010 ) = 34,
B0100010 DEPRECATED(0b0100010 ) = 34,
B00100010 DEPRECATED(0b00100010) = 34,
B100011 DEPRECATED(0b100011 ) = 35,
B0100011 DEPRECATED(0b0100011 ) = 35,
B00100011 DEPRECATED(0b00100011) = 35,
B100100 DEPRECATED(0b100100 ) = 36,
B0100100 DEPRECATED(0b0100100 ) = 36,
B00100100 DEPRECATED(0b00100100) = 36,
B100101 DEPRECATED(0b100101 ) = 37,
B0100101 DEPRECATED(0b0100101 ) = 37,
B00100101 DEPRECATED(0b00100101) = 37,
B100110 DEPRECATED(0b100110 ) = 38,
B0100110 DEPRECATED(0b0100110 ) = 38,
B00100110 DEPRECATED(0b00100110) = 38,
B100111 DEPRECATED(0b100111 ) = 39,
B0100111 DEPRECATED(0b0100111 ) = 39,
B00100111 DEPRECATED(0b00100111) = 39,
B101000 DEPRECATED(0b101000 ) = 40,
B0101000 DEPRECATED(0b0101000 ) = 40,
B00101000 DEPRECATED(0b00101000) = 40,
B101001 DEPRECATED(0b101001 ) = 41,
B0101001 DEPRECATED(0b0101001 ) = 41,
B00101001 DEPRECATED(0b00101001) = 41,
B101010 DEPRECATED(0b101010 ) = 42,
B0101010 DEPRECATED(0b0101010 ) = 42,
B00101010 DEPRECATED(0b00101010) = 42,
B101011 DEPRECATED(0b101011 ) = 43,
B0101011 DEPRECATED(0b0101011 ) = 43,
B00101011 DEPRECATED(0b00101011) = 43,
B101100 DEPRECATED(0b101100 ) = 44,
B0101100 DEPRECATED(0b0101100 ) = 44,
B00101100 DEPRECATED(0b00101100) = 44,
B101101 DEPRECATED(0b101101 ) = 45,
B0101101 DEPRECATED(0b0101101 ) = 45,
B00101101 DEPRECATED(0b00101101) = 45,
B101110 DEPRECATED(0b101110 ) = 46,
B0101110 DEPRECATED(0b0101110 ) = 46,
B00101110 DEPRECATED(0b00101110) = 46,
B101111 DEPRECATED(0b101111 ) = 47,
B0101111 DEPRECATED(0b0101111 ) = 47,
B00101111 DEPRECATED(0b00101111) = 47,
B110000 DEPRECATED(0b110000 ) = 48,
B0110000 DEPRECATED(0b0110000 ) = 48,
B00110000 DEPRECATED(0b00110000) = 48,
B110001 DEPRECATED(0b110001 ) = 49,
B0110001 DEPRECATED(0b0110001 ) = 49,
B00110001 DEPRECATED(0b00110001) = 49,
B110010 DEPRECATED(0b110010 ) = 50,
B0110010 DEPRECATED(0b0110010 ) = 50,
B00110010 DEPRECATED(0b00110010) = 50,
B110011 DEPRECATED(0b110011 ) = 51,
B0110011 DEPRECATED(0b0110011 ) = 51,
B00110011 DEPRECATED(0b00110011) = 51,
B110100 DEPRECATED(0b110100 ) = 52,
B0110100 DEPRECATED(0b0110100 ) = 52,
B00110100 DEPRECATED(0b00110100) = 52,
B110101 DEPRECATED(0b110101 ) = 53,
B0110101 DEPRECATED(0b0110101 ) = 53,
B00110101 DEPRECATED(0b00110101) = 53,
B110110 DEPRECATED(0b110110 ) = 54,
B0110110 DEPRECATED(0b0110110 ) = 54,
B00110110 DEPRECATED(0b00110110) = 54,
B110111 DEPRECATED(0b110111 ) = 55,
B0110111 DEPRECATED(0b0110111 ) = 55,
B00110111 DEPRECATED(0b00110111) = 55,
B111000 DEPRECATED(0b111000 ) = 56,
B0111000 DEPRECATED(0b0111000 ) = 56,
B00111000 DEPRECATED(0b00111000) = 56,
B111001 DEPRECATED(0b111001 ) = 57,
B0111001 DEPRECATED(0b0111001 ) = 57,
B00111001 DEPRECATED(0b00111001) = 57,
B111010 DEPRECATED(0b111010 ) = 58,
B0111010 DEPRECATED(0b0111010 ) = 58,
B00111010 DEPRECATED(0b00111010) = 58,
B111011 DEPRECATED(0b111011 ) = 59,
B0111011 DEPRECATED(0b0111011 ) = 59,
B00111011 DEPRECATED(0b00111011) = 59,
B111100 DEPRECATED(0b111100 ) = 60,
B0111100 DEPRECATED(0b0111100 ) = 60,
B00111100 DEPRECATED(0b00111100) = 60,
B111101 DEPRECATED(0b111101 ) = 61,
B0111101 DEPRECATED(0b0111101 ) = 61,
B00111101 DEPRECATED(0b00111101) = 61,
B111110 DEPRECATED(0b111110 ) = 62,
B0111110 DEPRECATED(0b0111110 ) = 62,
B00111110 DEPRECATED(0b00111110) = 62,
B111111 DEPRECATED(0b111111 ) = 63,
B0111111 DEPRECATED(0b0111111 ) = 63,
B00111111 DEPRECATED(0b00111111) = 63,
B1000000 DEPRECATED(0b1000000 ) = 64,
B01000000 DEPRECATED(0b01000000) = 64,
B1000001 DEPRECATED(0b1000001 ) = 65,
B01000001 DEPRECATED(0b01000001) = 65,
B1000010 DEPRECATED(0b1000010 ) = 66,
B01000010 DEPRECATED(0b01000010) = 66,
B1000011 DEPRECATED(0b1000011 ) = 67,
B01000011 DEPRECATED(0b01000011) = 67,
B1000100 DEPRECATED(0b1000100 ) = 68,
B01000100 DEPRECATED(0b01000100) = 68,
B1000101 DEPRECATED(0b1000101 ) = 69,
B01000101 DEPRECATED(0b01000101) = 69,
B1000110 DEPRECATED(0b1000110 ) = 70,
B01000110 DEPRECATED(0b01000110) = 70,
B1000111 DEPRECATED(0b1000111 ) = 71,
B01000111 DEPRECATED(0b01000111) = 71,
B1001000 DEPRECATED(0b1001000 ) = 72,
B01001000 DEPRECATED(0b01001000) = 72,
B1001001 DEPRECATED(0b1001001 ) = 73,
B01001001 DEPRECATED(0b01001001) = 73,
B1001010 DEPRECATED(0b1001010 ) = 74,
B01001010 DEPRECATED(0b01001010) = 74,
B1001011 DEPRECATED(0b1001011 ) = 75,
B01001011 DEPRECATED(0b01001011) = 75,
B1001100 DEPRECATED(0b1001100 ) = 76,
B01001100 DEPRECATED(0b01001100) = 76,
B1001101 DEPRECATED(0b1001101 ) = 77,
B01001101 DEPRECATED(0b01001101) = 77,
B1001110 DEPRECATED(0b1001110 ) = 78,
B01001110 DEPRECATED(0b01001110) = 78,
B1001111 DEPRECATED(0b1001111 ) = 79,
B01001111 DEPRECATED(0b01001111) = 79,
B1010000 DEPRECATED(0b1010000 ) = 80,
B01010000 DEPRECATED(0b01010000) = 80,
B1010001 DEPRECATED(0b1010001 ) = 81,
B01010001 DEPRECATED(0b01010001) = 81,
B1010010 DEPRECATED(0b1010010 ) = 82,
B01010010 DEPRECATED(0b01010010) = 82,
B1010011 DEPRECATED(0b1010011 ) = 83,
B01010011 DEPRECATED(0b01010011) = 83,
B1010100 DEPRECATED(0b1010100 ) = 84,
B01010100 DEPRECATED(0b01010100) = 84,
B1010101 DEPRECATED(0b1010101 ) = 85,
B01010101 DEPRECATED(0b01010101) = 85,
B1010110 DEPRECATED(0b1010110 ) = 86,
B01010110 DEPRECATED(0b01010110) = 86,
B1010111 DEPRECATED(0b1010111 ) = 87,
B01010111 DEPRECATED(0b01010111) = 87,
B1011000 DEPRECATED(0b1011000 ) = 88,
B01011000 DEPRECATED(0b01011000) = 88,
B1011001 DEPRECATED(0b1011001 ) = 89,
B01011001 DEPRECATED(0b01011001) = 89,
B1011010 DEPRECATED(0b1011010 ) = 90,
B01011010 DEPRECATED(0b01011010) = 90,
B1011011 DEPRECATED(0b1011011 ) = 91,
B01011011 DEPRECATED(0b01011011) = 91,
B1011100 DEPRECATED(0b1011100 ) = 92,
B01011100 DEPRECATED(0b01011100) = 92,
B1011101 DEPRECATED(0b1011101 ) = 93,
B01011101 DEPRECATED(0b01011101) = 93,
B1011110 DEPRECATED(0b1011110 ) = 94,
B01011110 DEPRECATED(0b01011110) = 94,
B1011111 DEPRECATED(0b1011111 ) = 95,
B01011111 DEPRECATED(0b01011111) = 95,
B1100000 DEPRECATED(0b1100000 ) = 96,
B01100000 DEPRECATED(0b01100000) = 96,
B1100001 DEPRECATED(0b1100001 ) = 97,
B01100001 DEPRECATED(0b01100001) = 97,
B1100010 DEPRECATED(0b1100010 ) = 98,
B01100010 DEPRECATED(0b01100010) = 98,
B1100011 DEPRECATED(0b1100011 ) = 99,
B01100011 DEPRECATED(0b01100011) = 99,
B1100100 DEPRECATED(0b1100100 ) = 100,
B01100100 DEPRECATED(0b01100100) = 100,
B1100101 DEPRECATED(0b1100101 ) = 101,
B01100101 DEPRECATED(0b01100101) = 101,
B1100110 DEPRECATED(0b1100110 ) = 102,
B01100110 DEPRECATED(0b01100110) = 102,
B1100111 DEPRECATED(0b1100111 ) = 103,
B01100111 DEPRECATED(0b01100111) = 103,
B1101000 DEPRECATED(0b1101000 ) = 104,
B01101000 DEPRECATED(0b01101000) = 104,
B1101001 DEPRECATED(0b1101001 ) = 105,
B01101001 DEPRECATED(0b01101001) = 105,
B1101010 DEPRECATED(0b1101010 ) = 106,
B01101010 DEPRECATED(0b01101010) = 106,
B1101011 DEPRECATED(0b1101011 ) = 107,
B01101011 DEPRECATED(0b01101011) = 107,
B1101100 DEPRECATED(0b1101100 ) = 108,
B01101100 DEPRECATED(0b01101100) = 108,
B1101101 DEPRECATED(0b1101101 ) = 109,
B01101101 DEPRECATED(0b01101101) = 109,
B1101110 DEPRECATED(0b1101110 ) = 110,
B01101110 DEPRECATED(0b01101110) = 110,
B1101111 DEPRECATED(0b1101111 ) = 111,
B01101111 DEPRECATED(0b01101111) = 111,
B1110000 DEPRECATED(0b1110000 ) = 112,
B01110000 DEPRECATED(0b01110000) = 112,
B1110001 DEPRECATED(0b1110001 ) = 113,
B01110001 DEPRECATED(0b01110001) = 113,
B1110010 DEPRECATED(0b1110010 ) = 114,
B01110010 DEPRECATED(0b01110010) = 114,
B1110011 DEPRECATED(0b1110011 ) = 115,
B01110011 DEPRECATED(0b01110011) = 115,
B1110100 DEPRECATED(0b1110100 ) = 116,
B01110100 DEPRECATED(0b01110100) = 116,
B1110101 DEPRECATED(0b1110101 ) = 117,
B01110101 DEPRECATED(0b01110101) = 117,
B1110110 DEPRECATED(0b1110110 ) = 118,
B01110110 DEPRECATED(0b01110110) = 118,
B1110111 DEPRECATED(0b1110111 ) = 119,
B01110111 DEPRECATED(0b01110111) = 119,
B1111000 DEPRECATED(0b1111000 ) = 120,
B01111000 DEPRECATED(0b01111000) = 120,
B1111001 DEPRECATED(0b1111001 ) = 121,
B01111001 DEPRECATED(0b01111001) = 121,
B1111010 DEPRECATED(0b1111010 ) = 122,
B01111010 DEPRECATED(0b01111010) = 122,
B1111011 DEPRECATED(0b1111011 ) = 123,
B01111011 DEPRECATED(0b01111011) = 123,
B1111100 DEPRECATED(0b1111100 ) = 124,
B01111100 DEPRECATED(0b01111100) = 124,
B1111101 DEPRECATED(0b1111101 ) = 125,
B01111101 DEPRECATED(0b01111101) = 125,
B1111110 DEPRECATED(0b1111110 ) = 126,
B01111110 DEPRECATED(0b01111110) = 126,
B1111111 DEPRECATED(0b1111111 ) = 127,
B01111111 DEPRECATED(0b01111111) = 127,
B10000000 DEPRECATED(0b10000000) = 128,
B10000001 DEPRECATED(0b10000001) = 129,
B10000010 DEPRECATED(0b10000010) = 130,
B10000011 DEPRECATED(0b10000011) = 131,
B10000100 DEPRECATED(0b10000100) = 132,
B10000101 DEPRECATED(0b10000101) = 133,
B10000110 DEPRECATED(0b10000110) = 134,
B10000111 DEPRECATED(0b10000111) = 135,
B10001000 DEPRECATED(0b10001000) = 136,
B10001001 DEPRECATED(0b10001001) = 137,
B10001010 DEPRECATED(0b10001010) = 138,
B10001011 DEPRECATED(0b10001011) = 139,
B10001100 DEPRECATED(0b10001100) = 140,
B10001101 DEPRECATED(0b10001101) = 141,
B10001110 DEPRECATED(0b10001110) = 142,
B10001111 DEPRECATED(0b10001111) = 143,
B10010000 DEPRECATED(0b10010000) = 144,
B10010001 DEPRECATED(0b10010001) = 145,
B10010010 DEPRECATED(0b10010010) = 146,
B10010011 DEPRECATED(0b10010011) = 147,
B10010100 DEPRECATED(0b10010100) = 148,
B10010101 DEPRECATED(0b10010101) = 149,
B10010110 DEPRECATED(0b10010110) = 150,
B10010111 DEPRECATED(0b10010111) = 151,
B10011000 DEPRECATED(0b10011000) = 152,
B10011001 DEPRECATED(0b10011001) = 153,
B10011010 DEPRECATED(0b10011010) = 154,
B10011011 DEPRECATED(0b10011011) = 155,
B10011100 DEPRECATED(0b10011100) = 156,
B10011101 DEPRECATED(0b10011101) = 157,
B10011110 DEPRECATED(0b10011110) = 158,
B10011111 DEPRECATED(0b10011111) = 159,
B10100000 DEPRECATED(0b10100000) = 160,
B10100001 DEPRECATED(0b10100001) = 161,
B10100010 DEPRECATED(0b10100010) = 162,
B10100011 DEPRECATED(0b10100011) = 163,
B10100100 DEPRECATED(0b10100100) = 164,
B10100101 DEPRECATED(0b10100101) = 165,
B10100110 DEPRECATED(0b10100110) = 166,
B10100111 DEPRECATED(0b10100111) = 167,
B10101000 DEPRECATED(0b10101000) = 168,
B10101001 DEPRECATED(0b10101001) = 169,
B10101010 DEPRECATED(0b10101010) = 170,
B10101011 DEPRECATED(0b10101011) = 171,
B10101100 DEPRECATED(0b10101100) = 172,
B10101101 DEPRECATED(0b10101101) = 173,
B10101110 DEPRECATED(0b10101110) = 174,
B10101111 DEPRECATED(0b10101111) = 175,
B10110000 DEPRECATED(0b10110000) = 176,
B10110001 DEPRECATED(0b10110001) = 177,
B10110010 DEPRECATED(0b10110010) = 178,
B10110011 DEPRECATED(0b10110011) = 179,
B10110100 DEPRECATED(0b10110100) = 180,
B10110101 DEPRECATED(0b10110101) = 181,
B10110110 DEPRECATED(0b10110110) = 182,
B10110111 DEPRECATED(0b10110111) = 183,
B10111000 DEPRECATED(0b10111000) = 184,
B10111001 DEPRECATED(0b10111001) = 185,
B10111010 DEPRECATED(0b10111010) = 186,
B10111011 DEPRECATED(0b10111011) = 187,
B10111100 DEPRECATED(0b10111100) = 188,
B10111101 DEPRECATED(0b10111101) = 189,
B10111110 DEPRECATED(0b10111110) = 190,
B10111111 DEPRECATED(0b10111111) = 191,
B11000000 DEPRECATED(0b11000000) = 192,
B11000001 DEPRECATED(0b11000001) = 193,
B11000010 DEPRECATED(0b11000010) = 194,
B11000011 DEPRECATED(0b11000011) = 195,
B11000100 DEPRECATED(0b11000100) = 196,
B11000101 DEPRECATED(0b11000101) = 197,
B11000110 DEPRECATED(0b11000110) = 198,
B11000111 DEPRECATED(0b11000111) = 199,
B11001000 DEPRECATED(0b11001000) = 200,
B11001001 DEPRECATED(0b11001001) = 201,
B11001010 DEPRECATED(0b11001010) = 202,
B11001011 DEPRECATED(0b11001011) = 203,
B11001100 DEPRECATED(0b11001100) = 204,
B11001101 DEPRECATED(0b11001101) = 205,
B11001110 DEPRECATED(0b11001110) = 206,
B11001111 DEPRECATED(0b11001111) = 207,
B11010000 DEPRECATED(0b11010000) = 208,
B11010001 DEPRECATED(0b11010001) = 209,
B11010010 DEPRECATED(0b11010010) = 210,
B11010011 DEPRECATED(0b11010011) = 211,
B11010100 DEPRECATED(0b11010100) = 212,
B11010101 DEPRECATED(0b11010101) = 213,
B11010110 DEPRECATED(0b11010110) = 214,
B11010111 DEPRECATED(0b11010111) = 215,
B11011000 DEPRECATED(0b11011000) = 216,
B11011001 DEPRECATED(0b11011001) = 217,
B11011010 DEPRECATED(0b11011010) = 218,
B11011011 DEPRECATED(0b11011011) = 219,
B11011100 DEPRECATED(0b11011100) = 220,
B11011101 DEPRECATED(0b11011101) = 221,
B11011110 DEPRECATED(0b11011110) = 222,
B11011111 DEPRECATED(0b11011111) = 223,
B11100000 DEPRECATED(0b11100000) = 224,
B11100001 DEPRECATED(0b11100001) = 225,
B11100010 DEPRECATED(0b11100010) = 226,
B11100011 DEPRECATED(0b11100011) = 227,
B11100100 DEPRECATED(0b11100100) = 228,
B11100101 DEPRECATED(0b11100101) = 229,
B11100110 DEPRECATED(0b11100110) = 230,
B11100111 DEPRECATED(0b11100111) = 231,
B11101000 DEPRECATED(0b11101000) = 232,
B11101001 DEPRECATED(0b11101001) = 233,
B11101010 DEPRECATED(0b11101010) = 234,
B11101011 DEPRECATED(0b11101011) = 235,
B11101100 DEPRECATED(0b11101100) = 236,
B11101101 DEPRECATED(0b11101101) = 237,
B11101110 DEPRECATED(0b11101110) = 238,
B11101111 DEPRECATED(0b11101111) = 239,
B11110000 DEPRECATED(0b11110000) = 240,
B11110001 DEPRECATED(0b11110001) = 241,
B11110010 DEPRECATED(0b11110010) = 242,
B11110011 DEPRECATED(0b11110011) = 243,
B11110100 DEPRECATED(0b11110100) = 244,
B11110101 DEPRECATED(0b11110101) = 245,
B11110110 DEPRECATED(0b11110110) = 246,
B11110111 DEPRECATED(0b11110111) = 247,
B11111000 DEPRECATED(0b11111000) = 248,
B11111001 DEPRECATED(0b11111001) = 249,
B11111010 DEPRECATED(0b11111010) = 250,
B11111011 DEPRECATED(0b11111011) = 251,
B11111100 DEPRECATED(0b11111100) = 252,
B11111101 DEPRECATED(0b11111101) = 253,
B11111110 DEPRECATED(0b11111110) = 254,
B11111111 DEPRECATED(0b11111111) = 255
};
#undef DEPRECATED
#endif
+46
View File
@@ -0,0 +1,46 @@
/*
Client.h - Base class that provides Client
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "Stream.h"
#include "IPAddress.h"
namespace arduino {
class Client : public Stream {
public:
virtual int connect(IPAddress ip, uint16_t port) =0;
virtual int connect(const char *host, uint16_t port) =0;
virtual size_t write(uint8_t) =0;
virtual size_t write(const uint8_t *buf, size_t size) =0;
virtual int available() = 0;
virtual int read() = 0;
virtual int read(uint8_t *buf, size_t size) = 0;
virtual int peek() = 0;
virtual void flush() = 0;
virtual void stop() = 0;
virtual uint8_t connected() = 0;
virtual operator bool() = 0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};
}
+10
View File
@@ -0,0 +1,10 @@
#include "Common.h"
/* C++ prototypes */
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
uint16_t makeWord(uint16_t w) { return w; }
uint16_t makeWord(uint8_t h, uint8_t l) { return (h << 8) | l; }
+169
View File
@@ -0,0 +1,169 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C"{
#endif
void yield(void);
typedef enum {
LOW = 0,
HIGH = 1,
CHANGE = 2,
FALLING = 3,
RISING = 4,
} PinStatus;
typedef enum {
INPUT = 0x0,
OUTPUT = 0x1,
INPUT_PULLUP = 0x2,
INPUT_PULLDOWN = 0x3,
} PinMode;
typedef enum {
LSBFIRST = 0,
MSBFIRST = 1,
} BitOrder;
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define EULER 2.718281828459045235360287471352
#define SERIAL 0x0
#define DISPLAY 0x1
#ifndef constrain
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#endif
#ifndef radians
#define radians(deg) ((deg)*DEG_TO_RAD)
#endif
#ifndef degrees
#define degrees(rad) ((rad)*RAD_TO_DEG)
#endif
#ifndef sq
#define sq(x) ((x)*(x))
#endif
typedef void (*voidFuncPtr)(void);
typedef void (*voidFuncPtrParam)(void*);
// interrupts() / noInterrupts() must be defined by the core
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitToggle(value, bit) ((value) ^= (1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
#ifndef bit
#define bit(b) (1UL << (b))
#endif
/* TODO: request for removal */
typedef bool boolean;
typedef uint8_t byte;
typedef uint16_t word;
void init(void);
void initVariant(void);
#ifndef HOST
int atexit(void (*func)()) __attribute__((weak));
#endif
int main() __attribute__((weak));
#ifdef EXTENDED_PIN_MODE
// Platforms who wnat to declare more than 256 pins need to define EXTENDED_PIN_MODE globally
typedef uint32_t pin_size_t;
#else
typedef uint8_t pin_size_t;
#endif
void pinMode(pin_size_t pinNumber, PinMode pinMode);
void digitalWrite(pin_size_t pinNumber, PinStatus status);
PinStatus digitalRead(pin_size_t pinNumber);
int analogRead(pin_size_t pinNumber);
void analogReference(uint8_t mode);
void analogWrite(pin_size_t pinNumber, int value);
unsigned long millis(void);
unsigned long micros(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(pin_size_t pin, uint8_t state, unsigned long timeout);
unsigned long pulseInLong(pin_size_t pin, uint8_t state, unsigned long timeout);
void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val);
uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder);
void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode);
void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void* param);
void detachInterrupt(pin_size_t interruptNumber);
void setup(void);
void loop(void);
#ifdef __cplusplus
} // extern "C"
#endif
#ifdef __cplusplus
template<class T, class L>
auto min(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (b < a) ? b : a;
}
template<class T, class L>
auto max(const T& a, const L& b) -> decltype((b < a) ? b : a)
{
return (a < b) ? b : a;
}
#else
#ifndef min
#define min(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a < _b ? _a : _b; })
#endif
#ifndef max
#define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })
#endif
#endif
#ifdef __cplusplus
/* C++ prototypes */
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin);
// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned long);
long map(long, long, long, long, long);
#endif // __cplusplus
+16
View File
@@ -0,0 +1,16 @@
#ifndef __COMPAT_H__
#define __COMPAT_H__
namespace arduino {
inline void pinMode(pin_size_t pinNumber, int mode) {
pinMode(pinNumber, (PinMode)mode);
};
inline void digitalWrite(pin_size_t pinNumber, int status) {
digitalWrite(pinNumber, (PinStatus)status);
};
}
#endif
+47
View File
@@ -0,0 +1,47 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <inttypes.h>
#include "Stream.h"
namespace arduino {
class HardwareI2C : public Stream
{
public:
virtual void begin() = 0;
virtual void begin(uint8_t address) = 0;
virtual void end() = 0;
virtual void setClock(uint32_t freq) = 0;
virtual void beginTransmission(uint8_t address) = 0;
virtual uint8_t endTransmission(bool stopBit) = 0;
virtual uint8_t endTransmission(void) = 0;
virtual size_t requestFrom(uint8_t address, size_t len, bool stopBit) = 0;
virtual size_t requestFrom(uint8_t address, size_t len) = 0;
virtual void onReceive(void(*)(int)) = 0;
virtual void onRequest(void(*)(void)) = 0;
};
}
+130
View File
@@ -0,0 +1,130 @@
/*
Copyright (c) 2018 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "Common.h"
#include <inttypes.h>
#include "Stream.h"
#define SPI_HAS_TRANSACTION
namespace arduino {
typedef enum {
SPI_MODE0 = 0,
SPI_MODE1 = 1,
SPI_MODE2 = 2,
SPI_MODE3 = 3,
} SPIMode;
class SPISettings {
public:
SPISettings(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode);
} else {
init_MightInline(clock, bitOrder, dataMode);
}
}
SPISettings(uint32_t clock, BitOrder bitOrder, int dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, (SPIMode)dataMode);
} else {
init_MightInline(clock, bitOrder, (SPIMode)dataMode);
}
}
// Default speed set to 4MHz, SPI mode set to MODE 0 and Bit order set to MSB first.
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
bool operator==(const SPISettings& rhs) const
{
if ((this->clockFreq == rhs.clockFreq) &&
(this->bitOrder == rhs.bitOrder) &&
(this->dataMode == rhs.dataMode)) {
return true;
}
return false;
}
bool operator!=(const SPISettings& rhs) const
{
return !(*this == rhs);
}
uint32_t getClockFreq() const {
return clockFreq;
}
SPIMode getDataMode() const {
return dataMode;
}
BitOrder getBitOrder() const {
return (bitOrder);
}
private:
void init_MightInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) {
init_AlwaysInline(clock, bitOrder, dataMode);
}
// Core developer MUST use an helper function in beginTransaction() to use this data
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, SPIMode dataMode) __attribute__((__always_inline__)) {
this->clockFreq = clock;
this->dataMode = dataMode;
this->bitOrder = bitOrder;
}
uint32_t clockFreq;
SPIMode dataMode;
BitOrder bitOrder;
friend class HardwareSPI;
};
const SPISettings DEFAULT_SPI_SETTINGS = SPISettings();
class HardwareSPI
{
public:
virtual ~HardwareSPI() { }
virtual uint8_t transfer(uint8_t data) = 0;
virtual uint16_t transfer16(uint16_t data) = 0;
virtual void transfer(void *buf, size_t count) = 0;
// Transaction Functions
virtual void usingInterrupt(int interruptNumber) = 0;
virtual void notUsingInterrupt(int interruptNumber) = 0;
virtual void beginTransaction(SPISettings settings) = 0;
virtual void endTransaction(void) = 0;
// SPI Configuration methods
virtual void attachInterrupt() = 0;
virtual void detachInterrupt() = 0;
virtual void begin() = 0;
virtual void end() = 0;
};
// Alias SPIClass to HardwareSPI since it's already the defacto standard for SPI classe name
typedef HardwareSPI SPIClass;
}
+105
View File
@@ -0,0 +1,105 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <inttypes.h>
#include "Stream.h"
namespace arduino {
// XXX: Those constants should be defined as const int / enums?
// XXX: shall we use namespaces too?
#define SERIAL_PARITY_EVEN (0x1ul)
#define SERIAL_PARITY_ODD (0x2ul)
#define SERIAL_PARITY_NONE (0x3ul)
#define SERIAL_PARITY_MARK (0x4ul)
#define SERIAL_PARITY_SPACE (0x5ul)
#define SERIAL_PARITY_MASK (0xFul)
#define SERIAL_STOP_BIT_1 (0x10ul)
#define SERIAL_STOP_BIT_1_5 (0x20ul)
#define SERIAL_STOP_BIT_2 (0x30ul)
#define SERIAL_STOP_BIT_MASK (0xF0ul)
#define SERIAL_DATA_5 (0x100ul)
#define SERIAL_DATA_6 (0x200ul)
#define SERIAL_DATA_7 (0x300ul)
#define SERIAL_DATA_8 (0x400ul)
#define SERIAL_DATA_MASK (0xF00ul)
#define SERIAL_5N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_5)
#define SERIAL_6N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_6)
#define SERIAL_7N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_7)
#define SERIAL_8N1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_NONE | SERIAL_DATA_8)
#define SERIAL_5N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_5)
#define SERIAL_6N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_6)
#define SERIAL_7N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_7)
#define SERIAL_8N2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_NONE | SERIAL_DATA_8)
#define SERIAL_5E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_5)
#define SERIAL_6E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_6)
#define SERIAL_7E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_7)
#define SERIAL_8E1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_EVEN | SERIAL_DATA_8)
#define SERIAL_5E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_5)
#define SERIAL_6E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_6)
#define SERIAL_7E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_7)
#define SERIAL_8E2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_EVEN | SERIAL_DATA_8)
#define SERIAL_5O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_5)
#define SERIAL_6O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_6)
#define SERIAL_7O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_7)
#define SERIAL_8O1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_ODD | SERIAL_DATA_8)
#define SERIAL_5O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_5)
#define SERIAL_6O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_6)
#define SERIAL_7O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_7)
#define SERIAL_8O2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_ODD | SERIAL_DATA_8)
#define SERIAL_5M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_5)
#define SERIAL_6M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_6)
#define SERIAL_7M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_7)
#define SERIAL_8M1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_MARK | SERIAL_DATA_8)
#define SERIAL_5M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_5)
#define SERIAL_6M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_6)
#define SERIAL_7M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_7)
#define SERIAL_8M2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_MARK | SERIAL_DATA_8)
#define SERIAL_5S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_5)
#define SERIAL_6S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_6)
#define SERIAL_7S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_7)
#define SERIAL_8S1 (SERIAL_STOP_BIT_1 | SERIAL_PARITY_SPACE | SERIAL_DATA_8)
#define SERIAL_5S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_5)
#define SERIAL_6S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_6)
#define SERIAL_7S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_7)
#define SERIAL_8S2 (SERIAL_STOP_BIT_2 | SERIAL_PARITY_SPACE | SERIAL_DATA_8)
class HardwareSerial : public Stream
{
public:
virtual void begin(unsigned long) = 0;
virtual void begin(unsigned long baudrate, uint16_t config) = 0;
virtual void end() = 0;
virtual int available(void) = 0;
virtual int peek(void) = 0;
virtual int read(void) = 0;
virtual void flush(void) = 0;
virtual size_t write(uint8_t) = 0;
using Print::write; // pull in write(str) and write(buf, size) from Print
virtual operator bool() = 0;
};
// XXX: Are we keeping the serialEvent API?
extern void serialEventRun(void) __attribute__((weak));
}
+127
View File
@@ -0,0 +1,127 @@
/*
IPAddress.cpp - Base class that provides IPAddress
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 "IPAddress.h"
#include "Print.h"
using namespace arduino;
IPAddress::IPAddress()
{
_address.dword = 0;
}
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
{
_address.bytes[0] = first_octet;
_address.bytes[1] = second_octet;
_address.bytes[2] = third_octet;
_address.bytes[3] = fourth_octet;
}
IPAddress::IPAddress(uint32_t address)
{
_address.dword = address;
}
IPAddress::IPAddress(const uint8_t *address)
{
memcpy(_address.bytes, address, sizeof(_address.bytes));
}
bool IPAddress::fromString(const char *address)
{
// TODO: add support for "a", "a.b", "a.b.c" formats
int16_t acc = -1; // Accumulator
uint8_t dots = 0;
while (*address)
{
char c = *address++;
if (c >= '0' && c <= '9')
{
acc = (acc < 0) ? (c - '0') : acc * 10 + (c - '0');
if (acc > 255) {
// Value out of [0..255] range
return false;
}
}
else if (c == '.')
{
if (dots == 3) {
// Too much dots (there must be 3 dots)
return false;
}
if (acc < 0) {
/* No value between dots, e.g. '1..' */
return false;
}
_address.bytes[dots++] = acc;
acc = -1;
}
else
{
// Invalid char
return false;
}
}
if (dots != 3) {
// Too few dots (there must be 3 dots)
return false;
}
if (acc < 0) {
/* No value between dots, e.g. '1..' */
return false;
}
_address.bytes[3] = acc;
return true;
}
IPAddress& IPAddress::operator=(const uint8_t *address)
{
memcpy(_address.bytes, address, sizeof(_address.bytes));
return *this;
}
IPAddress& IPAddress::operator=(uint32_t address)
{
_address.dword = address;
return *this;
}
bool IPAddress::operator==(const uint8_t* addr) const
{
return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
}
size_t IPAddress::printTo(Print& p) const
{
size_t n = 0;
for (int i =0; i < 3; i++)
{
n += p.print(_address.bytes[i], DEC);
n += p.print('.');
}
n += p.print(_address.bytes[3], DEC);
return n;
}
const IPAddress arduino::INADDR_NONE(0,0,0,0);
+85
View File
@@ -0,0 +1,85 @@
/*
IPAddress.h - Base class that provides IPAddress
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <stdint.h>
#include "Printable.h"
#include "String.h"
// forward declartions of global name space friend classes
class EthernetClass;
class DhcpClass;
class DNSClient;
namespace arduino {
// A class to make it easier to handle and pass around IP addresses
class IPAddress : public Printable {
private:
union {
uint8_t bytes[4]; // IPv4 address
uint32_t dword;
} _address;
// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
// be used when you know that the usage of the returned uint8_t* will be transient and not
// stored.
uint8_t* raw_address() { return _address.bytes; };
public:
// Constructors
IPAddress();
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint32_t address);
IPAddress(const uint8_t *address);
bool fromString(const char *address);
bool fromString(const String &address) { return fromString(address.c_str()); }
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected
operator uint32_t() const { return _address.dword; };
bool operator==(const IPAddress& addr) const { return _address.dword == addr._address.dword; };
bool operator!=(const IPAddress& addr) const { return _address.dword != addr._address.dword; };
bool operator==(const uint8_t* addr) const;
// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const { return _address.bytes[index]; };
uint8_t& operator[](int index) { return _address.bytes[index]; };
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address);
virtual size_t printTo(Print& p) const;
friend class UDP;
friend class Client;
friend class Server;
friend ::EthernetClass;
friend ::DhcpClass;
friend ::DNSClient;
};
extern const IPAddress INADDR_NONE;
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef W_INTERRUPTS_CPP
#define W_INTERRUPTS_CPP
#ifdef __cplusplus
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include "Common.h"
namespace arduino {
template <typename T>
using voidTemplateFuncPtrParam = void (*)(T param);
template<typename T> struct __container__ {
void* param;
voidTemplateFuncPtrParam<T> function;
};
// C++ only overloaded version of attachInterrupt function
template<typename T> void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam<T> userFunc, PinStatus mode, T& param) {
struct __container__<T> *cont = new __container__<T>();
cont->param = &param;
cont->function = userFunc;
// TODO: check lambda scope
// TODO: add structure to delete(__container__) when detachInterrupt() is called
auto f = [](void* a) -> void
{
T param = *(T*)((struct __container__<T>*)a)->param;
(((struct __container__<T>*)a)->function)(param);
};
attachInterruptParam(interruptNum, f, mode, cont);
}
template<typename T> void attachInterrupt(pin_size_t interruptNum, voidTemplateFuncPtrParam<T*> userFunc, PinStatus mode, T* param) {
attachInterruptParam(interruptNum, (voidFuncPtrParam)userFunc, mode, (void*)param);
}
}
#endif
#endif
+101
View File
@@ -0,0 +1,101 @@
/*
PluggableUSB.cpp
Copyright (c) 2015 Arduino LLC
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 "USBAPI.h"
#include "PluggableUSB.h"
using namespace arduino;
int PluggableUSB_::getInterface(uint8_t* interfaceCount)
{
int sent = 0;
PluggableUSBModule* node;
for (node = rootNode; node; node = node->next) {
int res = node->getInterface(interfaceCount);
if (res < 0)
return -1;
sent += res;
}
return sent;
}
int PluggableUSB_::getDescriptor(USBSetup& setup)
{
PluggableUSBModule* node;
for (node = rootNode; node; node = node->next) {
int ret = node->getDescriptor(setup);
// ret!=0 -> request has been processed
if (ret)
return ret;
}
return 0;
}
void PluggableUSB_::getShortName(char *iSerialNum)
{
PluggableUSBModule* node;
for (node = rootNode; node; node = node->next) {
iSerialNum += node->getShortName(iSerialNum);
}
*iSerialNum = 0;
}
bool PluggableUSB_::setup(USBSetup& setup)
{
PluggableUSBModule* node;
for (node = rootNode; node; node = node->next) {
if (node->setup(setup)) {
return true;
}
}
return false;
}
bool PluggableUSB_::plug(PluggableUSBModule *node)
{
if ((lastEp + node->numEndpoints) > totalEP) {
return false;
}
if (!rootNode) {
rootNode = node;
} else {
PluggableUSBModule *current = rootNode;
while (current->next) {
current = current->next;
}
current->next = node;
}
node->pluggedInterface = lastIf;
node->pluggedEndpoint = lastEp;
lastIf += node->numInterfaces;
for (uint8_t i = 0; i < node->numEndpoints; i++) {
*(unsigned int*)(epBuffer(lastEp)) = node->endpointType[i];
lastEp++;
}
return true;
// restart USB layer???
}
PluggableUSB_& PluggableUSB()
{
static PluggableUSB_ obj;
return obj;
}
+78
View File
@@ -0,0 +1,78 @@
/*
PluggableUSB.h
Copyright (c) 2015 Arduino LLC
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 PUSB_h
#define PUSB_h
#include "USBAPI.h"
#include <stdint.h>
#include <stddef.h>
namespace arduino {
class PluggableUSBModule {
public:
PluggableUSBModule(uint8_t numEps, uint8_t numIfs, unsigned int *epType) :
numEndpoints(numEps), numInterfaces(numIfs), endpointType(epType)
{ }
protected:
virtual bool setup(USBSetup& setup) = 0;
virtual int getInterface(uint8_t* interfaceCount) = 0;
virtual int getDescriptor(USBSetup& setup) = 0;
virtual uint8_t getShortName(char *name) { name[0] = 'A'+pluggedInterface; return 1; }
uint8_t pluggedInterface;
uint8_t pluggedEndpoint;
const uint8_t numEndpoints;
const uint8_t numInterfaces;
const unsigned int *endpointType;
PluggableUSBModule *next = NULL;
friend class PluggableUSB_;
};
class PluggableUSB_ {
public:
PluggableUSB_();
bool plug(PluggableUSBModule *node);
int getInterface(uint8_t* interfaceCount);
int getDescriptor(USBSetup& setup);
bool setup(USBSetup& setup);
void getShortName(char *iSerialNum);
private:
uint8_t lastIf;
uint8_t lastEp;
PluggableUSBModule* rootNode;
uint8_t totalEP;
};
}
// core need to define
void* epBuffer(unsigned int n); // -> returns a pointer to the Nth element of the EP buffer structure
// Replacement for global singleton.
// This function prevents static-initialization-order-fiasco
// https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use
arduino::PluggableUSB_& PluggableUSB();
#endif
+429
View File
@@ -0,0 +1,429 @@
/*
Copyright (c) 2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "Print.h"
using namespace arduino;
// Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--) {
if (write(*buffer++)) n++;
else break;
}
return n;
}
size_t Print::print(const __FlashStringHelper *ifsh)
{
#if defined(__AVR__)
PGM_P p = reinterpret_cast<PGM_P>(ifsh);
size_t n = 0;
while (1) {
unsigned char c = pgm_read_byte(p++);
if (c == 0) break;
if (write(c)) n++;
else break;
}
return n;
#else
return print(reinterpret_cast<const char *>(ifsh));
#endif
}
size_t Print::print(const String &s)
{
return write(s.c_str(), s.length());
}
size_t Print::print(const char str[])
{
return write(str);
}
size_t Print::print(char c)
{
return write(c);
}
size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}
size_t Print::print(int n, int base)
{
return print((long) n, base);
}
size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}
size_t Print::print(long n, int base)
{
if (base == 0) {
return write(n);
} else if (base == 10) {
if (n < 0) {
int t = print('-');
n = -n;
return printNumber(n, 10) + t;
}
return printNumber(n, 10);
} else {
return printNumber(n, base);
}
}
size_t Print::print(unsigned long n, int base)
{
if (base == 0) return write(n);
else return printNumber(n, base);
}
size_t Print::print(long long n, int base)
{
if (base == 0) {
return write(n);
} else if (base == 10) {
if (n < 0) {
int t = print('-');
n = -n;
return printULLNumber(n, 10) + t;
}
return printULLNumber(n, 10);
} else {
return printULLNumber(n, base);
}
}
size_t Print::print(unsigned long long n, int base)
{
if (base == 0) return write(n);
else return printULLNumber(n, base);
}
size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
}
size_t Print::println(const __FlashStringHelper *ifsh)
{
size_t n = print(ifsh);
n += println();
return n;
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void)
{
return write("\r\n");
}
size_t Print::println(const String &s)
{
size_t n = print(s);
n += println();
return n;
}
size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}
size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(long long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned long long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}
size_t Print::printf(const char *format, ...) {
va_list arg;
va_start(arg, format);
char temp[64];
char* buffer = temp;
size_t len = vsnprintf(temp, sizeof(temp), format, arg);
va_end(arg);
if (len > sizeof(temp) - 1) {
buffer = new char[len + 1];
if (!buffer) {
return 0;
}
va_start(arg, format);
vsnprintf(buffer, len + 1, format, arg);
va_end(arg);
}
len = write((const uint8_t*) buffer, len);
if (buffer != temp) {
delete[] buffer;
}
return len;
}
// TODO - must be better way than cut-n-paste!
size_t Print::printf_P(const char *format, ...) {
va_list arg;
va_start(arg, format);
char temp[64];
char* buffer = temp;
size_t len = vsnprintf(temp, sizeof(temp), format, arg);
va_end(arg);
if (len > sizeof(temp) - 1) {
buffer = new char[len + 1];
if (!buffer) {
return 0;
}
va_start(arg, format);
vsnprintf(buffer, len + 1, format, arg);
va_end(arg);
}
len = write((const uint8_t*) buffer, len);
if (buffer != temp) {
delete[] buffer;
}
return len;
}
// Private Methods /////////////////////////////////////////////////////////////
size_t Print::printNumber(unsigned long n, uint8_t base)
{
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1];
*str = '\0';
// prevent crash if called with base == 1
if (base < 2) base = 10;
do {
char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n);
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, int digits)
{
if (digits < 0)
digits = 2;
size_t n = 0;
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
n += print(".");
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)remainder;
n += print(toPrint);
remainder -= toPrint;
}
return n;
}
+100
View File
@@ -0,0 +1,100 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <inttypes.h>
#include <stdio.h> // for size_t
#include "String.h"
#include "Printable.h"
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
namespace arduino {
class Print
{
private:
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, int);
protected:
void setWriteError(int err = 1) { write_error = err; }
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
virtual size_t write(uint8_t) = 0;
size_t write(const char *str) {
if (str == NULL) return 0;
return write((const uint8_t *)str, strlen(str));
}
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block"
// should be overriden by subclasses with buffering
virtual int availableForWrite() { return 0; }
size_t print(const __FlashStringHelper *);
size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(long long, int = DEC);
size_t print(unsigned long long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
size_t println(const __FlashStringHelper *);
size_t println(const String &s);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
// EFP3 - Add printf() to make life so much easier...
size_t printf(const char *format, ...);
size_t printf_P(const char *format, ...);
virtual void flush() { /* Empty implementation for backward compatibility */ }
};
}
using namespace arduino;
+39
View File
@@ -0,0 +1,39 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <stdlib.h>
namespace arduino {
class Print;
/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};
}
+141
View File
@@ -0,0 +1,141 @@
/*
Copyright (c) 2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef __cplusplus
#ifndef _RING_BUFFER_
#define _RING_BUFFER_
#include <stdint.h>
#include <string.h>
namespace arduino {
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which head is the index of the location
// to which to write the next incoming character and tail is the index of the
// location from which to read.
#define SERIAL_BUFFER_SIZE 64
template <int N>
class RingBufferN
{
public:
uint8_t _aucBuffer[N] ;
volatile int _iHead ;
volatile int _iTail ;
volatile int _numElems;
public:
RingBufferN( void ) ;
void store_char( uint8_t c ) ;
void clear();
int read_char();
int available();
int availableForStore();
int peek();
bool isFull();
private:
int nextIndex(int index);
inline bool isEmpty() const { return (_numElems == 0); }
};
typedef RingBufferN<SERIAL_BUFFER_SIZE> RingBuffer;
template <int N>
RingBufferN<N>::RingBufferN( void )
{
memset( _aucBuffer, 0, N ) ;
clear();
}
template <int N>
void RingBufferN<N>::store_char( uint8_t c )
{
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (!isFull())
{
_aucBuffer[_iHead] = c ;
_iHead = nextIndex(_iHead);
_numElems++;
}
}
template <int N>
void RingBufferN<N>::clear()
{
_iHead = 0;
_iTail = 0;
_numElems = 0;
}
template <int N>
int RingBufferN<N>::read_char()
{
if (isEmpty())
return -1;
uint8_t value = _aucBuffer[_iTail];
_iTail = nextIndex(_iTail);
_numElems--;
return value;
}
template <int N>
int RingBufferN<N>::available()
{
return _numElems;
}
template <int N>
int RingBufferN<N>::availableForStore()
{
return (N - _numElems);
}
template <int N>
int RingBufferN<N>::peek()
{
if (isEmpty())
return -1;
return _aucBuffer[_iTail];
}
template <int N>
int RingBufferN<N>::nextIndex(int index)
{
return (uint32_t)(index + 1) % N;
}
template <int N>
bool RingBufferN<N>::isFull()
{
return (_numElems == N);
}
}
#endif /* _RING_BUFFER_ */
#endif /* __cplusplus */
+31
View File
@@ -0,0 +1,31 @@
/*
Server.h - Base class that provides Server
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "Print.h"
namespace arduino {
class Server : public Print {
public:
virtual void begin() = 0;
};
}
+321
View File
@@ -0,0 +1,321 @@
/*
Stream.cpp - adds parsing methods to Stream class
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Created July 2011
parsing functions based on TextFinder library by Michael Margolis
findMulti/findUntil routines written by Jim Leonard/Xuth
*/
#include "Common.h"
#include "Stream.h"
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
using namespace arduino;
// private method to read stream with timeout
int Stream::timedRead()
{
int c;
_startMillis = millis();
do {
c = read();
if (c >= 0) return c;
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// private method to peek stream with timeout
int Stream::timedPeek()
{
int c;
_startMillis = millis();
do {
c = peek();
if (c >= 0) return c;
} while(millis() - _startMillis < _timeout);
return -1; // -1 indicates timeout
}
// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit(LookaheadMode lookahead, bool detectDecimal)
{
int c;
while (1) {
c = timedPeek();
if( c < 0 ||
c == '-' ||
(c >= '0' && c <= '9') ||
(detectDecimal && c == '.')) return c;
switch( lookahead ){
case SKIP_NONE: return -1; // Fail code.
case SKIP_WHITESPACE:
switch( c ){
case ' ':
case '\t':
case '\r':
case '\n': break;
default: return -1; // Fail code.
}
case SKIP_ALL:
break;
}
read(); // discard non-numeric
}
}
// Public Methods
//////////////////////////////////////////////////////////////
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{
_timeout = timeout;
}
// find returns true if the target string is found
bool Stream::find(const char *target)
{
return findUntil(target, strlen(target), NULL, 0);
}
// reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool Stream::find(const char *target, size_t length)
{
return findUntil(target, length, NULL, 0);
}
// as find but search ends if the terminator string is found
bool Stream::findUntil(const char *target, const char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}
// reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(const char *target, size_t targetLen, const char *terminator, size_t termLen)
{
if (terminator == NULL) {
MultiTarget t[1] = {{target, targetLen, 0}};
return findMulti(t, 1) == 0;
} else {
MultiTarget t[2] = {{target, targetLen, 0}, {terminator, termLen, 0}};
return findMulti(t, 2) == 0;
}
}
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
long Stream::parseInt(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
long value = 0;
int c;
c = peekNextDigit(lookahead, false);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if((char)c == ignore)
; // ignore this character
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || (char)c == ignore );
if(isNegative)
value = -value;
return value;
}
// as parseInt but returns a floating point value
float Stream::parseFloat(LookaheadMode lookahead, char ignore)
{
bool isNegative = false;
bool isFraction = false;
double value = 0.0;
int c;
double fraction = 1.0;
c = peekNextDigit(lookahead, true);
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout
do{
if((char)c == ignore)
; // ignore
else if(c == '-')
isNegative = true;
else if (c == '.')
isFraction = true;
else if(c >= '0' && c <= '9') { // is c a digit?
if(isFraction) {
fraction *= 0.1;
value = value + fraction * (c - '0');
} else {
value = value * 10 + c - '0';
}
}
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || (c == '.' && !isFraction) || (char)c == ignore );
if(isNegative)
value = -value;
return value;
}
// read characters from stream into buffer
// terminates if length characters have been read, or timeout (see setTimeout)
// returns the number of characters placed in the buffer
// the buffer is NOT null terminated.
//
size_t Stream::readBytes(char *buffer, size_t length)
{
size_t count = 0;
while (count < length) {
int c = timedRead();
if (c < 0) break;
*buffer++ = (char)c;
count++;
}
return count;
}
// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{
size_t index = 0;
while (index < length) {
int c = timedRead();
if (c < 0 || (char)c == terminator) break;
*buffer++ = (char)c;
index++;
}
return index; // return number of characters, not including null terminator
}
String Stream::readString()
{
String ret;
int c = timedRead();
while (c >= 0)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
String Stream::readStringUntil(char terminator)
{
String ret;
int c = timedRead();
while (c >= 0 && (char)c != terminator)
{
ret += (char)c;
c = timedRead();
}
return ret;
}
int Stream::findMulti( struct Stream::MultiTarget *targets, int tCount) {
// any zero length target string automatically matches and would make
// a mess of the rest of the algorithm.
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
if (t->len <= 0)
return t - targets;
}
while (1) {
int c = timedRead();
if (c < 0)
return -1;
for (struct MultiTarget *t = targets; t < targets+tCount; ++t) {
// the simple case is if we match, deal with that first.
if ((char)c == t->str[t->index]) {
if (++t->index == t->len)
return t - targets;
else
continue;
}
// if not we need to walk back and see if we could have matched further
// down the stream (ie '1112' doesn't match the first position in '11112'
// but it will match the second position so we can't just reset the current
// index to 0 when we find a mismatch.
if (t->index == 0)
continue;
int origIndex = t->index;
do {
--t->index;
// first check if current char works against the new current index
if ((char)c != t->str[t->index])
continue;
// if it's the only char then we're good, nothing more to check
if (t->index == 0) {
t->index++;
break;
}
// otherwise we need to check the rest of the found string
int diff = origIndex - t->index;
size_t i;
for (i = 0; i < t->index; ++i) {
if (t->str[i] != t->str[i + diff])
break;
}
// if we successfully got through the previous loop then our current
// index is good.
if (i == t->index) {
t->index++;
break;
}
// otherwise we just try the next index
} while (t->index);
}
}
// unreachable
return -1;
}
+131
View File
@@ -0,0 +1,131 @@
/*
Stream.h - base class for character-based streams.
Copyright (c) 2010 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
parsing functions based on TextFinder library by Michael Margolis
*/
#pragma once
#include <inttypes.h>
#include "Print.h"
// compatability macros for testing
/*
#define getInt() parseInt()
#define getInt(ignore) parseInt(ignore)
#define getFloat() parseFloat()
#define getFloat(ignore) parseFloat(ignore)
#define getString( pre_string, post_string, buffer, length)
readBytesBetween( pre_string, terminator, buffer, length)
*/
namespace arduino {
// This enumeration provides the lookahead options for parseInt(), parseFloat()
// The rules set out here are used until either the first valid character is found
// or a time out occurs due to lack of input.
enum LookaheadMode{
SKIP_ALL, // All invalid characters are ignored.
SKIP_NONE, // Nothing is skipped, and the stream is not touched unless the first waiting character is valid.
SKIP_WHITESPACE // Only tabs, spaces, line feeds & carriage returns are skipped.
};
#define NO_IGNORE_CHAR '\x01' // a char not found in a valid ASCII numeric field
class Stream : public Print
{
protected:
unsigned long _timeout; // number of milliseconds to wait for the next char before aborting timed read
unsigned long _startMillis; // used for timeout measurement
int timedRead(); // private method to read stream with timeout
int timedPeek(); // private method to peek stream with timeout
int peekNextDigit(LookaheadMode lookahead, bool detectDecimal); // returns the next numeric digit in the stream or -1 if timeout
public:
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
Stream() {_timeout=1000;}
// parsing methods
void setTimeout(unsigned long timeout); // sets maximum milliseconds to wait for stream data, default is 1 second
unsigned long getTimeout(void) { return _timeout; }
bool find(const char *target); // reads data from the stream until the target string is found
bool find(const uint8_t *target) { return find ((const char *)target); }
// returns true if target string is found, false if timed out (see setTimeout)
bool find(const char *target, size_t length); // reads data from the stream until the target string of given length is found
bool find(const uint8_t *target, size_t length) { return find ((const char *)target, length); }
// returns true if target string is found, false if timed out
bool find(char target) { return find (&target, 1); }
bool findUntil(const char *target, const char *terminator); // as find but search ends if the terminator string is found
bool findUntil(const uint8_t *target, const char *terminator) { return findUntil((const char *)target, terminator); }
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen); // as above but search ends if the terminate string is found
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen) {return findUntil((const char *)target, targetLen, terminate, termLen); }
long parseInt(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// returns the first valid (long) integer value from the current position.
// lookahead determines how parseInt looks ahead in the stream.
// See LookaheadMode enumeration at the top of the file.
// Lookahead is terminated by the first character that is not a valid part of an integer.
// Once parsing commences, 'ignore' will be skipped in the stream.
float parseFloat(LookaheadMode lookahead = SKIP_ALL, char ignore = NO_IGNORE_CHAR);
// float version of parseInt
size_t readBytes( char *buffer, size_t length); // read chars from stream into buffer
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
// terminates if length characters have been read or timeout (see setTimeout)
// returns the number of characters placed in the buffer (0 means no valid data found)
size_t readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
size_t readBytesUntil( char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, length); }
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)
// Arduino String functions to be added here
String readString();
String readStringUntil(char terminator);
protected:
long parseInt(char ignore) { return parseInt(SKIP_ALL, ignore); }
float parseFloat(char ignore) { return parseFloat(SKIP_ALL, ignore); }
// These overload exists for compatibility with any class that has derived
// Stream and used parseFloat/Int with a custom ignore character. To keep
// the public API simple, these overload remains protected.
struct MultiTarget {
const char *str; // string you're searching for
size_t len; // length of string you're searching for
size_t index; // index used by the search routine.
};
// This allows you to search for an arbitrary number of strings.
// Returns index of the target that is found first or -1 if timeout occurs.
int findMulti(struct MultiTarget *targets, int tCount);
};
#undef NO_IGNORE_CHAR
}
+768
View File
@@ -0,0 +1,768 @@
/*
String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 "String.h"
#include "Common.h"
#include "itoa.h"
#include "deprecated-avr-comp/avr/dtostrf.h"
#include <float.h>
namespace arduino {
/*********************************************/
/* Static Member Initialisation */
/*********************************************/
size_t const String::FLT_MAX_DECIMAL_PLACES;
size_t const String::DBL_MAX_DECIMAL_PLACES;
/*********************************************/
/* Constructors */
/*********************************************/
String::String(const char *cstr)
{
init();
if (cstr) copy(cstr, strlen(cstr));
}
String::String(const char *cstr, unsigned int length)
{
init();
if (cstr) copy(cstr, length);
}
String::String(const String &value)
{
init();
*this = value;
}
String::String(const __FlashStringHelper *pstr)
{
init();
*this = pstr;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String::String(String &&rval)
{
init();
move(rval);
}
String::String(StringSumHelper &&rval)
{
init();
move(rval);
}
#endif
String::String(char c)
{
init();
char buf[2];
buf[0] = c;
buf[1] = 0;
*this = buf;
}
String::String(unsigned char value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned char)];
utoa(value, buf, base);
*this = buf;
}
String::String(int value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(int)];
itoa(value, buf, base);
*this = buf;
}
String::String(unsigned int value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned int)];
utoa(value, buf, base);
*this = buf;
}
String::String(long value, unsigned char base)
{
init();
char buf[2 + 8 * sizeof(long)];
ltoa(value, buf, base);
*this = buf;
}
String::String(unsigned long value, unsigned char base)
{
init();
char buf[1 + 8 * sizeof(unsigned long)];
ultoa(value, buf, base);
*this = buf;
}
String::String(float value, unsigned char decimalPlaces)
{
static size_t const FLOAT_BUF_SIZE = FLT_MAX_10_EXP + FLT_MAX_DECIMAL_PLACES + 1 /* '-' */ + 1 /* '.' */ + 1 /* '\0' */;
init();
char buf[FLOAT_BUF_SIZE];
decimalPlaces = min(decimalPlaces, FLT_MAX_DECIMAL_PLACES);
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::String(double value, unsigned char decimalPlaces)
{
static size_t const DOUBLE_BUF_SIZE = DBL_MAX_10_EXP + DBL_MAX_DECIMAL_PLACES + 1 /* '-' */ + 1 /* '.' */ + 1 /* '\0' */;
init();
char buf[DOUBLE_BUF_SIZE];
decimalPlaces = min(decimalPlaces, DBL_MAX_DECIMAL_PLACES);
*this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
}
String::~String()
{
if (buffer) free(buffer);
}
/*********************************************/
/* Memory Management */
/*********************************************/
inline void String::init(void)
{
buffer = NULL;
capacity = 0;
len = 0;
}
void String::invalidate(void)
{
if (buffer) free(buffer);
buffer = NULL;
capacity = len = 0;
}
unsigned char String::reserve(unsigned int size)
{
if (buffer && capacity >= size) return 1;
if (changeBuffer(size)) {
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
}
unsigned char String::changeBuffer(unsigned int maxStrLen)
{
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
if (newbuffer) {
buffer = newbuffer;
capacity = maxStrLen;
return 1;
}
return 0;
}
/*********************************************/
/* Copy and Move */
/*********************************************/
String & String::copy(const char *cstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
memcpy(buffer, cstr, length);
buffer[len] = '\0';
return *this;
}
String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
{
if (!reserve(length)) {
invalidate();
return *this;
}
len = length;
strcpy_P(buffer, (PGM_P)pstr);
return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void String::move(String &rhs)
{
if (buffer) {
if (rhs && capacity >= rhs.len) {
memcpy(buffer, rhs.buffer, rhs.len);
len = rhs.len;
buffer[len] = '\0';
rhs.len = 0;
return;
} else {
free(buffer);
}
}
buffer = rhs.buffer;
capacity = rhs.capacity;
len = rhs.len;
rhs.buffer = NULL;
rhs.capacity = 0;
rhs.len = 0;
}
#endif
String & String::operator = (const String &rhs)
{
if (this == &rhs) return *this;
if (rhs.buffer) copy(rhs.buffer, rhs.len);
else invalidate();
return *this;
}
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String & String::operator = (String &&rval)
{
if (this != &rval) move(rval);
return *this;
}
String & String::operator = (StringSumHelper &&rval)
{
if (this != &rval) move(rval);
return *this;
}
#endif
String & String::operator = (const char *cstr)
{
if (cstr) copy(cstr, strlen(cstr));
else invalidate();
return *this;
}
String & String::operator = (const __FlashStringHelper *pstr)
{
if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
else invalidate();
return *this;
}
/*********************************************/
/* concat */
/*********************************************/
unsigned char String::concat(const String &s)
{
return concat(s.buffer, s.len);
}
unsigned char String::concat(const char *cstr, unsigned int length)
{
unsigned int newlen = len + length;
if (!cstr) return 0;
if (length == 0) return 1;
if (!reserve(newlen)) return 0;
memcpy(buffer + len, cstr, length);
len = newlen;
buffer[len] = '\0';
return 1;
}
unsigned char String::concat(const char *cstr)
{
if (!cstr) return 0;
return concat(cstr, strlen(cstr));
}
unsigned char String::concat(char c)
{
return concat(&c, 1);
}
unsigned char String::concat(unsigned char num)
{
char buf[1 + 3 * sizeof(unsigned char)];
itoa(num, buf, 10);
return concat(buf);
}
unsigned char String::concat(int num)
{
char buf[2 + 3 * sizeof(int)];
itoa(num, buf, 10);
return concat(buf);
}
unsigned char String::concat(unsigned int num)
{
char buf[1 + 3 * sizeof(unsigned int)];
utoa(num, buf, 10);
return concat(buf);
}
unsigned char String::concat(long num)
{
char buf[2 + 3 * sizeof(long)];
ltoa(num, buf, 10);
return concat(buf);
}
unsigned char String::concat(unsigned long num)
{
char buf[1 + 3 * sizeof(unsigned long)];
ultoa(num, buf, 10);
return concat(buf);
}
unsigned char String::concat(float num)
{
char buf[20];
char* string = dtostrf(num, 4, 2, buf);
return concat(string);
}
unsigned char String::concat(double num)
{
char buf[20];
char* string = dtostrf(num, 4, 2, buf);
return concat(string);
}
unsigned char String::concat(const __FlashStringHelper * str)
{
if (!str) return 0;
int length = strlen_P((const char *) str);
if (length == 0) return 1;
unsigned int newlen = len + length;
if (!reserve(newlen)) return 0;
strcpy_P(buffer + len, (const char *) str);
len = newlen;
return 1;
}
/*********************************************/
/* Concatenate */
/*********************************************/
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!cstr || !a.concat(cstr)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(c)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(num)) a.invalidate();
return a;
}
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (!a.concat(rhs)) a.invalidate();
return a;
}
/*********************************************/
/* Comparison */
/*********************************************/
int String::compareTo(const String &s) const
{
if (!buffer || !s.buffer) {
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, s.buffer);
}
int String::compareTo(const char *cstr) const
{
if (!buffer || !cstr) {
if (cstr && *cstr) return 0 - *(unsigned char *)cstr;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, cstr);
}
unsigned char String::equals(const String &s2) const
{
return (len == s2.len && compareTo(s2) == 0);
}
unsigned char String::equals(const char *cstr) const
{
if (len == 0) return (cstr == NULL || *cstr == 0);
if (cstr == NULL) return buffer[0] == 0;
return strcmp(buffer, cstr) == 0;
}
unsigned char String::equalsIgnoreCase( const String &s2 ) const
{
if (this == &s2) return 1;
if (len != s2.len) return 0;
if (len == 0) return 1;
const char *p1 = buffer;
const char *p2 = s2.buffer;
while (*p1) {
if (tolower(*p1++) != tolower(*p2++)) return 0;
}
return 1;
}
unsigned char String::startsWith( const String &s2 ) const
{
if (len < s2.len) return 0;
return startsWith(s2, 0);
}
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
{
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
}
unsigned char String::endsWith( const String &s2 ) const
{
if ( len < s2.len || !buffer || !s2.buffer) return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}
/*********************************************/
/* Character Access */
/*********************************************/
char String::charAt(unsigned int loc) const
{
return operator[](loc);
}
void String::setCharAt(unsigned int loc, char c)
{
if (loc < len) buffer[loc] = c;
}
char & String::operator[](unsigned int index)
{
static char dummy_writable_char;
if (index >= len || !buffer) {
dummy_writable_char = 0;
return dummy_writable_char;
}
return buffer[index];
}
char String::operator[]( unsigned int index ) const
{
if (index >= len || !buffer) return 0;
return buffer[index];
}
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{
if (!bufsize || !buf) return;
if (index >= len) {
buf[0] = 0;
return;
}
unsigned int n = bufsize - 1;
if (n > len - index) n = len - index;
strncpy((char *)buf, buffer + index, n);
buf[n] = 0;
}
/*********************************************/
/* Search */
/*********************************************/
int String::indexOf(char c) const
{
return indexOf(c, 0);
}
int String::indexOf( char ch, unsigned int fromIndex ) const
{
if (fromIndex >= len) return -1;
const char* temp = strchr(buffer + fromIndex, ch);
if (temp == NULL) return -1;
return temp - buffer;
}
int String::indexOf(const String &s2) const
{
return indexOf(s2, 0);
}
int String::indexOf(const String &s2, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
const char *found = strstr(buffer + fromIndex, s2.buffer);
if (found == NULL) return -1;
return found - buffer;
}
int String::lastIndexOf( char theChar ) const
{
return lastIndexOf(theChar, len - 1);
}
int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
if (fromIndex >= len) return -1;
char tempchar = buffer[fromIndex + 1];
buffer[fromIndex + 1] = '\0';
char* temp = strrchr( buffer, ch );
buffer[fromIndex + 1] = tempchar;
if (temp == NULL) return -1;
return temp - buffer;
}
int String::lastIndexOf(const String &s2) const
{
return lastIndexOf(s2, len - s2.len);
}
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
{
if (s2.len == 0 || len == 0 || s2.len > len) return -1;
if (fromIndex >= len) fromIndex = len - 1;
int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++) {
p = strstr(p, s2.buffer);
if (!p) break;
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
}
return found;
}
String String::substring(unsigned int left, unsigned int right) const
{
if (left > right) {
unsigned int temp = right;
right = left;
left = temp;
}
String out;
if (left >= len) return out;
if (right > len) right = len;
out.copy(buffer + left, right - left);
return out;
}
/*********************************************/
/* Modification */
/*********************************************/
void String::replace(char find, char replace)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
if (*p == find) *p = replace;
}
}
void String::replace(const String& find, const String& replace)
{
if (len == 0 || find.len == 0) return;
int diff = replace.len - find.len;
char *readFrom = buffer;
char *foundAt;
if (diff == 0) {
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
memcpy(foundAt, replace.buffer, replace.len);
readFrom = foundAt + replace.len;
}
} else if (diff < 0) {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
readFrom = foundAt + find.len;
diff = 0 - diff;
size -= diff;
}
if (size == len) return;
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom - diff, readFrom, len - (readFrom - buffer));
len -= diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
} else {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
readFrom = foundAt + find.len;
size += diff;
}
if (size == len) return;
if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
len += diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
}
}
void String::remove(unsigned int index){
// Pass the biggest integer as the count. The remove method
// below will take care of truncating it at the end of the
// string.
remove(index, (unsigned int)-1);
}
void String::remove(unsigned int index, unsigned int count){
if (index >= len) { return; }
if (count <= 0) { return; }
if (count > len - index) { count = len - index; }
char *writeTo = buffer + index;
len = len - count;
memmove(writeTo, buffer + index + count,len - index);
buffer[len] = 0;
}
void String::toLowerCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
*p = tolower(*p);
}
}
void String::toUpperCase(void)
{
if (!buffer) return;
for (char *p = buffer; *p; p++) {
*p = toupper(*p);
}
}
void String::trim(void)
{
if (!buffer || len == 0) return;
char *begin = buffer;
while (isspace(*begin)) begin++;
char *end = buffer + len - 1;
while (isspace(*end) && end >= begin) end--;
len = end + 1 - begin;
if (begin > buffer) memmove(buffer, begin, len);
buffer[len] = 0;
}
/*********************************************/
/* Parsing / Conversion */
/*********************************************/
long String::toInt(void) const
{
if (buffer) return atol(buffer);
return 0;
}
float String::toFloat(void) const
{
return float(toDouble());
}
double String::toDouble(void) const
{
if (buffer) return atof(buffer);
return 0;
}
} // namespace arduino
+259
View File
@@ -0,0 +1,259 @@
/*
String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef __cplusplus
#ifndef __ARDUINO_STRINGS__
#define __ARDUINO_STRINGS__
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#if defined(__AVR__)
#include "avr/pgmspace.h"
#else
#include "deprecated-avr-comp/avr/pgmspace.h"
#endif
namespace arduino {
// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
// with little or no increase in code size.
// -felide-constructors
// -std=c++0x
class __FlashStringHelper;
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;
// The string class
class String
{
friend class StringSumHelper;
// use a function pointer to allow for "if (s)" without the
// complications of an operator bool(). for more information, see:
// http://www.artima.com/cppsource/safebool.html
typedef void (String::*StringIfHelperType)() const;
void StringIfHelper() const {}
static size_t const FLT_MAX_DECIMAL_PLACES = 10;
static size_t const DBL_MAX_DECIMAL_PLACES = FLT_MAX_DECIMAL_PLACES;
public:
// constructors
// creates a copy of the initial value.
// if the initial value is null or invalid, or if memory allocation
// fails, the string will be marked as invalid (i.e. "if (s)" will
// be false).
String(const char *cstr = "");
String(const char *cstr, unsigned int length);
String(const uint8_t *cstr, unsigned int length) : String((const char*)cstr, length) {}
String(const String &str);
String(const __FlashStringHelper *str);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String(String &&rval);
String(StringSumHelper &&rval);
#endif
explicit String(char c);
explicit String(unsigned char, unsigned char base=10);
explicit String(int, unsigned char base=10);
explicit String(unsigned int, unsigned char base=10);
explicit String(long, unsigned char base=10);
explicit String(unsigned long, unsigned char base=10);
explicit String(float, unsigned char decimalPlaces=2);
explicit String(double, unsigned char decimalPlaces=2);
~String(void);
// memory management
// return true on success, false on failure (in which case, the string
// is left unchanged). reserve(0), if successful, will validate an
// invalid string (i.e., "if (s)" will be true afterwards)
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const {return len;}
// creates a copy of the assigned value. if the value is null or
// invalid, or if the memory allocation fails, the string will be
// marked as invalid ("if (s)" will be false).
String & operator = (const String &rhs);
String & operator = (const char *cstr);
String & operator = (const __FlashStringHelper *str);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
#endif
// concatenate (works w/ built-in types)
// returns true on success, false on failure (in which case, the string
// is left unchanged). if the argument is null or invalid, the
// concatenation is considered unsucessful.
unsigned char concat(const String &str);
unsigned char concat(const char *cstr);
unsigned char concat(const char *cstr, unsigned int length);
unsigned char concat(const uint8_t *cstr, unsigned int length) {return concat((const char*)cstr, length);}
unsigned char concat(char c);
unsigned char concat(unsigned char num);
unsigned char concat(int num);
unsigned char concat(unsigned int num);
unsigned char concat(long num);
unsigned char concat(unsigned long num);
unsigned char concat(float num);
unsigned char concat(double num);
unsigned char concat(const __FlashStringHelper * str);
// if there's not enough memory for the concatenated value, the string
// will be left unchanged (but this isn't signalled in any way)
String & operator += (const String &rhs) {concat(rhs); return (*this);}
String & operator += (const char *cstr) {concat(cstr); return (*this);}
String & operator += (char c) {concat(c); return (*this);}
String & operator += (unsigned char num) {concat(num); return (*this);}
String & operator += (int num) {concat(num); return (*this);}
String & operator += (unsigned int num) {concat(num); return (*this);}
String & operator += (long num) {concat(num); return (*this);}
String & operator += (unsigned long num) {concat(num); return (*this);}
String & operator += (float num) {concat(num); return (*this);}
String & operator += (double num) {concat(num); return (*this);}
String & operator += (const __FlashStringHelper *str){concat(str); return (*this);}
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs);
// comparison (only works w/ Strings and "strings")
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
int compareTo(const String &s) const;
int compareTo(const char *cstr) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
friend unsigned char operator == (const String &a, const String &b) { return a.equals(b); }
friend unsigned char operator == (const String &a, const char *b) { return a.equals(b); }
friend unsigned char operator == (const char *a, const String &b) { return b == a; }
friend unsigned char operator < (const String &a, const String &b) { return a.compareTo(b) < 0; }
friend unsigned char operator < (const String &a, const char *b) { return a.compareTo(b) < 0; }
friend unsigned char operator < (const char *a, const String &b) { return b.compareTo(a) > 0; }
friend unsigned char operator != (const String &a, const String &b) { return !(a == b); }
friend unsigned char operator != (const String &a, const char *b) { return !(a == b); }
friend unsigned char operator != (const char *a, const String &b) { return !(a == b); }
friend unsigned char operator > (const String &a, const String &b) { return b < a; }
friend unsigned char operator > (const String &a, const char *b) { return b < a; }
friend unsigned char operator > (const char *a, const String &b) { return b < a; }
friend unsigned char operator <= (const String &a, const String &b) { return !(b < a); }
friend unsigned char operator <= (const String &a, const char *b) { return !(b < a); }
friend unsigned char operator <= (const char *a, const String &b) { return !(b < a); }
friend unsigned char operator >= (const String &a, const String &b) { return !(a < b); }
friend unsigned char operator >= (const String &a, const char *b) { return !(a < b); }
friend unsigned char operator >= (const char *a, const String &b) { return !(a < b); }
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char startsWith( const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;
// character acccess
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [] (unsigned int index) const;
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{ getBytes((unsigned char *)buf, bufsize, index); }
const char* c_str() const { return buffer; }
char* begin() { return buffer; }
char* end() { return buffer + length(); }
const char* begin() const { return c_str(); }
const char* end() const { return c_str() + length(); }
// search
int indexOf( char ch ) const;
int indexOf( char ch, unsigned int fromIndex ) const;
int indexOf( const String &str ) const;
int indexOf( const String &str, unsigned int fromIndex ) const;
int lastIndexOf( char ch ) const;
int lastIndexOf( char ch, unsigned int fromIndex ) const;
int lastIndexOf( const String &str ) const;
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
String substring( unsigned int beginIndex ) const { return substring(beginIndex, len); };
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
// modification
void replace(char find, char replace);
void replace(const String& find, const String& replace);
void remove(unsigned int index);
void remove(unsigned int index, unsigned int count);
void toLowerCase(void);
void toUpperCase(void);
void trim(void);
// parsing/conversion
long toInt(void) const;
float toFloat(void) const;
double toDouble(void) const;
protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
protected:
void init(void);
void invalidate(void);
unsigned char changeBuffer(unsigned int maxStrLen);
// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pstr, unsigned int length);
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
void move(String &rhs);
#endif
};
class StringSumHelper : public String
{
public:
StringSumHelper(const String &s) : String(s) {}
StringSumHelper(const char *p) : String(p) {}
StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char num) : String(num) {}
StringSumHelper(int num) : String(num) {}
StringSumHelper(unsigned int num) : String(num) {}
StringSumHelper(long num) : String(num) {}
StringSumHelper(unsigned long num) : String(num) {}
StringSumHelper(float num) : String(num) {}
StringSumHelper(double num) : String(num) {}
};
} // namespace arduino
#endif // __cplusplus
#endif // __ARDUINO_STRINGS__
+64
View File
@@ -0,0 +1,64 @@
/*
USBAPI.h
Copyright (c) 2005-2014 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __USBAPI__
#define __USBAPI__
#include <stdint.h>
namespace arduino {
//================================================================================
//================================================================================
// Low level API
typedef struct __attribute__((packed))
{
union {
uint8_t bmRequestType;
struct {
uint8_t direction : 5;
uint8_t type : 2;
uint8_t transferDirection : 1;
};
};
uint8_t bRequest;
uint8_t wValueL;
uint8_t wValueH;
uint16_t wIndex;
uint16_t wLength;
} USBSetup;
}
//================================================================================
// USB APIs (C scope)
//================================================================================
int USB_SendControl(uint8_t flags, const void* d, int len);
int USB_RecvControl(void* d, int len);
int USB_RecvControlLong(void* d, int len);
uint8_t USB_Available(uint8_t ep);
uint8_t USB_SendSpace(uint8_t ep);
int USB_Send(uint8_t ep, const void* data, int len); // blocking
int USB_Recv(uint8_t ep, void* data, int len); // non-blocking
int USB_Recv(uint8_t ep); // non-blocking
void USB_Flush(uint8_t ep);
#endif
+92
View File
@@ -0,0 +1,92 @@
/*
* Udp.cpp: Library to send/receive UDP packets.
*
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
* might not happen often in practice, but in larger network topologies, a UDP
* packet can be received out of sequence.
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
* aware of it. Again, this may not be a concern in practice on small local networks.
* For more information, see http://www.cafeaulait.org/course/week12/35.html
*
* MIT License:
* Copyright (c) 2008 Bjoern Hartmann
* 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.
*
* bjoern@cs.stanford.edu 12/30/2008
*/
#pragma once
#include "Stream.h"
#include "IPAddress.h"
namespace arduino {
class UDP : public Stream {
public:
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual uint8_t beginMulticast(IPAddress, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure
virtual void stop() =0; // Finish with the UDP socket
// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port) =0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket() =0;
// Write a single byte into the packet
virtual size_t write(uint8_t) =0;
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size) =0;
// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket() =0;
// Number of bytes remaining in the current packet
virtual int available() =0;
// Read a single byte from the current packet
virtual int read() =0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len) =0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) =0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() =0;
virtual void flush() =0; // Finish reading the current packet
// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() =0;
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort() =0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};
}
using namespace arduino;
+171
View File
@@ -0,0 +1,171 @@
/*
WCharacter.h - Character utility functions for Wiring & Arduino
Copyright (c) 2010 Hernando Barragan. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 Character_h
#define Character_h
#include <ctype.h>
namespace arduino {
// WCharacter.h prototypes
inline bool isAlphaNumeric(int c) __attribute__((always_inline));
inline bool isAlpha(int c) __attribute__((always_inline));
inline bool isAscii(int c) __attribute__((always_inline));
inline bool isWhitespace(int c) __attribute__((always_inline));
inline bool isControl(int c) __attribute__((always_inline));
inline bool isDigit(int c) __attribute__((always_inline));
inline bool isGraph(int c) __attribute__((always_inline));
inline bool isLowerCase(int c) __attribute__((always_inline));
inline bool isPrintable(int c) __attribute__((always_inline));
inline bool isPunct(int c) __attribute__((always_inline));
inline bool isSpace(int c) __attribute__((always_inline));
inline bool isUpperCase(int c) __attribute__((always_inline));
inline bool isHexadecimalDigit(int c) __attribute__((always_inline));
inline int toAscii(int c) __attribute__((always_inline));
inline int toLowerCase(int c) __attribute__((always_inline));
inline int toUpperCase(int c)__attribute__((always_inline));
// Checks for an alphanumeric character.
// It is equivalent to (isalpha(c) || isdigit(c)).
inline bool isAlphaNumeric(int c)
{
return ( isalnum(c) == 0 ? false : true);
}
// Checks for an alphabetic character.
// It is equivalent to (isupper(c) || islower(c)).
inline bool isAlpha(int c)
{
return ( isalpha(c) == 0 ? false : true);
}
// Checks whether c is a 7-bit unsigned char value
// that fits into the ASCII character set.
inline bool isAscii(int c)
{
return ( isascii (c) == 0 ? false : true);
}
// Checks for a blank character, that is, a space or a tab.
inline bool isWhitespace(int c)
{
return ( isblank (c) == 0 ? false : true);
}
// Checks for a control character.
inline bool isControl(int c)
{
return ( iscntrl (c) == 0 ? false : true);
}
// Checks for a digit (0 through 9).
inline bool isDigit(int c)
{
return ( isdigit (c) == 0 ? false : true);
}
// Checks for any printable character except space.
inline bool isGraph(int c)
{
return ( isgraph (c) == 0 ? false : true);
}
// Checks for a lower-case character.
inline bool isLowerCase(int c)
{
return (islower (c) == 0 ? false : true);
}
// Checks for any printable character including space.
inline bool isPrintable(int c)
{
return ( isprint (c) == 0 ? false : true);
}
// Checks for any printable character which is not a space
// or an alphanumeric character.
inline bool isPunct(int c)
{
return ( ispunct (c) == 0 ? false : true);
}
// Checks for white-space characters. For the avr-libc library,
// these are: space, formfeed ('\f'), newline ('\n'), carriage
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
inline bool isSpace(int c)
{
return ( isspace (c) == 0 ? false : true);
}
// Checks for an uppercase letter.
inline bool isUpperCase(int c)
{
return ( isupper (c) == 0 ? false : true);
}
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
// 8 9 a b c d e f A B C D E F.
inline bool isHexadecimalDigit(int c)
{
return ( isxdigit (c) == 0 ? false : true);
}
// Converts c to a 7-bit unsigned char value that fits into the
// ASCII character set, by clearing the high-order bits.
inline int toAscii(int c)
{
return toascii (c);
}
// Warning:
// Many people will be unhappy if you use this function.
// This function will convert accented letters into random
// characters.
// Converts the letter c to lower case, if possible.
inline int toLowerCase(int c)
{
return tolower (c);
}
// Converts the letter c to upper case, if possible.
inline int toUpperCase(int c)
{
return toupper (c);
}
}
#endif
@@ -0,0 +1,37 @@
/*
dtostrf - Emulation for dtostrf function from avr-libc
Copyright (c) 2016 Arduino LLC. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// This is a default implementation for dtostrf function.
// This file should be used if the standard lib doesn't provide an
// implementation of dtostrf.
// Create a file called "dtostrf.c" with the following include:
// #include "api/deprecated-avr-comp/avr/dtostrf.c.impl"
#include <stdio.h>
char *dtostrf (double val, signed char width, unsigned char prec, char *sout) {
asm(".global _printf_float");
char fmt[20];
sprintf(fmt, "%%%d.%df", width, prec);
sprintf(sout, fmt, val);
return sout;
}
@@ -0,0 +1,34 @@
/*
dtostrf - Emulation for dtostrf function from avr-libc
Copyright (c) 2015 Arduino LLC. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#if !defined(ARDUINO_ARCH_AVR)
#ifdef __cplusplus
extern "C" {
#endif
char *dtostrf(double val, signed char width, unsigned char prec, char *sout);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,23 @@
/*
Copyright (c) 2015 Arduino LCC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
Empty file.
This file is here to allow compatibility with sketches (made for AVR)
that includes <AVR/interrupt.h>
*/
@@ -0,0 +1,142 @@
/*
pgmspace.h - Definitions for compatibility with AVR pgmspace macros
Copyright (c) 2015 Arduino LLC
Based on work of Paul Stoffregen on Teensy 3 (http://pjrc.com)
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 __PGMSPACE_H_
#define __PGMSPACE_H_ 1
#include <inttypes.h>
#define PROGMEM
#define PGM_P const char *
#define PSTR(str) (str)
#define _SFR_BYTE(n) (n)
typedef void prog_void;
typedef char prog_char;
typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;
typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t;
typedef const void* int_farptr_t;
typedef const void* uint_farptr_t;
#define memchr_P(s, c, n) memchr((s), (c), (n))
#define memcmp_P(s1, s2, n) memcmp((s1), (s2), (n))
#define memccpy_P(dest, src, c, n) memccpy((dest), (src), (c), (n))
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#define memmem_P(haystack, haystacklen, needle, needlelen) memmem((haystack), (haystacklen), (needle), (needlelen))
#define memrchr_P(s, c, n) memrchr((s), (c), (n))
#define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(s, c) strchr((s), (c))
#define strchrnul_P(s, c) strchrnul((s), (c))
#define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(s1, s2) strcasecmp((s1), (s2))
#define strcasestr_P(haystack, needle) strcasestr((haystack), (needle))
#define strcspn_P(s, accept) strcspn((s), (accept))
#define strlcat_P(s1, s2, n) strlcat((s1), (s2), (n))
#define strlcpy_P(s1, s2, n) strlcpy((s1), (s2), (n))
#define strlen_P(a) strlen((a))
#define strnlen_P(s, n) strnlen((s), (n))
#define strncmp_P(s1, s2, n) strncmp((s1), (s2), (n))
#define strncasecmp_P(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strncat_P(s1, s2, n) strncat((s1), (s2), (n))
#define strncpy_P(s1, s2, n) strncpy((s1), (s2), (n))
#define strpbrk_P(s, accept) strpbrk((s), (accept))
#define strrchr_P(s, c) strrchr((s), (c))
#define strsep_P(sp, delim) strsep((sp), (delim))
#define strspn_P(s, accept) strspn((s), (accept))
#define strstr_P(a, b) strstr((a), (b))
#define strtok_P(s, delim) strtok((s), (delim))
#define strtok_rP(s, delim, last) strtok((s), (delim), (last))
#define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
#define snprintf_P(s, f, ...) snprintf((s), (f), __VA_ARGS__)
#define vsprintf_P(s, f, ...) vsprintf((s), (f), __VA_ARGS__)
#define vsnprintf_P(s, f, ...) vsnprintf((s), (f), __VA_ARGS__)
#if 0
// Requires natural aligned addresses
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr))
#define pgm_read_ptr(addr) (*(void *const *)(addr))
#else
// Supports misaligned addresses
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) ((unsigned short)(pgm_read_byte((intptr_t)addr) | (pgm_read_byte((intptr_t)addr + 1) << 8)))
#define pgm_read_dword(addr) ((unsigned long)(pgm_read_byte((intptr_t)addr) | (pgm_read_byte((intptr_t)addr + 1) << 8)) | \
(pgm_read_byte((intptr_t)addr + 2) << 16) | (pgm_read_byte((intptr_t)addr + 3) << 24))
#define pgm_read_ptr(addr) ((void *)pgm_read_dword(addr))
static inline float pgm_read_float(const void *addr) {
union {
void *p;
float f;
} x;
x.p = pgm_read_ptr(addr);
return x.f;
}
#endif
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define pgm_get_far_address(addr) (&(addr))
#endif
+25
View File
@@ -0,0 +1,25 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including Client.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../Client.h"
@@ -0,0 +1,25 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including HardwareSerial.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../HardwareSerial.h"
+25
View File
@@ -0,0 +1,25 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including IPAddress.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../IPAddress.h"
+24
View File
@@ -0,0 +1,24 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including Print.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../Print.h"
+24
View File
@@ -0,0 +1,24 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including Printable.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../Printable.h"
+25
View File
@@ -0,0 +1,25 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including Server.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../Server.h"
+25
View File
@@ -0,0 +1,25 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including Stream.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../Stream.h"
+25
View File
@@ -0,0 +1,25 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including Udp.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../Udp.h"
+24
View File
@@ -0,0 +1,24 @@
/*
Copyright 2016, Arduino LLC. All Right Reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// including WString.h is deprecated, for all future projects use Arduino.h instead
// This include is added for compatibility, it will be remove on the next
// major release of the API
#include "../String.h"
+37
View File
@@ -0,0 +1,37 @@
/*
Copyright (c) 2016 Arduino LLC. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
// Standard C functions required in Arduino API
// If these functions are not provided by the standard library, the
// core should supply an implementation of them.
#ifdef __cplusplus
extern "C" {
#endif
extern char* itoa(int value, char *string, int radix);
extern char* ltoa(long value, char *string, int radix);
extern char* utoa(unsigned value, char *string, int radix);
extern char* ultoa(unsigned long value, char *string, int radix);
#ifdef __cplusplus
} // extern "C"
#endif
+38 -38
View File
@@ -1,46 +1,46 @@
/*
* Core debug macros header for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Core debug macros header for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if !defined(DEBUG_RP2040_PORT)
#define DEBUGV(...) do { } while(0)
#define DEBUGCORE(...) do { } while(0)
#define DEBUGWIRE(...) do { } while(0)
#define DEBUGSPI(...) do { } while(0)
#define DEBUGV(...) do { } while(0)
#define DEBUGCORE(...) do { } while(0)
#define DEBUGWIRE(...) do { } while(0)
#define DEBUGSPI(...) do { } while(0)
#else
#define DEBUGV(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#define DEBUGV(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#if defined(DEBUG_RP2040_CORE)
#define DEBUGCORE(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGCORE(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_CORE)
#define DEBUGCORE(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGCORE(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_WIRE)
#define DEBUGWIRE(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGWIRE(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_WIRE)
#define DEBUGWIRE(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGWIRE(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_SPI)
#define DEBUGSPI(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGSPI(...) do { } while(0)
#endif
#if defined(DEBUG_RP2040_SPI)
#define DEBUGSPI(fmt, ...) do { DEBUG_RP2040_PORT.printf(fmt, ## __VA_ARGS__); DEBUG_RP2040_PORT.flush(); } while (0)
#else
#define DEBUGSPI(...) do { } while(0)
#endif
#endif
+50 -38
View File
@@ -1,50 +1,62 @@
/*
* delay() for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
delay() for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <pico.h>
#include <pico/time.h>
extern "C" void delay( unsigned long ms ) {
if (!ms) {
return;
#ifdef USE_TINYUSB
#include "Adafruit_TinyUSB_API.h"
#endif
extern "C"
{
void delay(unsigned long ms) {
if (!ms) {
return;
}
sleep_ms(ms);
}
sleep_ms(ms);
}
extern "C" void delayMicroseconds( unsigned int usec ) {
if (!usec) {
return;
void delayMicroseconds(unsigned int usec) {
if (!usec) {
return;
}
sleep_us(usec);
}
sleep_us(usec);
}
extern "C" void yield() {
// NOOP
}
void yield() {
#ifdef USE_TINYUSB
TinyUSB_Device_Task();
TinyUSB_Device_FlushCDC();
#endif
}
extern "C" uint32_t millis() {
return to_ms_since_boot(get_absolute_time());
}
extern "C" uint32_t micros() {
return to_us_since_boot(get_absolute_time());
}
uint32_t millis() {
return to_ms_since_boot(get_absolute_time());
}
uint32_t micros() {
return to_us_since_boot(get_absolute_time());
}
} // extern C
+69 -146
View File
@@ -1,25 +1,33 @@
/*
* Main handler for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Main handler for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <Arduino.h>
#include "RP2040USB.h"
#include <pico/stdlib.h>
#include <pico/multicore.h>
RP2040 rp2040;
volatile bool _MFIFO::_otherIdled = false;
mutex_t _pioMutex;
extern void setup();
extern void loop();
@@ -29,25 +37,66 @@ extern void loop();
void initVariant() __attribute__((weak));
void initVariant() { }
// Optional 2nd core setup and loop
extern void setup1() __attribute__((weak));
extern void loop1() __attribute__((weak));
static void main1() {
rp2040.fifo.registerCore();
if (setup1) {
setup1();
}
while (true) {
if (loop1) {
loop1();
}
}
}
extern "C" int main() {
#if F_CPU != 125000000
set_sys_clock_khz(F_CPU / 1000, true);
#endif
mutex_init(&_pioMutex);
initVariant();
#ifndef NO_USB
#ifdef USE_TINYUSB
TinyUSB_Device_Init(0);
#else
__USBStart();
#ifndef DISABLE_USB_SERIAL
// Enable serial port for reset/upload always
Serial.begin();
Serial.begin(115200);
#endif
#endif
#endif
#if defined DEBUG_RP2040_PORT
DEBUG_RP2040_PORT.begin();
#endif
#ifndef NO_USB
if (setup1 || loop1) {
rp2040.fifo.begin(2);
multicore_launch_core1(main1);
} else {
rp2040.fifo.begin(1);
}
rp2040.fifo.registerCore();
#endif
setup();
while (1) {
while (true) {
loop();
#ifdef USE_TINYUSB
yield();
#endif
if (arduino::serialEventRun) {
arduino::serialEventRun();
}
@@ -60,129 +109,3 @@ extern "C" int main() {
}
return 0;
}
/* NEWLIB syscall overloads, so we can ::print() and ::getc() using our objects */
/* Placed here to ensure this compilation unit will be present when it's time */
/* to link newlib.a. */
#include <stdint.h>
#include <errno.h>
#include <_syslist.h>
#include <sys/times.h>
#include <bits/stdc++.h>
#undef errno
// TODO - check the fd, create a VFS, etc.
extern "C" int errno;
extern "C" ssize_t _write(int fd, const void *buf, size_t count) {
#if defined DEBUG_RP2040_PORT
return DEBUG_RP2040_PORT.write((const char *)buf, count);
#else
return 0;
#endif
}
extern "C" int _chown (const char *path, uid_t owner, gid_t group) {
errno = ENOSYS;
return -1;
}
extern "C" int _close (int fildes) {
errno = ENOSYS;
return -1;
}
extern "C" int _execve (char *name, char **argv, char **env) {
errno = ENOSYS;
return -1;
}
extern "C" int _fork (void) {
errno = ENOSYS;
return -1;
}
extern "C" int _fstat (int fildes, struct stat *st) {
errno = ENOSYS;
return -1;
}
extern "C" int _getpid (void) {
errno = ENOSYS;
return -1;
}
struct timeval;
extern "C" int _gettimeofday (struct timeval *ptimeval, void *ptimezone)
{
errno = ENOSYS;
return -1;
}
extern "C" int _isatty (int file) {
errno = ENOSYS;
return 0;
}
extern "C" int _kill (int pid, int sig) {
errno = ENOSYS;
return -1;
}
extern "C" int _link (char *existing, char *newlink) {
errno = ENOSYS;
return -1;
}
extern "C" int _lseek (int file, int ptr, int dir) {
errno = ENOSYS;
return -1;
}
extern "C" int _open (char *file, int flags, int mode) {
errno = ENOSYS;
return -1;
}
extern "C" int _read (int file, char *ptr, int len)
{
// return Serial.read(ptr, len);
return -1;
}
extern "C" int _readlink (const char *path, char *buf, size_t bufsize) {
errno = ENOSYS;
return -1;
}
extern "C" int _stat (const char *file, struct stat *st) {
errno = ENOSYS;
return -1;
}
extern "C" int _symlink (const char *path1, const char *path2) {
errno = ENOSYS;
return -1;
}
extern "C" clock_t _times (struct tms *buf) {
errno = ENOSYS;
return -1;
}
extern "C" int _unlink (char *name) {
errno = ENOSYS;
return -1;
}
extern "C" int _wait (int *status) {
errno = ENOSYS;
return -1;
}
extern "C" void __sync_synchronize() { /* noop */ }
+18 -18
View File
@@ -1,22 +1,22 @@
/*
* Millis() for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
Millis() for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <pico/time.h>
+193
View File
@@ -0,0 +1,193 @@
/*
NEWLIB syscall implementations
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <Arduino.h>
#include <stdint.h>
#include <errno.h>
#include <_syslist.h>
#include <sys/times.h>
#include <pico/stdlib.h>
#include <pico/multicore.h>
#undef errno
// TODO - check the fd, create a VFS, etc.
extern "C" int errno;
extern "C" ssize_t _write(int fd, const void *buf, size_t count) {
#if defined DEBUG_RP2040_PORT
(void) fd;
return DEBUG_RP2040_PORT.write((const char *)buf, count);
#else
(void) fd;
(void) buf;
(void) count;
return 0;
#endif
}
extern "C" int _chown(const char *path, uid_t owner, gid_t group) {
(void) path;
(void) owner;
(void) group;
errno = ENOSYS;
return -1;
}
extern "C" int _close(int fd) {
(void) fd;
errno = ENOSYS;
return -1;
}
extern "C" int _execve(char *name, char **argv, char **env) {
(void) name;
(void) argv;
(void) env;
errno = ENOSYS;
return -1;
}
extern "C" int _fork(void) {
errno = ENOSYS;
return -1;
}
extern "C" int _fstat(int fd, struct stat *st) {
(void) fd;
(void) st;
errno = ENOSYS;
return -1;
}
extern "C" int _getpid(void) {
errno = ENOSYS;
return -1;
}
static int64_t __timedelta_us = 0.0;
extern "C" int _gettimeofday(struct timeval *tv, void *tz) {
(void) tz;
uint64_t now_us = to_us_since_boot(get_absolute_time()) + __timedelta_us;
if (tv) {
tv->tv_sec = now_us / 1000000L;
tv->tv_usec = now_us % 1000000L;
}
return 0;
}
extern "C" int settimeofday(const struct timeval *tv, const struct timezone *tz) {
(void) tz;
uint64_t now_us = to_us_since_boot(get_absolute_time());
if (tv) {
uint64_t newnow_us;
newnow_us = tv->tv_sec * 1000000L;
newnow_us += tv->tv_usec;
__timedelta_us = newnow_us - now_us;
}
return 0;
}
extern "C" int _isatty(int file) {
(void) file;
errno = ENOSYS;
return 0;
}
extern "C" int _kill(int pid, int sig) {
(void) pid;
(void) sig;
errno = ENOSYS;
return -1;
}
extern "C" int _link(char *existing, char *newlink) {
(void) existing;
(void) newlink;
errno = ENOSYS;
return -1;
}
extern "C" int _lseek(int file, int ptr, int dir) {
(void) file;
(void) ptr;
(void) dir;
errno = ENOSYS;
return -1;
}
extern "C" int _open(char *file, int flags, int mode) {
(void) file;
(void) flags;
(void) mode;
errno = ENOSYS;
return -1;
}
extern "C" int _read(int file, char *ptr, int len) {
(void) file;
(void) ptr;
(void) len;
// return Serial.read(ptr, len);
return -1;
}
extern "C" int _readlink(const char *path, char *buf, size_t bufsize) {
(void) path;
(void) buf;
(void) bufsize;
errno = ENOSYS;
return -1;
}
extern "C" int _stat(const char *file, struct stat *st) {
(void) file;
(void) st;
errno = ENOSYS;
return -1;
}
extern "C" int _symlink(const char *path1, const char *path2) {
(void) path1;
(void) path2;
errno = ENOSYS;
return -1;
}
extern "C" clock_t _times(struct tms *buf) {
(void) buf;
errno = ENOSYS;
return -1;
}
extern "C" int _unlink(char *name) {
(void) name;
errno = ENOSYS;
return -1;
}
extern "C" int _wait(int *status) {
(void) status;
errno = ENOSYS;
return -1;
}
+37 -42
View File
@@ -1,23 +1,23 @@
/*
stdlib_noniso.h - nonstandard (but useful) conversion functions
stdlib_noniso.h - nonstandard (but useful) conversion functions
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
Copyright (c) 2021 David Gauchard. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
Copyright (c) 2021 David Gauchard. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU Lesser General Public
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 <stdlib.h>
@@ -32,37 +32,31 @@
// but is smaller by ~800B/flash and ~250B/rodata
// ulltoa fills str backwards and can return a pointer different from str
extern "C" char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix)
{
extern "C" char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) {
str += --slen;
*str = 0;
do
{
do {
auto mod = val % radix;
val /= radix;
*--str = mod + ((mod > 9) ? ('a' - 10) : '0');
} while (--slen && val);
return val? nullptr: str;
return val ? nullptr : str;
}
// lltoa fills str backwards and can return a pointer different from str
extern "C" char* lltoa (long long val, char* str, int slen, unsigned int radix)
{
extern "C" char* lltoa(long long val, char* str, int slen, unsigned int radix) {
bool neg;
if (val < 0)
{
if (val < 0) {
val = -val;
neg = true;
}
else
{
} else {
neg = false;
}
char* ret = ulltoa(val, str, slen, radix);
if (neg)
{
if (ret == str || ret == nullptr)
if (neg) {
if (ret == str || ret == nullptr) {
return nullptr;
}
*--ret = '-';
}
return ret;
@@ -92,7 +86,7 @@ extern "C" char * dtostrf(double number, signed char width, unsigned char prec,
int fillme = width; // how many cells to fill for the integer part
if (prec > 0) {
fillme -= (prec+1);
fillme -= (prec + 1);
}
// Handle negative numbers
@@ -105,8 +99,9 @@ extern "C" char * dtostrf(double number, signed char width, unsigned char prec,
// Round correctly so that print(1.999, 2) prints as "2.00"
// I optimized out most of the divisions
double rounding = 2.0;
for (uint8_t i = 0; i < prec; ++i)
for (uint8_t i = 0; i < prec; ++i) {
rounding *= 10.0;
}
rounding = 1.0 / rounding;
number += rounding;
@@ -132,14 +127,18 @@ extern "C" char * dtostrf(double number, signed char width, unsigned char prec,
}
// Handle negative sign
if (negative) *out++ = '-';
if (negative) {
*out++ = '-';
}
// Print the digits, and if necessary, the decimal point
digitcount += prec;
int8_t digit = 0;
while (digitcount-- > 0) {
digit = (int8_t)number;
if (digit > 9) digit = 9; // insurance
if (digit > 9) {
digit = 9; // insurance
}
*out++ = (char)('0' | digit);
if ((digitcount == prec) && (prec > 0)) {
*out++ = '.';
@@ -161,8 +160,7 @@ extern "C" char * dtostrf(double number, signed char width, unsigned char prec,
*/
extern "C" const char* strrstr(const char*__restrict p_pcString,
const char*__restrict p_pcPattern)
{
const char*__restrict p_pcPattern) {
const char* pcResult = 0;
size_t stStringLength = (p_pcString ? strlen(p_pcString) : 0);
@@ -170,13 +168,10 @@ extern "C" const char* strrstr(const char*__restrict p_pcString,
if ((stStringLength) &&
(stPatternLength) &&
(stPatternLength <= stStringLength))
{
(stPatternLength <= stStringLength)) {
// Pattern is shorter or has the same length than the string
for (const char* s = (p_pcString + stStringLength - stPatternLength); s >= p_pcString; --s)
{
if (0 == strncmp(s, p_pcPattern, stPatternLength))
{
for (const char* s = (p_pcString + stStringLength - stPatternLength); s >= p_pcString; --s) {
if (0 == strncmp(s, p_pcPattern, stPatternLength)) {
pcResult = s;
break;
}
+22 -22
View File
@@ -1,29 +1,29 @@
/*
stdlib_noniso.h - nonstandard (but useful) conversion functions
stdlib_noniso.h - nonstandard (but useful) conversion functions
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
Copyright (c) 2014 Ivan Grokhotkov. All rights reserved.
This file is part of the esp8266 core for Arduino environment.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
You should have received a copy of the GNU Lesser General Public
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 STDLIB_NONISO_H
#define STDLIB_NONISO_H
#ifdef __cplusplus
extern "C"{
extern "C" {
#endif
int atoi(const char *s);
@@ -32,19 +32,19 @@ long atol(const char* s);
double atof(const char* s);
char* itoa (int val, char *s, int radix);
char* itoa(int val, char *s, int radix);
char* ltoa (long val, char *s, int radix);
char* ltoa(long val, char *s, int radix);
char* lltoa (long long val, char* str, int slen, unsigned int radix);
char* lltoa(long long val, char* str, int slen, unsigned int radix);
char* utoa (unsigned int val, char *s, int radix);
char* utoa(unsigned int val, char *s, int radix);
char* ultoa (unsigned long val, char *s, int radix);
char* ultoa(unsigned long val, char *s, int radix);
char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix);
char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix);
char* dtostrf (double val, signed char width, unsigned char prec, char *s);
char* dtostrf(double val, signed char width, unsigned char prec, char *s);
void reverse(char* begin, char* end);
-52
View File
@@ -1,52 +0,0 @@
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //
#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif
// ---- //
// tone //
// ---- //
#define tone_wrap_target 0
#define tone_wrap 7
static const uint16_t tone_program_instructions[] = {
// .wrap_target
0x80a0, // 0: pull block
0xa027, // 1: mov x, osr
0xb846, // 2: mov y, isr side 1
0x0083, // 3: jmp y--, 3
0x0045, // 4: jmp x--, 5
0xb046, // 5: mov y, isr side 0
0x0086, // 6: jmp y--, 6
0x0042, // 7: jmp x--, 2
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program tone_program = {
.instructions = tone_program_instructions,
.length = 8,
.origin = -1,
};
static inline pio_sm_config tone_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + tone_wrap_target, offset + tone_wrap);
sm_config_set_sideset(&c, 2, true, false);
return c;
}
static inline void tone_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = tone_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
pio_sm_init(pio, sm, offset, &c);
}
#endif
@@ -1,4 +1,4 @@
; Tone for the Raspberry Pi Pico RP2040
; Tone2 for the Raspberry Pi Pico RP2040
;
; Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
;
@@ -18,32 +18,35 @@
; Side-set pin 0 is used for Tone output
.program tone
; OSR == Halfcycle count
.program tone2
.side_set 1 opt
pull
mov x, osr
pull ; TXFIFO -> OSR, or X -> OSR if no new period
mov x, osr ; OSR -> X
high:
mov y, isr side 1
pull noblock ; Potentially grab new HALFCYCLECOUNT, OTW copy from backup in X
mov x, osr ; OSR -> X
mov y, osr side 1 ; HALFCYCLECOUNT -> Y
highloop:
jmp y-- highloop
jmp x-- low
jmp y-- highloop ; while (y--) { /* noop delay */ }
low:
mov y, isr side 0
mov y, osr side 0 ; HALFCYCLECOUNT -> Y
lowloop:
jmp y-- lowloop
jmp y-- lowloop ; while (y--) { /* noop delay */ }
jmp x-- high
jmp high ; GOTO high
% c-sdk {
static inline void tone_program_init(PIO pio, uint sm, uint offset, uint pin) {
static inline void tone2_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = tone_program_get_default_config(offset);
pio_sm_config c = tone2_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
pio_sm_init(pio, sm, offset, &c);
}
%}
+53
View File
@@ -0,0 +1,53 @@
// -------------------------------------------------- //
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //
#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif
// ----- //
// tone2 //
// ----- //
#define tone2_wrap_target 0
#define tone2_wrap 8
static const uint16_t tone2_program_instructions[] = {
// .wrap_target
0x80a0, // 0: pull block
0xa027, // 1: mov x, osr
0x8080, // 2: pull noblock
0xa027, // 3: mov x, osr
0xb847, // 4: mov y, osr side 1
0x0085, // 5: jmp y--, 5
0xb047, // 6: mov y, osr side 0
0x0087, // 7: jmp y--, 7
0x0002, // 8: jmp 2
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program tone2_program = {
.instructions = tone2_program_instructions,
.length = 9,
.origin = -1,
};
static inline pio_sm_config tone2_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + tone2_wrap_target, offset + tone2_wrap);
sm_config_set_sideset(&c, 2, true, false);
return c;
}
static inline void tone2_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_gpio_init(pio, pin);
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);
pio_sm_config c = tone2_program_get_default_config(offset);
sm_config_set_sideset_pins(&c, pin);
pio_sm_init(pio, sm, offset, &c);
}
#endif
+40 -27
View File
@@ -1,36 +1,38 @@
/*
* PWM and analogRead for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
PWM and analogRead for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <Arduino.h>
#include <CoreMutex.h>
#include <hardware/gpio.h>
#include <hardware/pwm.h>
#include <hardware/clocks.h>
#include <hardware/pll.h>
#include <hardware/adc.h>
static int32_t analogScale = 255;
static uint32_t analogMap = 0;
static uint32_t analogScale = 255;
static uint16_t analogFreq = 1000;
static bool pwmInitted = false;
static bool adcInitted = false;
auto_init_mutex(_dacMutex);
extern "C" void analogWriteFreq(uint32_t freq) {
if (freq == analogFreq) {
return;
@@ -68,23 +70,25 @@ extern "C" void analogWriteResolution(int res) {
}
extern "C" void analogWrite(pin_size_t pin, int val) {
if ((pin < 0) || (pin > 29)) {
CoreMutex m(&_dacMutex);
if ((pin > 29) || !m) {
DEBUGCORE("ERROR: Illegal analogWrite pin (%d)\n", pin);
return;
}
if (!pwmInitted) {
pwm_config c = pwm_get_default_config();
pwm_config_set_clkdiv( &c, clock_get_hz(clk_sys) / (float) (analogScale * analogFreq) );
pwm_config_set_wrap( &c, analogScale );
for (int i=0; i<30; i++) {
pwm_config_set_clkdiv(&c, clock_get_hz(clk_sys) / (float)(analogScale * analogFreq));
pwm_config_set_wrap(&c, analogScale);
for (int i = 0; i < 30; i++) {
pwm_init(pwm_gpio_to_slice_num(i), &c, true);
}
pwmInitted = true;
}
if (val < 0) {
val = 0;
} else if (val > analogScale) {
} else if ((uint32_t)val > analogScale) {
val = analogScale;
}
@@ -92,8 +96,12 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
pwm_set_gpio_level(pin, val);
}
auto_init_mutex(_adcMutex);
extern "C" int analogRead(pin_size_t pin) {
if ((pin < A0) || (pin > A3)) {
CoreMutex m(&_adcMutex);
if ((pin < A0) || (pin > A3) || !m) {
DEBUGCORE("ERROR: Illegal analogRead pin (%d)\n", pin);
return 0;
}
@@ -106,6 +114,11 @@ extern "C" int analogRead(pin_size_t pin) {
}
extern "C" float analogReadTemp() {
CoreMutex m(&_adcMutex);
if (!m) {
return 0.0f; // Deadlock
}
if (!adcInitted) {
adc_init();
}
+49 -49
View File
@@ -1,68 +1,69 @@
/*
* pinMode and digitalRead/Write for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
pinMode and digitalRead/Write for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 "Arduino.h"
#include <hardware/gpio.h>
static PinMode _pm[30];
extern "C" void pinMode( pin_size_t ulPin, PinMode ulMode ) {
extern "C" void pinMode(pin_size_t ulPin, PinMode ulMode) {
switch (ulMode) {
case INPUT:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
break;
case INPUT_PULLUP:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
gpio_pull_up(ulPin);
gpio_put(ulPin, 0);
break;
case INPUT_PULLDOWN:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
gpio_pull_down(ulPin);
gpio_put(ulPin, 1);
break;
case OUTPUT:
gpio_init(ulPin);
gpio_set_dir(ulPin, true);
break;
default:
DEBUGCORE("ERROR: Illegal pinMode mode (%d)\n", ulMode);
// Error
return;
case INPUT:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
break;
case INPUT_PULLUP:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
gpio_pull_up(ulPin);
gpio_put(ulPin, 0);
break;
case INPUT_PULLDOWN:
gpio_init(ulPin);
gpio_set_dir(ulPin, false);
gpio_pull_down(ulPin);
gpio_put(ulPin, 1);
break;
case OUTPUT:
gpio_init(ulPin);
gpio_set_dir(ulPin, true);
break;
default:
DEBUGCORE("ERROR: Illegal pinMode mode (%d)\n", ulMode);
// Error
return;
}
if ((ulPin < 0) || (ulPin > 29)) {
if (ulPin > 29) {
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
return;
}
_pm[ulPin] = ulMode;
}
extern "C" void digitalWrite( pin_size_t ulPin, PinStatus ulVal ) {
if ((ulPin < 0) || (ulPin > 29)) {
extern "C" void digitalWrite(pin_size_t ulPin, PinStatus ulVal) {
if (ulPin > 29) {
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
return;
}
gpio_set_function(ulPin, GPIO_FUNC_SIO);
if (_pm[ulPin] == INPUT_PULLDOWN) {
if (ulVal == LOW) {
gpio_set_dir(ulPin, false);
@@ -80,11 +81,10 @@ extern "C" void digitalWrite( pin_size_t ulPin, PinStatus ulVal ) {
}
}
extern "C" PinStatus digitalRead( pin_size_t ulPin ) {
if ((ulPin < 0) || (ulPin > 29)) {
extern "C" PinStatus digitalRead(pin_size_t ulPin) {
if (ulPin > 29) {
DEBUGCORE("ERROR: Illegal pin in digitalRead (%d)\n", ulPin);
return LOW;
}
return gpio_get(ulPin) ? HIGH : LOW;
}
+56 -33
View File
@@ -1,68 +1,86 @@
/*
* wiring_private for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
wiring_private for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <Arduino.h>
#include <CoreMutex.h>
#include <hardware/gpio.h>
#include <hardware/sync.h>
#include <stack>
#include <map>
// Support nested IRQ disable/re-enable
static std::stack<uint32_t> _irqStack;
static std::stack<uint32_t> _irqStack[2];
extern "C" void interrupts() {
if (_irqStack.empty()) {
if (_irqStack[get_core_num()].empty()) {
// ERROR
return;
}
restore_interrupts(_irqStack.top());
_irqStack.pop();
auto oldIrqs = _irqStack[get_core_num()].top();
_irqStack[get_core_num()].pop();
restore_interrupts(oldIrqs);
}
extern "C" void noInterrupts() {
_irqStack.push(save_and_disable_interrupts());
_irqStack[get_core_num()].push(save_and_disable_interrupts());
}
// Only 1 GPIO IRQ callback for all pins, so we need to look at the pin it's for and
// dispatch to the real callback manually
auto_init_mutex(_irqMutex);
static std::map<pin_size_t, voidFuncPtr> _map;
void _gpioInterruptDispatcher(uint gpio, uint32_t events) {
auto irq = _map.find(gpio);
if (irq != _map.end()) {
// Ignore events, only one event per pin supported by Arduino
irq->second(); // Do the callback
(void) events;
// Only need to lock around the std::map check, not the whole IRQ callback
voidFuncPtr cb = nullptr;
{
CoreMutex m(&_irqMutex);
if (m) {
auto irq = _map.find(gpio);
if (irq != _map.end()) {
cb = irq->second;
}
}
}
if (cb) {
cb(); // Do the callback
} else {
// ERROR, but we're in an IRQ so do nothing
}
}
extern "C" void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus mode) {
CoreMutex m(&_irqMutex);
if (!m) {
return;
}
uint32_t events;
switch (mode) {
case LOW: events = 1; break;
case HIGH: events = 2; break;
case FALLING: events = 4; break;
case RISING: events = 8; break;
case CHANGE: events = 4 | 8; break;
default: return; // ERROR
case LOW: events = 1; break;
case HIGH: events = 2; break;
case FALLING: events = 4; break;
case RISING: events = 8; break;
case CHANGE: events = 4 | 8; break;
default: return; // ERROR
}
noInterrupts();
detachInterrupt(pin);
@@ -72,6 +90,11 @@ extern "C" void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus
}
extern "C" void detachInterrupt(pin_size_t pin) {
CoreMutex m(&_irqMutex);
if (!m) {
return;
}
noInterrupts();
auto irq = _map.find(pin);
if (irq != _map.end()) {
+33 -29
View File
@@ -1,55 +1,59 @@
/*
* pulseIn for the Raspberry Pi Pico RP2040
*
* Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
pulseIn for the Raspberry Pi Pico RP2040
Copyright (c) 2021 Earle F. Philhower, III <earlephilhower@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
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 <Arduino.h>
#include <hardware/timer.h>
#include <hardware/gpio.h>
extern "C" unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
extern "C" unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) {
uint64_t start = time_us_64();
uint64_t abort = start + timeout;
if ((pin < 0) || (pin > 29)) {
if (pin > 29) {
DEBUGCORE("ERROR: Illegal pin in pulseIn (%d)\n", pin);
return 0;
}
// Wait for deassert, if needed
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort) );
if (time_us_64() >= abort) return 0;
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort));
if (time_us_64() >= abort) {
return 0;
}
// Wait for assert
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort) );
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort));
uint64_t begin = time_us_64();
if (begin >= abort) return 0;
if (begin >= abort) {
return 0;
}
// Wait for deassert
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort) );
while ((!!gpio_get(pin) != !state) && (time_us_64() < abort));
uint64_t end = time_us_64();
if (end >= abort) return 0;
if (end >= abort) {
return 0;
}
return end - begin;
}
extern "C" unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout)
{
extern "C" unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout) {
return pulseIn(pin, state, timeout);
}
+34 -32
View File
@@ -1,22 +1,22 @@
/*
* wiring_shift.c - shiftOut() function
* Part of Arduino - http://www.arduino.cc/
*
* Copyright (c) 2005-2006 David A. Mellis
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307 USA
wiring_shift.c - shiftOut() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/
#include <Arduino.h>
@@ -24,42 +24,44 @@
extern "C" uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder) {
uint8_t value = 0;
uint8_t i;
if ((dataPin < 0) || (dataPin > 29)) {
if (dataPin > 29) {
DEBUGCORE("ERROR: Illegal dataPin in shiftIn (%d)\n", dataPin);
return 0;
}
if ((clockPin < 0) || (clockPin > 29)) {
if (clockPin > 29) {
DEBUGCORE("ERROR: Illegal clockPin in shiftIn (%d)\n", clockPin);
return 0;
}
for (i = 0; i < 8; ++i) {
digitalWrite(clockPin, HIGH);
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, LOW);
digitalWrite(clockPin, HIGH);
if (bitOrder == LSBFIRST) {
value |= digitalRead(dataPin) << i;
} else {
value |= digitalRead(dataPin) << (7 - i);
}
digitalWrite(clockPin, LOW);
}
return value;
}
extern "C" void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val) {
uint8_t i;
if ((dataPin < 0) || (dataPin > 29)) {
if (dataPin > 29) {
DEBUGCORE("ERROR: Illegal dataPin in shiftOut (%d)\n", dataPin);
return;
}
if ((clockPin < 0) || (clockPin > 29)) {
if (clockPin > 29) {
DEBUGCORE("ERROR: Illegal clockPin in shiftOut (%d)\n", clockPin);
return;
}
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
if (bitOrder == LSBFIRST) {
digitalWrite(dataPin, !!(val & (1 << i)));
else
} else {
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
}
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
digitalWrite(clockPin, LOW);
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ EEPROM Library
While the Raspberry Pi Pico RP2040 does not come with an EEPROM onboard, we
simulate one by using a single 4K chunk of flash at the end of flash space.
**Note that this is a simulated EEPROM and will only support the numeber of
**Note that this is a simulated EEPROM and will only support the number of
writes as the onboard flash chip, not the 100,000 or so of a real EEPROM.**
Therefore, do not frequently update the EEPROM or you may prematurely wear
out the flash.
+1 -1
View File
@@ -3,7 +3,7 @@ File Systems
The Arduino-Pico core supports using some of the onboard flash as a file
system, useful for storing configuration data, output strings, logging,
and more. It also supports using SD cards as another (FAT32) filesytem,
and more. It also supports using SD cards as another (FAT32) filesystem,
with an API that's compatible with the onboard flash file system.
+1 -1
View File
@@ -47,7 +47,7 @@ the output will be changing.
size_t write(uint8_t)
~~~~~~~~~~~~~~~~~~~~~
Provided for compatibilty, but not very useful. Writes a sample from 0...255
Provided for compatibility, but not very useful. Writes a sample from 0...255
to the I2S buffer. See ``write(int16_t)`` for a better one
size_t write(const uint8_t \*buffer, size_t size)

Some files were not shown because too many files have changed in this diff Show More