Compare commits

...
304 Commits
Author SHA1 Message Date
Earle F. Philhower, III 2297d61d92 Update version 2024-06-18 09:44:58 -07:00
Limor "Ladyada" Friedandhathach 6d601250d6 Add Adafruit Adalogger Feather (#2229)
Co-authored-by: hathach <thach@tinyusb.org>
2024-06-17 21:00:45 -07:00
Earle F. Philhower, III c99614c1f5 Add AsyncUDP and simple NetBIOS name lookup server (#2234)
Thanks to @me-no-dev's code.  Lets Windows look up the PicoW by name
using NBNS and needs much less memory and code than mDNS.

AsyncUDP ported from the old ESP8266 version, only minimal changes.  Will
probably only be valid in IPv4 environments and may not match current
ESP32 AsyncUDP interfaces.
2024-06-17 17:46:53 -07:00
Mete K. Atay 352d363463 Add METE HOCA Akana R1 (#2230) 2024-06-17 09:53:02 -07:00
Ayush Sharma 1775fedf44 Webserver: Add support for filters and removable routes (#2225)
This PR implements filters and removable routes in RP2040 arduino core, making it API compatible with recent changes to ESP32 & ESP8266 WebServer API.
2024-06-13 15:32:17 -07:00
Earle F. Philhower, III 4ab0ba6133 Fix crash on SD.end() without initial SD.begin() (#2222)
Fixes #2220
2024-06-11 13:40:27 -07:00
Earle F. Philhower, III eb0badd817 Avoid malloc/free while in HCI callbacks (#2219)
Bluetooth operates at IRQ level, so using std::list (which needs to
new and delete objects) is not legal.  Use a fixed, preallocated
vector instead.
2024-06-10 16:38:50 -07:00
Earle F. Philhower, III f272995536 For consistency, BTHID Joypad->Joystick (#2218)
Matches existing library names and nomenclature
2024-06-10 13:34:59 -07:00
Earle F. Philhower, III db13d3c1f8 Add basic A2DP BluetoothAudio documentation (#2217) 2024-06-09 17:47:13 -07:00
Earle F. Philhower, III f8c1ec100f Add BluetoothHIDMaster documentation (#2216)
Also link in FatFSUSB docs, d'oh!
2024-06-09 16:51:35 -07:00
Earle F. Philhower, III 1fd66bf9c2 Add joypad HID master support (#2214)
Play games on your Pico using Bluetooth gamepads!
2024-06-09 11:47:13 -07:00
Earle F. Philhower, III 151c52c1a0 Remove leftover LWIP debug/redefines (#2213)
Fixes #2211
2024-06-09 10:10:20 -07:00
Earle F. Philhower, III bde21e5ae1 Add BLE support to BluetoothHIDMaster (#2208)
Support Bluetooth BLE keyboard and mice using the same HID master
infrastructure as the BT Classic.
2024-06-07 14:52:52 -07:00
Earle F. Philhower, III c104c6717c Upgrade to Adafruit TinyUSB 3.1.5 (#2206) 2024-06-05 22:36:30 -07:00
Michael Rangen b0ffd89dbb Added Raspberry Breadstick (#2205)
https://shop.breadstick.ca/products/raspberry-breadstick-rp2040
I think I did the pin definitions correctly... other boards used generic pin numbers based on the GPIO pins but I've mapped GPIO to the silkscreen pin labels on our board.
2024-06-05 22:15:05 -07:00
Earle F. Philhower, III 0f05ad1cc2 Use block writes for BT audio consumers (#2204)
Around 2x the performance, and every bit is needed w/BT SBC compression
and decompression.
2024-06-05 16:03:35 -07:00
Zillion 0ec12aa49f Add GroundStudio Marble Pico board (#2203) 2024-06-05 15:18:21 -07:00
Earle F. Philhower, III f997a9c3bd Update README.md 2024-06-05 13:51:03 -07:00
Earle F. Philhower, III 9039089067 Fix PWMAudio::write(buffer, len) (#2202)
PWMAudio was only ever writing one half the buffer passed in because
of an off-by-2 error.  Fixes the sine output in KeyboardPiano.
2024-06-05 13:08:08 -07:00
Earle F. Philhower, III 8bc8c824d3 Update version 2024-06-05 12:03:10 -07:00
Earle F. Philhower, III f08ba6bd42 Rebuild OTA bootloader for newer LittleFS version (#2199)
The LittleFS folks changed the on-flash format in 2.6.0, making
it unmountable with earlier precompiled code.

Rebuild the OTA bootloader using the 2.9.3 LittleFS release,
matching the core version.

Fixes #2198
2024-06-05 11:48:16 -07:00
Earle F. Philhower, III 1ef61d725b Clean up OTA example references to ESP8266 (#2200) 2024-06-05 11:40:37 -07:00
Earle F. Philhower, III b42083f20a Add "Needs Bluetooth" compile warning (#2197) 2024-06-05 11:08:20 -07:00
Earle F. Philhower, III f820dc134a Update version 2024-06-04 14:46:13 -07:00
Earle F. Philhower, III f6d13d2b70 Bluetooth Master HID and musical keyboard example (#2195)
Adds BluetoothHIDMaster and HIDKeyStream which let the PicoW connect to
and use Bluetooth Classic HID devices like keyboards and mice.

An example that lets the PicoW use a BT keyboard as a piano is
included and shows the use of the new classes.
2024-06-04 14:09:28 -07:00
Earle F. Philhower, III f786583986 Split out BluetoothHCI for shared usage (#2194) 2024-06-03 15:09:55 -07:00
Earle F. Philhower, III 5f6fb75505 Move to LittleFS 2.9.3. (#2193)
On-flash format changed after 2.5.1, but this can read prior versions
and will upgrade on-device to the later version.
2024-06-03 09:32:52 -07:00
Christian Halter 962dedad21 Fix folder name for Archi board (#2191)
* fix: Changed folder name to match build.variant property
* Added GPIO definitions for Archi board
Co-authored-by: Christian Halter <christian.halter@newsan.com.ar>
2024-06-03 09:20:59 -07:00
Earle F. Philhower, III ce45c65568 Make LittleFS filenames support full size (#2192)
Support 255 character names, not just 32, in LittleFS filesystems.
2024-06-03 09:11:01 -07:00
Earle F. Philhower, III 6d6433f256 Add track info support for BT audio sink (#2190) 2024-05-31 13:08:41 -07:00
Earle F. Philhower, III bf385490d3 Fix crash on audio end from IRQ, refactor A2DP (#2189)
Fixes #2188

We get a call to stop the audio channel from a timer/IRQ context, so can't
safely remove the IRQ handler for the AudioBufferManager.  The SDK will panic.

Because the IRQ handler will be a noop if it's not uninstalled, we will
instead just leave our shared handler in place and let it do nothing.

Use a common BluetoothLock RAII in BluetoothAudio to clen up the code and
automatically lock BT for the AVRCP button methods.
2024-05-31 12:14:57 -07:00
Earle F. Philhower, III 919a754ef8 Add double-mem LWIP option (#2187)
Add a "-32K" option to all the IP stack options that doubles the PCB and memory
pools from default.  For most use cases this is not necessary, but it could be
helpful in cases where large numbers of TCP clients are connected or high
bandwidth applications.

Fixes #2050
2024-05-30 18:30:50 -07:00
Earle F. Philhower, III 0a2b616c8a Add Cookies to HTTPClient (#2186)
From:
https://github.com/espressif/arduino-esp32/pull/6216
https://github.com/espressif/arduino-esp32/pull/6280
https://github.com/espressif/arduino-esp32/pull/7112
2024-05-30 13:27:43 -07:00
Earle F. Philhower, III 56bd539528 Webserver Ignore extra headers in multipart forms (#2184)
From https://github.com/espressif/arduino-esp32/pull/9253
2024-05-30 13:16:15 -07:00
Earle F. Philhower, III 3839f07afe HTTPClient - Fix case sensitivity for header keys (#2185)
From https://github.com/espressif/arduino-esp32/pull/8713
2024-05-30 13:05:49 -07:00
Earle F. Philhower, III 2043623ce6 Fix POST form parser edge cases (#2182)
From https://github.com/espressif/arduino-esp32/pull/9167
2024-05-30 12:19:44 -07:00
Earle F. Philhower, III a3dba8be5d Fix AdvancedWebServer.ino uptime conversion (#2183)
From https://github.com/espressif/arduino-esp32/pull/9224
2024-05-30 12:07:28 -07:00
Earle F. Philhower, III 1f9350dc2a Allow setting SerialBT advertised name (#2181)
Trivial fix #2179
2024-05-30 11:40:40 -07:00
Earle F. Philhower, III 361b4e0862 Allow uploading huge files to WebServer (#2180)
From https://github.com/espressif/arduino-esp32/pull/9440
2024-05-30 11:24:18 -07:00
Earle F. Philhower, III fa2bfdc2ba Small RAM savings (128b) in WebServer (#2178)
From https://github.com/espressif/arduino-esp32/pull/9594
2024-05-30 10:38:50 -07:00
Earle F. Philhower, III 679be8520f Update version 2024-05-29 14:54:32 -07:00
Earle F. Philhower, III 01e9dc99f2 Add A2DP sink (speaker) support (#2177)
Provide direct connection from BT audio to I2S and PWM audio outputs.
Example included showing play/pause operation.
2024-05-29 14:53:06 -07:00
Earle F. Philhower, III ec5e62e533 Add Bluetooth audio out (A2DP) on the PicoW (#2174)
Adds a library to run classic Bluetooth A2DP source (output) audio from
the PicoW.  Simple example showing operation and callbacks.

Factor out multiple BT lock/unlock and place in the PicoW variant files.
2024-05-26 14:30:40 -07:00
Earle F. Philhower, III 367200a2c8 Use custom LWIP checksum for ~13% faster checksums (#2172)
Use -O2 only on the LWIP checksum routine, resulting in a speedup of
around 13% (checksumming only, not entire LWIP stack) for 72 add'l bytes
of flash.
2024-05-22 10:37:30 -07:00
Earle F. Philhower, III 11814823ed Add asynchronous I2C read and write operations (#2167)
Fixes #1730

Uses DMA operations to avoid the need to bit-bang or busy wait for I2C operations
that might be very slow.  Optional, adds new API calls to enable.  Simple example
included.
2024-05-21 14:32:12 -07:00
Earle F. Philhower, III e6c7ee7813 Add asynchronous SPI transactions (#2168)
Fixes #1192

Uses DMA operations to avoid the need to bit-bang or busy wait for SPI
operations that might be very slow. Optional, adds new API calls to enable.
Simple example included.
2024-05-21 14:08:36 -07:00
Earle F. Philhower, III dc856dbb1c Update README.md 2024-05-21 09:51:27 -07:00
Christian HalterandChristian Halter c4b1ab81c1 Add Newsan Archi board (#2169)
Co-authored-by: Christian Halter <christian.halter@newsan.com.ar>
2024-05-21 09:51:08 -07:00
Earle F. Philhower, III f33df254f1 Add SPI::setMOSI/setMISO, better match pin names (#2166) 2024-05-20 14:43:55 -07:00
Earle F. Philhower, III 83a6aaca1c Update SDFat to use array transfers (#2164)
Fixes #2163
2024-05-17 13:52:47 -07:00
Earle F. Philhower, III 182af71492 Update StaticMulticore-FreeRTOS.ino (#2161) 2024-05-15 07:57:46 -07:00
Earle F. Philhower, III d4cdb3ea69 Fix LWIP crash on unexpected ping packets (#2159)
When a ping is sent from the Pico, a raw_recv callback is added which
sees all raw incoming packets to detect the response from the ping target.
If while waiting for the target response an external ping packet arrives
this incoming ping request packet will be processed by the
LwipIntfDev<>::_pingCB which will return "0" not processed and which
*should* not change the payload unless it handles the actual packet.

Unfortunately, the 20 byte header was unconditionally stripped off of
the packet before checking if this was our response, changing the
payload address and causing an assertion in LWIP.

Fix by using absolute offsets inside the raw packet for the ping
response checks.

Fixes #2156
Fixes #2149
2024-05-14 17:37:54 -07:00
Earle F. Philhower, III 016bf80e3b Protect againt calling LWIP_Ethernet::begin twice (#2158)
As seen in debug of #2149, if the LwipIntfDev is already _started,
return false for a ::begin() call.

Also, protect netif_add/_remove on the very small possibilty of being
called by LwipIntfDev devices while the CYW43 driver is doing work.
2024-05-13 19:08:38 -07:00
Earle F. Philhower, III d850de15fa Update version 2024-05-13 12:07:12 -07:00
Daniel Egnor 819a73ba5a Fix PID specification for arduino-cli (#2157) 2024-05-13 12:06:31 -07:00
Earle F. Philhower, III 8d4ef5ef8c FreeRTOS: Disable IRQs when task switching disabled (#2155)
Avoids crash seen in #2132
2024-05-10 18:53:45 -07:00
Juraj Andrássy 8673da2505 Ethernet legacy API compatibility layer (#2147)
With example from the Arduino Ethernet library
2024-05-06 10:06:51 -07:00
Earle F. Philhower, III fa58b6987a CI can use custom defines, add ESPHost/WINC tests (#2142)
If a file called `.ci.defines` is present in a directory, apply those
while building the specified sketch.

* Add an lwip_ESPHost test, like the wired Ethernet ones
* Add WINC1500 test and CI hook
* Remove 1 minor warning in WINC build
2024-05-02 13:37:50 -07:00
Earle F. Philhower, III 0b4afab56c Update README.md (#2141)
Add missing boards and WiFi types
2024-05-02 12:42:27 -07:00
Juraj Andrássy 597251d6b5 Add lwIP_WINC1500 - new WiFi driver for ATWINC1500 (#2140) 2024-05-02 12:13:21 -07:00
Earle F. Philhower, III 56e5559357 Minor keyword addition for syntax hilighting (#2139) 2024-05-01 12:27:03 -07:00
Earle F. Philhower, III 0b4394468b Update to latest Joystick upstream (#2138)
Fixes #2136
2024-04-30 12:46:28 -07:00
Dominic PearmanandDominic Pearman 315bfdace1 BTstack: remove superfluous call during setup. (#2137)
Co-authored-by: Dominic Pearman <dominic@phymorous.de>
2024-04-30 10:23:35 -07:00
Calvin Huang 783bee5c49 Add functions to set PDM pins, remove unused pwrPin (#2133)
* functions to set PDM pins

* change pin set method to better match existing libs
2024-04-29 09:32:22 -07:00
Dominic PearmanandDominic Pearman a439028087 BTstack: added function to set scan respone data. (#2134)
Co-authored-by: Dominic Pearman <dominic@phymorous.de>
2024-04-29 08:06:50 -07:00
Earle F. Philhower, III a49bcd4a95 Remove "EXAMPLE" from LWIP header (#2128)
The lwipopts.h file started with the PicoW example one, but no longer
tracks it, so remove the EXAMPLE define guard.
2024-04-26 11:00:11 -07:00
Earle F. Philhower, III 6279b60179 Add missing JSON files for new boards (#2125) 2024-04-25 15:39:09 -07:00
Earle F. Philhower, III a8e6634776 Avoid swapping L/R channels on I2S input (#2124)
Fixes #2123
2024-04-25 11:22:07 -07:00
Earle F. Philhower, III bd8eb9bca2 Shift I2S input data by 1 bit (#2121)
Fixes #2037
2024-04-24 11:20:22 -07:00
Earle F. Philhower, III d53d0033fe Update version 2024-04-22 07:58:48 -07:00
Earle F. Philhower, III d554df7670 Protect W5500/ENC28J60 isLinked() call from IRQ (#2115)
Fixes #2105

W5100 doesn't support isLinked, so no change needed there.
2024-04-19 13:59:11 -07:00
Earle F. Philhower, III 3aaa132e2e Add Waveshare RP2050-PiZero
Fixes #1870
2024-04-19 12:24:46 -07:00
Earle F. Philhower, III c2812e187b Add more verbosity to multicore docs (#2114) 2024-04-19 12:16:25 -07:00
Earle F. Philhower, III 683b62eda7 Add Waveshare RP2040 Matrix (#2113)
Fixes #2033
2024-04-19 12:13:07 -07:00
Earle F. Philhower, III ebbedb3e26 Add Olimex RP2040-Pico30 (#2112)
Same pinout as the plain Pico, just different flash and # of GPIOs

Fixes #2054
2024-04-19 11:49:01 -07:00
Earle F. Philhower, III 72148ffefc Add Sparkfun RP2040 MicroMod (#2111)
Fix #2094
2024-04-19 11:08:08 -07:00
Earle F. Philhower, III 074b952314 Add FatFS and FatFSUSB - Wear-Leveled FTL based FAT filesystem for onboard flash (#2028)
* Add FatFS for onboard flash use/sharing of FAT

* Move all to "fatfs" namespace

The FatFS library defines commonly used names like WORD which could conflict
with user code otherwise.

* Restyle

* FTL-based, wear-leveling FatFS with USB export

Allow using FAT filesystem with onboard flash in a safer, wear-leveled
way and to export the onboard flash to the host as a USB drive for easy
data transfer.

* Update documentation

* Fix submodule reference

* Don't spellehcek ChaN FatFS files

* Disable FTL debugging

* More codespell skips

* Move to latest SPIFTL library

* Allow using raw flash instead of FTL

* Remove unneeded static FIL 4k allocation

* Expose FAT FS format configuration options

* Update documentation

* Remove USB partial flash rewrites

* Remove unneeded dups of FatFS sources

Leave the LICENSE.md and README.md to point to upstream.

* Clean up comments
2024-04-19 10:52:02 -07:00
Kevin Witteveen (MartiniMarter) 11dfb2c913 Add WiFi::beginNoBlock() (#2063) 2024-04-19 10:16:03 -07:00
Earle F. Philhower, III 55ea2b515c Add some missing keywords.txt entries (#2109) 2024-04-19 04:17:35 -07:00
Earle F. Philhower, III 6c22ea3be1 Set creation time on LittleFS directory creation (#2108) 2024-04-18 15:58:06 -07:00
Earle F. Philhower, III 1be28b55e4 Update to Adafruit TinyUSB 3.1.3 (#2043) 2024-04-18 15:49:20 -07:00
Earle F. Philhower, III 48a52e61ce Update to SDFat 2.2.2 release (#2079) 2024-04-18 15:05:36 -07:00
Ha Thach f737be3320 Add native text to TinyUSB Host menu option (#2098) 2024-04-15 09:19:37 -07:00
Juraj Andrássy 2a256f9c25 LwipIntfDev - linkStatus added (#2081) 2024-03-29 09:14:05 -07:00
Jean-Luc Béchennec c62215663f Add 128MHz frequency (#2069) 2024-03-22 08:22:22 -07:00
Dominic Pearman fd6941479d Fixed code block in piouart.rst (#2064) 2024-03-20 03:48:09 -07:00
Aaron Tulino 175cbcdcdf Minor typo (IQR instead of IRQ) (#2060) 2024-03-19 05:25:07 -07:00
Juraj Andrássy 71edeb8d1a lwIP_enc28j60 - add missing end() method (#2055) 2024-03-16 14:10:12 -07:00
Dominic Pearman c90248dc10 Minor corrections to ota.rst (#2053)
Hi,

Just a typo and a couple of wording corrections.
2024-03-13 07:02:29 -07:00
Earle F. Philhower, III a8d1067125 Unswap CTS/RTS enable on SeriaUART (#2052)
Fixes #2047
2024-03-10 13:23:33 -07:00
Juraj Andrássy 22139df33c Enable interrupt-mode for lwIP_ESPHost (#2036) 2024-03-06 12:38:29 -08:00
Juraj Andrássy 9c94bab290 Add RawDev::interruptMode (#2042) 2024-03-06 11:58:37 -08:00
Earle F. Philhower, III ea8874037c Use passed-in SPI on SD.end(true) (#2040)
Fixes #2034
2024-03-05 12:22:01 -08:00
Earle F. Philhower, III 77209a12cc Update SPISlave.cpp (#2021)
Fixes #2019
2024-02-23 09:46:42 -08:00
Earle F. Philhower, III c670f66140 Update version 2024-02-16 13:11:02 -08:00
Earle F. Philhower, III a09ce0d8d0 Update Windows Picotool blob pointers (#2009)
Fixes #2008
2024-02-16 11:38:39 -08:00
Earle F. Philhower, III 795968a8e0 Clean up WIFI local variable MAC size (#2006)
MACs are 6-bytes long, not 8.
2024-02-14 12:17:09 -08:00
Earle F. Philhower, III 01ab02d02a Fix ESPHost WiFi connect without a specified BSSID (#2007)
See https://github.com/earlephilhower/arduino-pico/pull/2001#issuecomment-1944461469
2024-02-14 12:00:06 -08:00
Earle F. Philhower, III 7e73e0b5b4 Can't call get_rand_64 under FreeRTOS (#2004)
Remove the HW random generator call while initting LWIP to avoid the SDK
looping forver due to FreeRTOS exception/timer interrupts.
2024-02-13 12:08:33 -08:00
Earle F. Philhower, III 91c007eb8f Update version 2024-02-12 10:38:24 -08:00
ardnew b29f6b922f Update README.md (#1999)
The `Picoprobe` example showing how to upload to Ubuntu is invalid because Ubuntu does not create or assign users to a `users` group (for many major releases, now). 

The reason the example worked is because the permissions were applied globally, rendering the `GROUP=users` assignment in the rule irrelevant. Hence, this assignment has been dropped.  

The `pico-debug` example has been updated similarly, but it uses a proper group-level rule, and Ubuntu does still use group `plugdev`. 

The reader thus has two good examples of creating `udev` rules.
2024-02-12 10:27:52 -08:00
Earle F. Philhower, III 40e52f84b8 Fix WiFiMulti and ESPhost STA connection w/BSSID (#2001)
WiFiMulti specifies a specific BSSID, in addition to the AP name and
password.  In the WiFi core the BSSID is stored as the raw 6-byte MAC
address, but the ESPHostedFG firmware expects a formatted C-String
(i.e. "ab:cd:ef:01:02:03" instead of {0xab, 0xcd, 0xef, 1, 2, 3})

Convert the raw bytes to the string format expected in the ESP FW.
2024-02-12 10:17:36 -08:00
Earle F. Philhower, III 972b7f53be Fix warning in lwip_ESPHost, add to styler (#1998) 2024-02-11 11:51:16 -08:00
Kevin Witteveen fc894fba0e PWMAudio low bitrate whine fix (DMA pacing timer) (#1996) 2024-02-10 09:17:37 -08:00
Earle F. Philhower, III 929ee98a6c Make W5100 example run on Wiznet w/no changes (#1994)
Use the #define board name to identify when building for the
WIZnet W5100s-EVB-Pico and assign the proper pins and IRQs.
2024-02-09 14:06:28 -08:00
Earle F. Philhower, III 88ccf0c256 Undo FreeRTOS idleOtherCore changes (#1992)
Fixes #1991
2024-02-09 09:46:30 -08:00
Terry Phillips 874b41f549 Update wire.rst (#1990)
Correct buffer size to match Wire.h
2024-02-06 16:27:08 -08:00
LinusHeu fcd47fe170 Update ide.rst (#1989)
Remove outdated(?) info
2024-02-06 15:43:14 -08:00
Earle F. Philhower, III 842ec245ac Add W5100, W5500, and ECN28J60 interrupt-driven mode (#1986)
No polling needed and massively reduces latency by using the GPIO interrupt to
signal the Pico to read a received packet.  Also drops CPU load when no packets
are incoming.
2024-02-06 14:15:37 -08:00
Earle F. Philhower, III a41618fa87 Make Python3 re.split() use a r-string (#1985)
Fixes #1983
2024-02-06 09:49:45 -08:00
Earle F. Philhower, III c095fce5b2 More GH action updates (#1980) 2024-02-02 09:24:22 -08:00
Earle F. Philhower, III 6715e5e6b7 Update version 2024-02-02 09:10:28 -08:00
Earle F. Philhower, III 12702717e3 Undo #1864, fix LWIP offline error (#1979)
Fixes #1973

The periodic LWIP pump/Ethernet packet reader async_context stopped
firing occasionally under high packet loads, causing the LWIP stack
to become unresponsive to any incoming data.

Re-implement the 2-step process for polling (like the CYW43 driver
from the RPI folks does) and undoes #1864 change.
2024-02-01 19:09:09 -08:00
Earle F. Philhower, III 9c66d9737b Update all GitHub actions, remove deprecation warn (#1978) 2024-02-01 11:51:28 -08:00
Earle F. Philhower, III 7f5756c464 Make OpenOCD and Picotool M1 native, too (#1977)
All binaries should now be native on Apple silicon.
2024-02-01 11:43:41 -08:00
Earle F. Philhower, III 1a30113f0d Use ARM Python3 on M1 (#1976) 2024-01-31 09:38:47 -08:00
Earle F. Philhower, III f1170e9d54 Fix Apple M1 installation, add to CI (#1975) 2024-01-31 08:45:10 -08:00
Earle F. Philhower, III 1bf41bcc60 Add native Apple ARM silicon support (#1959)
* Add native Apple ARM silicon M1/M2/M3 support

* Identify Mac ARM in download get.py script

Thanks to the ESP32 `get.py` sources!

* Rebuild M1 w/o using strip
2024-01-30 15:06:52 -08:00
Juraj Andrássy 7180ca3b0c Add ESP32-based WiFi support via lwIP_ESPHost library (#1950) 2024-01-30 14:57:04 -08:00
Earle F. Philhower, III c64a4a58d7 Fix initial SPI startup (#1970)
Clocks were not being set at all after #1934.  Ensure they are by initting
to an impossible 0hz clock on creation and ::end

Fixes #1969
2024-01-28 16:21:48 -08:00
Nerradia 02c272b091 Skip SPI re-init if clock frequency doesn't change (#1934) 2024-01-28 10:27:12 -08:00
Juraj Andrássy 2a74250a51 lwIP_nodriver - end() compilation error fix (#1966) 2024-01-28 06:49:31 -08:00
Pontus Oldberg adb23c1cac Fixed incorrect pinout for SPI interface. (#1951) 2024-01-22 06:16:16 -08:00
Earle F. Philhower, III a99a572bda Add TZ.h database, borrowed from ESP8266 core (#1947) 2024-01-20 15:57:15 -08:00
Earle F. Philhower, III 7ce7dde06a Update README.md (#1946) 2024-01-20 12:51:53 -08:00
Juraj Andrássy fef8d2c384 WiFi - prepare for alternative drivers (#1935) 2024-01-20 12:35:13 -08:00
Pontus Oldberg 916c31d934 Adds iLabs RP2040 Connectivity (LTE/WIFI/BLE) board. (#1936) 2024-01-12 07:32:27 -08:00
Arnoz 403c147fa3 Adding Dude's Cab board (#1933)
Adding Dude's Cab board (rp2040 based board for virtual pinball use)
2024-01-10 14:02:07 -08:00
noqman 915e093564 Change Maker UNO RP2040 to Maker Uno RP2040 and board name in README.md (#1924) 2024-01-05 07:12:24 -08:00
Earle F. Philhower, III 32e74d024e Update version 2024-01-03 18:02:35 -08:00
Earle F. Philhower, III 326697bbe1 Update Mac Picotool/OpenOCD to use bundled dylibs (#1922)
Fixes #1919 by using binaries from https://github.com/earlephilhower/pico-quick-toolchain/pull/37
2024-01-02 18:51:20 -08:00
Earle F. Philhower, III afbba68549 Set AP IP address on ::beginAP
The Arduino WiFi normalization ended up calling the underlying LWIP
::config after the AP was begin, resulting in a failure to set the
IP configuration of the AP.  Move the _wifi.begin() call to after
the IP configuration is set.

Fixes #1989
2024-01-02 18:20:25 -08:00
Steve Bian 042555206b Adds definition for WIRE_INTERFACES_COUNT #1182 (#1921)
* Adds definition for WIRE_INTERFACES_COUNT so those libraries which rely on it can detect and use...

Wire1. e.g. u8g2 will not use Wire1 unless this is (a) defined and (b) >1. This constant is defined
on other cores, e.g. for SAMD based boards.
2024-01-01 18:55:03 -08:00
Richard Teel 24f6302612 Updated listfiles example and added CardInfo example (#1914) 2023-12-27 12:01:06 -08:00
Joseph Duchesne 15eb459df9 Add variants_dir support to pio build, allowing local variants in project repos (#1911) 2023-12-26 09:59:45 -08:00
Ha Thach 3160fde679 Support native USB as host (#1910)
* add a new usbstack menu to use native usb as host

* update tinyusb library to 2.3.0

* skip Host native example in ci
2023-12-25 11:36:07 -08:00
Earle F. Philhower, III 1160d7cd7c Replace ancient "boolean" with "bool" (#1908) 2023-12-20 13:46:07 -08:00
Earle F. Philhower, III 2aa85e3263 Minor LWIPEthernet cleanup (#1906) 2023-12-20 07:49:48 -08:00
erpebe c4f36170d4 Correct calculation of totalBlocks() in SD.h and SDFS.h (#1899) 2023-12-13 12:45:15 -08:00
Earle F. Philhower, III 3068cd0af0 Use SW random generator for all LWIP (#1892) 2023-12-10 16:18:17 -08:00
Earle F. Philhower, III fa390f48af Clean up FreeRTOS header, include add'l APIs (#1891) 2023-12-10 09:48:15 -08:00
Dominic Pearman 0c7454b6f7 Minor typo correction to platformio.rst. (#1889) 2023-12-08 07:42:35 -08:00
Earle F. Philhower, III 500f197c02 Update version 2023-12-06 09:52:23 -08:00
Earle F. Philhower, III 2bf249ffe1 Avoid freezeing the core from LWIP under FreeRTOS (#1884)
Avoid issues with interrupts and priority inversions and other deadlocks
and use a SW based random generator for LWIP when under FreeRTOS.

This means removing any overrides for sleep_until and the two
get_rand_xx calls from the SDK, making things much saner.

Related to #1883, #1872, and other random FreeRTOS lockups.
2023-12-06 09:41:14 -08:00
Dominic PearmanandDominic Pearman 81070a0b3f Minor documentation corrections in platformio.rst. (#1885)
* Corrected minor typo.

* Removed superfluous newline.

---------

Co-authored-by: Dominic Pearman <dominic@phymorous.de>
2023-12-06 06:20:59 -08:00
GUVWAF d45a11f9e7 Disable interrupts first when idling core (#1883) 2023-12-05 11:53:41 -08:00
Earle F. Philhower, III c3a3526aad Fix SPI 16-bit transfers (#1882)
Fixes #1879
Fixes #1874
2023-12-04 17:30:43 -08:00
Earle F. Philhower, III 280fc43731 Fix SPI debug print warning (#1881) 2023-12-04 12:48:49 -08:00
Earle F. Philhower, III 762535faf9 Add documentation about MDNS + FreeRTOS = crash (#1880)
See #1875
2023-12-04 08:57:49 -08:00
GUVWAF 0e4fd0587b Replace std::bind in MDNSResponder for UDP context (#1875) 2023-12-03 08:34:35 -08:00
GUVWAF d2461a14ad Enable interrupts last when resuming other core (#1872) 2023-12-02 10:20:05 -08:00
Juraj Andrássy a1902b5f41 WiFiServer modernization (#1871) 2023-12-02 09:31:39 -08:00
Taylor Alexander aka Sequoia c2d60774af Fix small typo in analog.rst (#1869)
Change "RP20400" to "RP2040"
2023-12-01 15:17:58 -08:00
Earle F. Philhower, III 269c579846 Remove IPv6 compile warning (#1867) 2023-12-01 12:10:16 -08:00
Juraj Andrássy 91183ca22f LwipIntfDev - disconnect()/end() should not clear static IP settings (#1866) 2023-12-01 11:53:01 -08:00
Earle F. Philhower, III 971c235e8d Remove unneeded intermediate async for Ethernet (#1864)
Remove the always pending worker whose job it was to fire another async
worker after a timeout.
2023-12-01 10:50:15 -08:00
Juraj Andrássy abd3547711 WiFi and Ethernet - config static IP auto gw,mask,dns as in Arduino libs (#1862) 2023-12-01 10:24:11 -08:00
Juraj Andrássy 9181ec055d LwipIntfDev - hostByName default value for the timeout parameter (#1858)
to have standard version with two parameters
2023-11-30 08:58:15 -08:00
Juraj Andrássy 58089b1f44 wl_defintions.h wl_enc_type update (#1859) 2023-11-30 08:33:33 -08:00
Juraj Andrássy 4f62e0a4ba LwipIntfDev - added macAddress getter and DNS IP getter and setter (#1856)
and dnsIP(n) getter in WiFiClass too
2023-11-29 13:24:16 -08:00
Richard Teel dbab62c214 Added clearAPList method to WiFiMulti (#1848)
Fixes #1846
2023-11-27 15:35:36 -08:00
Earle F. Philhower, III 6a878cdee8 Only create SPI/Wire instances if variant defined (#1842)
Fixes #1841
2023-11-24 09:56:13 -08:00
noqman cebdb6c917 Add new board variant: Cytron Maker UNO RP2040 (#1838) 2023-11-24 07:13:37 -08:00
Earle F. Philhower, III 39a2bbd788 Update version 2023-11-22 07:59:00 -08:00
Earle F. Philhower, III 199314a463 Fix picotool path for Windows and Mac (#1836)
Fixes #1835
2023-11-21 13:55:32 -08:00
Earle F. Philhower, III 1020023eab Avoid infinite loop in BLE HID send (#1834)
If the BLE connection is severed, don't wait for the needToSend
flag to clear in the HID::send routine since it may never actually
clear unless the BLE connection is restored.

Partial #1817
2023-11-21 11:53:41 -08:00
Abdullah "Hayri" Kırmızıyüz a475c444c5 Added Degz Suibo RP2040 board (#1828) 2023-11-20 09:20:36 -08:00
Marco Scholl 633ac316b4 Add rp2040.getStackPointer and getFreeStack (#1816)
Fixes #1814
2023-11-16 07:57:49 -08:00
Earle F. Philhower, III 4625d2c8ab Avoid memory allocation in Ethernet callbacks (#1815)
std::bind can cause a memory allocation to occur during the periodic
polling interrupt which is a very bad thing.  Use a lambda instead.

Fixes #1812
2023-11-14 10:01:06 -08:00
David Ross Smith db7ba160ae Allow MCLK multiplier to be set on all I2S devices (#1813)
As discussed in #1765.
2023-11-13 06:57:37 -08:00
Earle F. Philhower, III ea936f00e1 Protect W5500/ENC28J60 isLinked from interrupt (#1805)
Fixes #1786
2023-11-12 11:09:09 -08:00
ZinnerC 8ac616e8db Adding capability to enable timeout for I2C (#1793) 2023-11-09 17:37:28 -08:00
Andriy Golovnya 3ce902183e Added RP2040-Eins board (#1804)
* Aggregated several earlier patches in one to add RP2040-Eins board into the project.
- Moved RP2040-ProMini in alphabetical order position.
- Added board description files for RP2040-Eins.
- Added board header file for RP2040-Eins.
- Adjusted unused pins order of RP2040-ProMini to be the same as in RP2040-Eins.
- Added RP2040-Eins to README.md.
- Renamed board files to use underscores to better fit the existing file naming style.

* Updated README.md
2023-11-05 15:32:08 +00:00
James Sleeman c34e602937 Handled already mounted disk. (#1797) 2023-11-05 10:36:56 +00:00
Nico Maas 28e25293a9 Add RAKwireless RAK11300 (#1802) 2023-11-05 10:26:19 +00:00
Krzysztof Heim 319d36531e Update wifintp.rst (#1798)
, instead of .
2023-11-01 16:09:05 +01:00
Andrew DeLisa 5bea328967 Add Sea-Picro board (#1784)
* add sea-picro board

* add configurable board URL to makeboards.py

* update board URL for sea picro

* update note about QT port

* update pin mappings

* fix board vendor/name
2023-10-28 14:29:34 +02:00
rlcamp f5f7267f44 Add Serial.dtr() and Serial.rts() methods (#1779)
* add Serial.dtr() and Serial.rts() methods

* added documentation for Serial.dtr() and Serial.rts()
2023-10-24 19:02:17 +02:00
Johnny Stene a4ad8ae0fd Fix typos in fs.rst (#1781) 2023-10-22 20:10:16 +02:00
rlcamp 44abc19d46 Use __attribute((weak)) for _write() and other stubs called by newlib, so that sketch and library code can provide non-stub implementations (#1777) 2023-10-20 14:58:51 -05:00
Cole Deck 2e93f1c9c8 Clear dirty flag after commiting EEPROM to flash (#1776)
* Clear dirty flag after commiting EEPROM to flash

* Styling: remove whitespace
2023-10-18 17:21:27 -07:00
Earle F. Philhower, III ae6847cf78 Allow changing USB HID poll rate (#1771)
Fixes #1769

Add a weak variable that can be overridden by the user to speed up or
slow down the USB HID polling speed.
2023-10-17 04:38:48 -07:00
Earle F. Philhower, III d42f0ab4b0 Update spi.rst (#1768) 2023-10-12 12:23:10 -07:00
Earle F. Philhower, III 10ddaee94d Add debugging for Bluetooth (#1767)
BTStack requires a special logger registration to enable debugging.  Add
support through the IDE menus.
2023-10-12 08:21:44 -07:00
Earle F. Philhower, III 5678bb9904 Don't break transfer16 into 2 8-bit CS periods (#1764)
With HW chip select enabled, transfer16's 2 individual byte transfers will
actualy deassert CS for a brief instant between bytes.  Avoid this by doing
a single multi-byte (2) tranfer of 16b.
2023-10-11 08:40:17 -07:00
Earle F. Philhower, III 5ecef160d4 Avoid calling spi_set_format during transactions (#1762)
Avoid potential interaction with Pico SDK 1.5.1 update that causes hiccups in
SPI transmissions.

Fixes #1760
2023-10-11 08:22:38 -07:00
Earle F. Philhower, III 52d50da56f Avoid calling spi_set_format during SPI transfers (#1762)
Avoid potential interaction with Pico SDK 1.5.1 update that causes hiccups in
SPI transmissions.  SPI.transfer16 to use 8-bit transfers.

Fixes #1760
2023-10-11 08:22:01 -07:00
Earle F. Philhower, III 47111a6eba Undo BSTstackLib warning (#1758)
Undo #1751
2023-10-08 16:42:08 -07:00
palmerr23 f6a5ef0f85 Update analog.rst (#1756)
Added text about specific dependencies between analogWriteRange and analogWriteFreq
2023-10-07 07:47:20 -07:00
Earle F. Philhower, III 7868ddee42 Allow full 8K stack for both cores, optionally (#1750)
Fixes #1749

Defining a global true `bool core1_separate_stack = true` will separate
the two cores' stacks, with core 0 using the scratch RAM while core 1
will use 8K from the heap.
2023-10-07 07:38:32 -07:00
Earle F. Philhower, III 6a0cc90a4d Update fs.rst (#1754)
Fix #1753
2023-10-05 17:24:04 -07:00
Earle F. Philhower, III 21d212a2ff Clarify LittleFS upload documentation (#1752) 2023-10-04 17:20:01 -07:00
Earle F. Philhower, III bd6b20dedd Mark the BTStackLib as unsupported (#1751)
Per https://github.com/bluekitchen/btstack/issues/529#issuecomment-1746293987
Don't run BTstackLib examples in CI
2023-10-04 09:39:01 -07:00
Earle F. Philhower, III 3cc68f82a2 Fix minor FS documentation issues (#1738) 2023-09-29 21:10:49 -07:00
Earle F. Philhower, III 4f945780e7 Remove redundant variable set in LittleFS lib (#1737) 2023-09-28 17:56:18 -07:00
Earle F. Philhower, III f08ef117b5 Point to new IDE2.x LittleFS uploader (#1736) 2023-09-28 17:47:16 -07:00
Earle F. Philhower, III 41b0686aec Update version 2023-09-22 17:45:32 -07:00
Earle F. Philhower, III 9178ed580e Fix Windows GDB startup with new toolchain binary (#1726)
See https://github.com/earlephilhower/pico-quick-toolchain/issues/30
Fixes #1711
2023-09-22 17:39:44 -07:00
Benjamin Aigner 60e93f3e20 BLE HID composite device support (#1587)
* Adapted all libraries to support multiprotocol HID over BT & BLE

* Added ATT DB depending on setup; still no success with working connection

* Added hids_device from BTStack develop branch as override

* Fixing the GATT handle patching, added working ATT DB

* ran astyle on example

* Updates in BLE implementation; WORKING! (but only if all are activated). Removed sdkoverride again, doesn't work.

* Moved ATT DB handles to correct places

* Finally functioning for Mouse+KBD+Joy, and each individual

* Cleaned up code & ran astyle

* Added sdkoverrides to pull develop functions from BTSTack

* Changed a few typos by BTStack to run codespell successfully

* Ran astyle on sdkoverride files

* Added some #if guards for including BTSTack file only if BT is enabled

* Fixed Feature Report value characteristics handle assignment; fixed too long HID report

* Ran astyle
2023-09-22 17:27:20 -07:00
Dom 7e8fcc5afa Allow Ethernet devices on SPI1 (#1725)
_spiUnit is a reference, and when initialized with SPI, it cannot be changed in the constructor afterwards.
So initialize it in the constructor's declaration.
2023-09-22 11:54:53 -07:00
Earle F. Philhower, IIIandEarle F. Philhower, III 39238a505d Add BOOTSEL documentation (#1722)
Co-authored-by: Earle F. Philhower, III <earle.philhower@kioxia.com>
2023-09-21 08:34:39 -07:00
Earle F. Philhower, III f60b7831c8 Add SPISlave class (#1717)
Allows the Pico to behave as an SPI slave and allows apps to respond
with appropriate data through callbacks.

Fixes #1680
2023-09-17 15:23:03 -07:00
Earle F. Philhower, III c48cdeeea0 Protect SPI transaction start/end from race conditions (#1715)
It would be possible for an IRQ-driven SPI user to fire
while the main app's SPI.beginTransaction was in process.
This would result in incorrect state for the main app since
the IRQ may overwrite some settings that the app already
set.

Disable all IRQs around the begin and end processes to avoid
the possibility.
2023-09-16 13:59:37 -07:00
Earle F. Philhower, III 0be7c98dff Support IRQ disabled SPI transactions (#1714)
Fixes #1147

When SPI.beginTransaction() is called, disable all GPIO IRQs that were
registered using SPI.usingInterrupt().  On SPI.endTransaction(), restore
all the IRQs to their prior state.
2023-09-16 13:31:14 -07:00
Earle F. Philhower, III 0ed1f3dce1 Add WIZnet W5100S-EVB-Pico docs (#1713) 2023-09-15 17:36:13 -07:00
Earle F. Philhower, III f5e8e5b325 Fallthrough LWIP mutex on PicoW wired Ethernet (#1712)
When built for the PicoW but run on a Pico (non-W), fall through to use
the wired Ethernet mutex instead of no mutex at all for LWIP protection.
2023-09-15 09:08:21 -07:00
Earle F. Philhower, III 1f3d5011b2 Support wired network interfaces (W5500, W5100, ENC28J60) (#1703)
Enable use of wired Ethernet modules as first-class LWIP citizens.  All
networking classes like MDNS, WebServer, HTTPClient, WiFiClient, and OTA
can use a wired Ethernet adapter just like built-in WiFi.

Two examples updated to show proper use.

Uses the Async Context support built into the Pico SDK.  When running on the
Pico  it will use the CYW43 async instance.

Uses modified wired Ethernet drivers, thanks Nicholas Humfrey!

Note, the classic, non-LWIP integrated `Ethernet` and related libraries
should still work fine (but not be able to use WebServer/HTTPS/etc.)

Fixes #775
2023-09-14 19:04:39 -07:00
Earle F. Philhower, III 3950b94474 Avoid spurious GCC 7.x warning in platform.io builds (#1709) 2023-09-13 13:28:54 -07:00
Earle F. Philhower, III 99b4aac48b Update version 2023-09-13 13:10:54 -07:00
Earle F. Philhower, III 2bd64b566c GDB/Binutils release-gdb-13.2, GCC still 12.3 (#1706)
Fix #1681 due to breakage of GDB 12.3 in Platform.IO
Remove new Binutils linker warning
2023-09-13 13:09:37 -07:00
wd5gnr 3c93d14b33 Update rp2040.rst (#1704)
isPicoW was missing the rp2040. qualifier.
2023-09-10 13:54:24 -07:00
Earle F. Philhower, III 5639edefee Update wifi.rst (#1702) 2023-09-09 08:09:15 -07:00
Andy2No 585c31ef39 Pin definitions for Pimoroni Tiny 2040 (#1699)
Fixes #1696

Additional pin definitions for Pimoroni Tiny 2040, including using the Green LED element of the RGB LED as the default LED.

There are only 12 external header pins for GPIO, including 4 ADC pins, so there are less options for assigning pins than on a generic Pico RP2040. In particular, there can only be one SPI, and it can't have an SS pin but I've defined GPIO17, as on the pico, because the definition is used in generic / common.h.

BOOTSEL on the Pimoroni Tiny 2040 is connected to GPIO23. I don't know if that has any consequences for implementing reading from BOOTSEL for this board. That may need to be revisited, but it doesn't appear to involve any changes to pins_arduino.h.
2023-09-08 13:16:04 -07:00
Earle F. Philhower, III a385a4c1e5 Update README.md 2023-09-05 15:44:34 -07:00
Earle F. Philhower, III ef257c32b4 Update version 2023-09-05 14:15:03 -07:00
Earle F. Philhower, III 88cd4b5288 Fix Print::print(0ULL) (#1692)
Move to a patched ArduinoCore-API revision.

Fixes #1691
2023-09-03 13:30:12 -07:00
Earle F. Philhower, III ca7ec56f0d Rebuild OTA using GCC 12.3 (#1690)
No functional changes, just for completeness.
2023-09-03 09:58:28 -07:00
Earle F. Philhower, III 74b1156d5e Fix PicoProbe CMSIS restart of second core (#1689)
For some reason `program ... reset" causes OpenOCD to leave the chip in a
state where the 2nd core does not come up properly, leading to problems in
FreeRTOS and others.

Use a separate reset sequence after programming to work around the issue.

Fixes #1687
2023-09-03 09:43:34 -07:00
Odd Stråbø 6ac7ee1a9d Fix gcc search path in make-ota.sh (#1688) 2023-09-03 09:23:50 -07:00
Earle F. Philhower, III 0b56452c35 Rebuild libpico/libbearssl using GCC 12.3 (#1686) 2023-09-01 08:17:31 -07:00
Earle F. Philhower, III b9c66ca0fd Ensure HID reports aren't dropped (#1685)
Fixes #1682

Make the HID report wait up to 500ms for an existing one to go out
before giving up sending a report.
2023-08-31 08:40:38 -07:00
Earle F. Philhower, III faf06a3b70 Avoid obsolete GCC 7.1 note on building WiFi (#1684)
Fixes #1683
2023-08-31 07:42:54 -07:00
Earle F. Philhower, III d0ac7f06b1 Update version 2023-08-30 08:29:26 -07:00
Earle F. Philhower, III e9daaa3589 Add TDM support to I2S (#1673)
Fixes #1066

Implements a simple TDM mode for the I2S output object.
2023-08-30 08:28:34 -07:00
João Vieira 1393811525 Add stdint.h to generic variant common.h (#1677)
Fixes #1676
2023-08-27 13:55:17 -07:00
Andriy Golovnya 2b640669a7 Added RP2040-ProMini board to the project. (#1674) 2023-08-27 11:53:19 -07:00
Earle F. Philhower, III 9d0f0a8d7a Add missing Tiny2040 JSON (#1675) 2023-08-27 10:03:12 -07:00
Earle F. Philhower, III 21d2fb4afa Add Pimoroni Tiny2040 (#1672)
Fixes #1604.  Supports 2MB and 8MB revs
2023-08-25 10:39:56 -07:00
Earle F. Philhower, III ade74986ee GCC 12.3, GDB 12, OpenOCD 0.12, Picotool 1.1.2 (#1670)
Major toolchain update including:
* GCC 12.3
* GDB 12
* OpenOCD 0.12
* Picotool 1.1.2

* Fix MDNS infinite recursion

* Remove legacy Picoprobe

Fixes #1313
Fixes #1650
2023-08-25 09:56:52 -07:00
LinusHeu 73722b5c87 Fix I2S stop/start race condition #1656 (#1659)
Fixes  #1656
2023-08-22 08:40:23 -07:00
Earle F. Philhower, III 456b474a48 Allow re-setting identical pins without panic() (#1655)
Setting a pin to the current value is a no-op, not fatal.

Fixes #1652
2023-08-21 08:52:49 -07:00
Jimmy Hedman f11cc4db69 Make MDNS compile with IPv6 enabled (#1651) 2023-08-20 14:47:23 -07:00
Matt 8c2901da13 Update license.rst (#1648)
fixed typo in license.rst
2023-08-17 09:33:31 -07:00
LinusHeu ca4637d14d SPI debugging: tiny fix & log actual baudrate (#1641) 2023-08-10 07:39:36 -07:00
Earle F. Philhower, III 313caf406e Update version 2023-08-04 17:09:07 -07:00
Rastloser 25052fedd6 Update platform.txt to require auto-discovery and serial-monitor (#1631)
Fixes #1619

Requiring the auto-discovery tool and serial monitor if they have not already been included by other boards (namely if AVR cores have been uninstalled in the IDE).
2023-08-04 16:31:47 -07:00
Kattni 678cd2c4b9 Add Adafruit Metro RP2040 (#1630) 2023-08-04 15:49:05 -07:00
Dryw Wade 1231317c9c Fix race condition between WiFi receive and consume (#1614)
If another packet comes in between freeing `_rx_buf` and setting `_rx_buf` to 0, that new packet could get put into the same memory address and get concatenated to itself, which leads to an infinite loop.
New solution assigns a temp pointer, sets `rx_buf` to 0, then frees the memory, which guarantees `_rx_buf` always points to valid data.
2023-08-03 20:10:24 -07:00
Earle F. Philhower, III cd76f030cb Update serial.rst 2023-08-03 11:10:01 -07:00
Earle F. Philhower, III 36839cb190 Update serial.rst, add ignoreFlowControl docs (#1626) 2023-08-02 17:06:42 -07:00
marklinmax 23e68973c0 Add SerialUSB::ignoreFlowControl() method (#1624)
Fixes #1620
2023-08-02 17:00:26 -07:00
Patrick Van Oosterwijck 70af32eead Add new board Silicognition RP2040-Shim (#1623)
Board documentation can be found here:
https://silicognition.com/Products/rp2040-shim/

Signed-off-by: Patrick Van Oosterwijck <patrick@silicognition.com>
2023-08-02 16:48:55 -07:00
Maximilian Gerhardt 3cc5ac14ff Fix PlatformIO intellisense (#1616)
The `_idedata` has been changed to `__idedata` in newer PlatformIO core versions per https://github.com/platformio/platformio-core/commit/158aabbdf23ed1ff8f5e3f01fb4ef1723a78d3bb. This change has broken the logic to expand out the `-iprefix PATH @INCLUDEFILE` argument into its individual include paths, causing Intellisense breakages on some VSCode systems and other IDEs that didn't handle these arguments correctly or in which the path was corrupted.
2023-07-29 13:48:29 -07:00
Earle F. Philhower, III 4fd8e41db1 Update version 2023-07-28 10:35:47 -07:00
Earle F. Philhower, III 5fd4736d8f Handle swapped Wire IRQs properly (#1608)
When we swap the Wire objects, we need the i2c0 IRQ shim to call
Wire1.onIRQ, not the usual Wire.onIRQ.  Same for i2c1 IRQ shim.

Fixes #1607
2023-07-26 15:40:07 -07:00
Earle F. Philhower, III 67a07edccc Fix FS upload crash (#1598)
Thanks to @pietglas for finding and fixing.  See #1590 for more info.
2023-07-17 15:17:31 -07:00
Earle F. Philhower, III 1dc0872818 Remove obsolete refs to ATOMIC_FS_UPDATE (#1597)
See #1590
2023-07-14 14:58:21 -07:00
Pontus Oldberg ead0728a57 Adds new Challenger WiFi6/BLE5 board to the mix. (#1595) 2023-07-14 08:58:06 -07:00
Jack Burgess 14eb8d3906 Update ota.rst (#1592)
Spelling mistakes and grammatical corrections
2023-07-14 08:10:13 -07:00
LinusHeu 4c90b295b2 Fix: 'I2S::operator=(const I2S&)' is implicitly (#1588) 2023-07-12 03:26:43 -07:00
Earle F. Philhower, III 43aa0427ea Reapply #1548 (#1582) 2023-07-07 13:38:04 -07:00
palmerr23 cc5d1779a3 Add MCLK support for I2S, optimize clocks for jitter-free playback (#1555)
Fixes #1065
2023-07-07 13:10:32 -07:00
Earle F. Philhower, III 0f437e4db2 Remove leftover debug printf in LWIP_Ethernet (#1572)
See #1161
2023-07-02 13:12:22 -07:00
Max 3778fbb833 Add ArtronShop RP2 Nano board (#1567) 2023-06-28 09:16:05 -07:00
Ha Thach 4b6f3d05e1 BREAKING: Change default debug_script to cmsis-dap (#1565)
The PicoProbe firmware has only supported  CMSIS-DAP for some time, make it the default debugging option to work around IDE 2.0 issues.
2023-06-27 09:31:58 -07:00
Earle F. Philhower, III 9e89dda900 Ensure 64bit math for SD card FSInfo (#1553)
Fixes #1552

Ensure that 64 bit multiplication is done when calculating the total size
available and used for SDFS.
2023-06-23 08:25:36 -07:00
Tristan Rowley 91e69e2a1a Add Pimoroni Plasma RP2040 support (#1556) 2023-06-22 12:58:57 -07:00
Mohammed Chamma 21d1a285dc Fix typo in fs.rst regarding info64 (#1551) 2023-06-20 13:00:36 -07:00
LinusHeu 0e579792d1 I2S: Don't consider _isHolding when it's an output (#1548) 2023-06-19 07:54:34 -07:00
Earle F. Philhower, III 20cabe824f Update version 2023-06-17 19:40:40 -07:00
Earle F. Philhower, III 0847d3dbb0 Update to Pico-SDK 1.5.1 (#1539)
This should reduce the `git submodule update` space required as well as
avoid the max-path-len errors under Windows in most cases.
2023-06-15 17:05:04 -07:00
Paint Your Dragon fa7c287f07 Linker tweaks for RAM-resident PicoDVI library functions (#1541) 2023-06-15 15:01:02 -07:00
hreintke 9b3032cd58 WebServer: Solve HTTP request delay by dropping idle connections (#1537)
Serve next wificlient (http_request) if current client does not have data
2023-06-15 07:39:02 -07:00
Earle F. Philhower, III 50646b9e70 Update httpclient.rst (#1538) 2023-06-15 07:20:15 -07:00
Earle F. Philhower, III 3d6a1c7b41 Enable proper reuse of PIO programs (#1526)
* Enable proper reuse of PIO programs

Rewrite the PIOProgram helper class to properly re-use loaded programs
and to try to re-use loaded instructions before allocating a new PIO
program.

Supersedes #1524

* Less copy-pasta
2023-06-13 04:42:37 -07:00
Earle F. Philhower, III 5b76b0668b Addition ABM checks in PWMAudio and ADCInput (#1530)
Handle the case where the DMA manager is unable to completely allocate
needed resources (DMA channels or memory) and return `false` in ::begin()
2023-06-12 15:20:52 -07:00
Earle F. Philhower, III d18f8dce2f I2S check for failure of ARB and PIO allocation (#1528)
Per https://github.com/earlephilhower/arduino-pico/pull/1524#issuecomment-1587885054
2023-06-12 12:24:08 -07:00
Earle F. Philhower, III c64cdc14b6 Call I2S::end() in I2S destructor (#1527)
Per https://github.com/earlephilhower/arduino-pico/pull/1524#issuecomment-1587562257
2023-06-12 12:12:50 -07:00
Earle F. Philhower, III cc800713bd Minor clean up includes (#1520) 2023-06-10 20:42:28 -07:00
Linar Yusupov c6a0d6ecfe Fix for invalid __channelCount in ~AudioBufferManager() (#1519) 2023-06-10 10:51:19 -07:00
Earle F. Philhower, III c6426ae461 Update RP2040Support.h (#1518) 2023-06-09 07:59:05 -07:00
Earle F. Philhower, III 7b04a033b3 Update rp2040.rst (#1515) 2023-06-08 09:49:57 -07:00
madias123 8e4008bf12 Add rebootToBootloader to reboot to bootloader from code (#1514) 2023-06-08 09:48:35 -07:00
Earle F. Philhower, III 7eb176c0b4 Update version 2023-06-07 18:06:55 -07:00
hreintke 3f475ac68c CoreMutex add portYieldFromISR for FreeRTOS (#1484) 2023-06-07 06:59:10 -07:00
Earle F. Philhower, III 5204dab99b Fix CoreMutex FreeRTOS ISR logic (#1510) 2023-06-07 00:15:41 -07:00
Earle F. Philhower, III 273fb84dc5 Update to Adafruit TinyUSB 2.2.1 (#1511)
Fixes #1509
2023-06-07 00:05:12 -07:00
LinusHeu fe3af4d98b Update i2s.rst + typo (#1504) 2023-06-05 13:10:04 -07:00
Earle F. Philhower, III 9aade5bb24 Update adc.rst (#1502) 2023-06-05 02:15:09 -07:00
Earle F. Philhower, III 3c408dab7c AudioBufferManager(I2s, PWMAudio, ADCInput) clicking fix (#1500)
The ABM had an off-by-one error in the DMA buffer swapover.  Instead of
setting the DMA address to the newly added buffer in active[], it set it
to the buffer that was currently running.

This would effectively disable the ping-pong and cause clicks/lost data.

Fixes #1491
2023-06-04 18:40:29 -07:00
Earle F. Philhower, III 2888f4d03d I2S::available/availableForWrite() returns bytes (#1499)
Per the Arduino documentation, I2s::available should return bytes free,
not samples.  Adjust accordingly.
2023-06-04 16:38:12 -07:00
Earle F. Philhower, III f57b5bc762 Add I2S::getOverUnderflow() (#1497)
See #1491.  Thanks @LinusHeu
2023-06-04 14:21:02 -07:00
Earle F. Philhower, III 35a4d57360 Fix I2s::available/availableForWrite() (#1496)
Return the actual number of samples that can be read/written, not the
number of 32-bit values there is space for.
2023-06-04 14:10:53 -07:00
Earle F. Philhower, III 579e366bcf Fix serial reset hang under FreeRTOS (#1495)
The serial port reset logic was calling `sleep_ms()` which ended up doing
a task switch...while the other core was frozen and everything was supposed
to be locked.

Use `busy_wait_ms()` which is a tight loop to delay in the reset portion.

Fixes #1486
2023-06-04 13:28:11 -07:00
hreintke db4f79448d CoreMutex freeRTOS Mutex acquire properly (#1481)
Since FreeRTOS has real tasks and mutexes with support for priority bumping, actually always try and take a `CoreMutex` instead of seeing if someone else already has it and aborting immediately.

This fix helps ensure things like Serial output in a multi-task system won't get lost.
2023-06-04 13:12:30 -07:00
LinusHeu 45bbcca207 AudioBufferManager: Make dma_claim_unused_channel() not panic (#1487) 2023-05-30 15:51:07 -07:00
Dominic PearmanandDominic Pearman 8e961a5667 Added setup overload to pass name. (#1483)
Co-authored-by: Dominic Pearman <dominic@phymorous.de>
2023-05-27 10:40:24 -07:00
Ivan Kravets 64ad69c247 Temporary disable publishing to the PIO registry (#1476)
See RPI's CEO comment https://github.com/platformio/platform-raspberrypi/pull/36#issuecomment-1560504425
2023-05-26 10:24:28 -07:00
Jan 4def2f219c Implement the BD_ADDR(char * address_string) constructor. (#1440)
* Implement the BD_ADDR(char * address_string) constructor.

* Updating implementation to use sscanf.

There is an extra step after the sscanf that checks that we got
six bytes back and if we did not, it will set all bytes in the
address to zero.

* Example using BD_ADDR(const char * address_string)

This example shows how BD_ADDR(const char * address_string) can
be used to create BD_ADDR objects to use for comparisons etc.

* Update LEDeviceScanner.ino formatting
2023-05-25 06:54:24 -07:00
Earle F. Philhower, III b2b4b2d71d Update version 2023-05-23 17:57:38 -07:00
Earle F. Philhower, III e93bd14ef5 Generate warnings if Pico STDIO init called (#1467)
Warn the user that the Pico SDK STDIO calls (stdio_init_all, stdio_usb_init,
stdio_uart_init) are not supported or needed at compile time.  See multiple
issues #1433 #1347 #1273 #1251 and others.
2023-05-23 17:28:57 -07:00
Earle F. Philhower, III 652f9f9eda Fix FreeRTOS CoreMutex shim to handle ISRs (#1442)
* Fix FreeRTOS CoreMutex shim to handle ISRs

Automatically check, when in FreeRTOS, if we're in an ISR and
if so call the correct mutex grab.

Thanks to @caveman99 for finding and proposing a solution!

Fixes #1441

* Fix the CoreMutex destructor, too
2023-05-23 10:12:52 -07:00
Earle F. Philhower, III cac9eb0cd7 BREAKING: Swap Wire1 and Wire in Adafruit Feather (#1468)
Fixes #1465

The Adafruit Feather came onboard before the Wire swapping was supported
in the core, so it's backwards from the real definition.  Now that swapping is
supported, fix it to match the rest of the boards.
2023-05-23 09:57:28 -07:00
LinusHeu 3b4fb295ea Fix I2S::write(const uint8_t *buffer, size_t size) (#1461)
According to this: https://github.com/earlephilhower/arduino-pico/discussions/1450
2023-05-20 11:33:50 -07:00
Jean-Luc Béchennec a1ae61b5b1 BT Serial connection docs for Mac (#1459) 2023-05-20 10:56:06 -07:00
355abd8c57 Add setInverted() options to SerialPIO (#1451)
Call `SerialPIO::setInverted(txinv, rxinv)` before `SerialPIO::begin()` to enable.

---------

Co-authored-by: Mykle Hansen <mykle@mykle.com>
Co-authored-by: Earle F. Philhower, III <earlephilhower@yahoo.com>
2023-05-19 16:30:26 -07:00
Earle F. Philhower, III b57ac66815 Cleanup legacy includes (#1452) 2023-05-16 23:47:17 -07:00
Earle F. Philhower, III a851a928d2 Merge latest FreeRTOS/SMP upstream branch (#1449)
Update to head of upstream FreeRTOS/SMP branch.  Very minor changes.

Remove the custom getreent implementation, use the one that was defined
in the upstream FreeRTOS/smp branch (callback related vs. static vars).
2023-05-16 12:13:51 -07:00
Earle F. Philhower, III 16c2e8e454 Clean up FreeRTOS, remove core freeze hacks (#1448) 2023-05-15 19:52:38 -07:00
Earle F. Philhower, III ae908c8e9b Use real FreeRTOS tasks to idle core during flash (#1444)
Fixes #1439

Use a real FreeRTOS task, at the highest priority, to idle the other core
while doing flash accesses.

The USB stack seems to have some timing dependent bits which get broken
if FreeRTOS switches out the current task when it's running.  Avoid any
issue by disabling preemption on the core for all tud_task calls.

The PendSV handler disable flag can live completely inside the FreeRTOS
variant port, so remove any reference to it in the main core.

Tested using Multicode-FreeRTOS, #1402 and #1441

The USB FIFO interrupts were still being serviced even when the core was
frozen, leading to crashes.  Explicitly shut off IRQs on both the victim
and the initiator core when freezing.

Removed the need for hack __holdUpPendSV flag
2023-05-15 18:10:30 -07:00
Earle F. Philhower, III 723c81470a Update contrib.rst 2023-05-15 10:09:30 -07:00
Alessandro Ranellucci a7905fba3e Add Arduino CLI installation instructions (#1447) 2023-05-15 09:29:12 -07:00
Earle F. Philhower, III 6e52b72523 Update macro for detecting this core in contributing docs (#1436) 2023-05-11 09:45:34 -07:00
git2212 ef4ec4185a Add dummy Serial implementation when NO_USB defined (#1438)
Fixes #1434
2023-05-11 09:45:01 -07:00
422 changed files with 144972 additions and 2659 deletions
+25 -21
View File
@@ -18,21 +18,21 @@ jobs:
name: Check spelling
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
- name: Run codespell
uses: codespell-project/actions-codespell@master
with:
skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server,./ota/uzlib,./libraries/http-parser/lib,./libraries/WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino,./libraries/HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino,./.git
ignore_words_list: ser,dout
skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server,./ota/uzlib,./libraries/http-parser/lib,./libraries/WebServer/examples/HelloServerBearSSL/HelloServerBearSSL.ino,./libraries/HTTPUpdateServer/examples/SecureBearSSLUpdater/SecureBearSSLUpdater.ino,./.git,./libraries/FatFS/lib/fatfs,./libraries/FatFS/src/diskio.h,./libraries/FatFS/src/ff.cpp,./libraries/FatFS/src/ffconf.h,./libraries/FatFS/src/ffsystem.cpp,./libraries/FatFS/src/ff.h,./libraries/lwIP_WINC1500/src/driver,./libraries/lwIP_WINC1500/src/common,./libraries/lwIP_WINC1500/src/bus_wrapper,./libraries/lwIP_WINC1500/src/spi_flash
ignore_words_list: ser,dout,shiftIn,acount
# Consistent style
astyle:
name: Style, Boards, Package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: false
- name: Check package references
@@ -59,15 +59,15 @@ jobs:
matrix:
chunk: [0, 1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
@@ -87,15 +87,15 @@ jobs:
name: Build TinyUSB Examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
@@ -113,15 +113,15 @@ jobs:
name: Windows
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Cache Windows toolchain
id: cache-windows
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
@@ -144,17 +144,20 @@ jobs:
# Single build under macOS to ensure the Mac toolchain is good.
build-mac:
name: Mac
runs-on: macOS-12
strategy:
matrix:
os: [macOS-12, macOS-14]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Cache Mac toolchain
id: cache-mac
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
@@ -165,6 +168,7 @@ jobs:
mod: 500
rem: 1
run: |
uname -a
cd pico-sdk
git submodule update --init
cd ..
@@ -175,7 +179,7 @@ jobs:
name: Build PlatformIO Examples
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: 'true'
- name: Initialize needed submodules
@@ -186,19 +190,19 @@ jobs:
git submodule update --init
cd ../..
- name: Cache pip
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install PlatformIO
+15 -15
View File
@@ -9,28 +9,28 @@ jobs:
name: Update master JSON file
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
- name: Cache pip
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Cache PlatformIO
uses: actions/cache@v3
- uses: actions/setup-python@v5
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio
python-version: '3.x'
# - name: Cache PlatformIO
# uses: actions/cache@v4
# with:
# path: ~/.platformio
# key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
# - name: Install PlatformIO
# run: |
# python -m pip install --upgrade pip
# pip install --upgrade platformio
- name: Deploy updated JSON
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
@@ -43,5 +43,5 @@ jobs:
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
# Upload to Platform.IO
curl -LO $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/$TAG/rp2040-$TAG.zip
pio package publish rp2040-$TAG.zip --non-interactive
# curl -LO $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/releases/download/$TAG/rp2040-$TAG.zip
# pio package publish rp2040-$TAG.zip --non-interactive
+2 -2
View File
@@ -15,11 +15,11 @@ jobs:
name: Package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- uses: actions/setup-python@v4
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Build package JSON
+6
View File
@@ -37,3 +37,9 @@
[submodule "libraries/http_parser/lib/http-parser"]
path = libraries/http-parser/lib/http-parser
url = https://github.com/nodejs/http-parser.git
[submodule "libraries/FatFS/lib/SPIFTL"]
path = libraries/FatFS/lib/SPIFTL
url = https://github.com/earlephilhower/SPIFTL.git
[submodule "libraries/AsyncUDP"]
path = libraries/AsyncUDP
url = https://github.com/earlephilhower/AsyncUDP.git
+65 -48
View File
@@ -4,7 +4,7 @@
Raspberry Pi Pico Arduino core, for all RP2040 boards
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.
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 12.3/Newlib 4.0 toolchain.
# Documentation
See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for more detailed usage information.
@@ -21,20 +21,27 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
* Adafruit ItsyBitsy RP2040
* Adafruit KB2040
* Adafruit Macropad RP2040
* Adafruit Metro RP2040
* Adafruit QTPy RP2040
* Adafruit STEMMA Friend RP2040
* Adafruit Trinkey RP2040 QT
* Arduino Nano RP2040 Connect
* ArtronShop RP2 Nano
* Breadstick Raspberry
* BridgeTek IDM2040-7A
* Cytron Maker Pi RP2040
* Cytron Maker Nano RP2040
* Cytron Maker Uno RP2040
* DatanoiseTV PicoADK+
* Degz Suibo RP2040
* DeRuiLab FlyBoard2040 Core
* DFRobot Beetle RP2040
* ElectronicCats Hunter Cat NFC
* ExtremeElectronics RC2040
* GroundStudio Marble Pico
* Invector Labs Challenger RP2040 WiFi
* Invector Labs Challenger RP2040 WiFi/BLE
* Invector Labs Challenger RP2040 WiFi6/BLE
* Invector Labs Challenger NB RP2040 WiFi
* Invector Labs Challenger RP2040 LTE
* Invector Labs Challenger RP2040 LoRa
@@ -44,12 +51,23 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
* Invector Labs RPICO32
* Melopero Cookie RP2040
* Melopero Shake RP2040
* METE HOCA Akana R1
* Neko Systems BL2040 Mini
* Olimex RP2040-Pico30
* Newsan Archi
* nullbits Bit-C PRO
* Pimoroni PGA2040
* Pimoroni Plasma2040
* Pimoroni Tiny2040
* RAKwireless RAK11300
* Redscorp RP2040-Eins
* Redscorp RP2040-ProMini
* Sea-Picro
* Seeed Indicator RP2040
* Seeed XIAO RP2040
* Silicognition RP2040-Shim
* Solder Party RP2040 Stamp
* SparkFun MicroMod RP2040
* SparkFun ProMicro RP2040
* SparkFun Thing Plus RP2040
* uPesy RP2040 DevKit
@@ -60,11 +78,43 @@ Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blo
* Waveshare RP2040 Plus
* Waveshare RP2040 LCD 0.96
* Waveshare RP2040 LCD 1.28
* Waveshare RP2040 Matrix
* Waveshare RP2040 PiZero
* WIZnet W5100S-EVB-Pico
* WIZnet W5500-EVB-Pico
* WIZnet WizFi360-EVB-Pico
* Generic (configurable flash, I/O pins)
# Features
* Adafruit TinyUSB Arduino (USB mouse, keyboard, flash drive, generic HID, CDC Serial, MIDI, WebUSB, others)
* Bluetooth on the PicoW (Classic and BLE) with Keyboard, Mouse, Joystick, and Virtual Serial
* Bluetooth Classic and BLE HID master mode (connect to BT keyboard, mouse, or joystick)
* Generic Arduino USB Serial, Keyboard, Joystick, and Mouse emulation
* WiFi (Pico W, ESP32-based ESPHost, Atmel WINC1500)
* Ethernet (Wired W5500, W5100, ENC28J60)
* HTTP client and server (WebServer)
* SSL/TLS/HTTPS
* Over-the-Air (OTA) upgrades
* Filesystems (LittleFS and SD/SDFS)
* Multicore support (setup1() and loop1())
* FreeRTOS SMP support
* Overclocking and underclocking from the menus
* digitalWrite/Read, shiftIn/Out, tone, analogWrite(PWM)/Read, temperature
* Analog stereo audio in using DMA and the built-in ADC
* Analog stereo audio out using PWM hardware
* Bluetooth A2DP audio source (output) and sink (input) on the PicoW
* USB drive mode for data loggers (SingleFileDrive, FatFSUSB)
* Peripherals: SPI master/slave, Wire(I2C) master/slave, dual UART, emulated EEPROM, I2S audio input/output, Servo
* printf (i.e. debug) output over USB serial
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
* Servos
* Tones
* I2S Input
* I2S Output
* Software UARTs (Serial ports)
# Installing via Arduino Boards Manager
## Windows-specific Notes
Please do not use the Windows Store version of the actual Arduino application
@@ -162,11 +212,14 @@ Under Windows a local admin user should be able to access the Picoprobe port aut
To set up user-level access to Picoprobes on Ubuntu (and other OSes which use `udev`):
````
echo 'SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", GROUP="users", MODE="0666"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
echo 'SUBSYSTEMS=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", MODE="0666"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
sudo udevadm control --reload
sudo udevadm trigger -w -s usb
````
The first line creates a file with the USB vendor and ID of the Picoprobe 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.
The first line creates a device file in `/dev` matching the USB vendor and product ID of the Picoprobe, and it enables global read+write permissions. The second line causes `udev` to load this new rule. The third line requests the kernel generate "device change" events that will cause our new `udev` rule to run.
If for some reason the device file does not appear, manually unplug and re-plug the USB connection and check again. The output from `dmesg` can reveal useful diagnostics if the device file remains absent.
Once Picoprobe permissions are set up properly, then select the board "Raspberry Pi Pico (Picoprobe)" in the Tools menu and upload as normal.
@@ -175,13 +228,16 @@ Once Picoprobe permissions are set up properly, then select the board "Raspberry
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`):
To set up group-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
sudo udevadm trigger -w -s usb
````
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.
The first line creates a device file in `/dev` that matches all CMSIS-DAP adapters, and it enables read+write permissions for members of the `plugdev` group. The second line causes `udev` to load this new rule. The third line requests the kernel generate "device change" events that will cause our new `udev` rule to run.
If for some reason the device file does not appear, manually unplug and re-plug the USB connection and check again. The output from `dmesg` can reveal useful diagnostics if the device file remains absent.
Once CMSIS-DAP permissions are set up properly, then select the board "Raspberry Pi Pico (pico-debug)" in the Tools menu.
@@ -190,47 +246,6 @@ When first connecting the USB port to your PC, you must copy [pico-debug-gimmeca
# 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)
* Bluetooth on the PicoW (Classic and BLE) with Keyboard, Mouse, Joystick, and Virtual Serial
* Generic Arduino USB Serial, Keyboard, Joystick, and Mouse emulation
* WiFi (Pico W)
* HTTP client and server (WebServer)
* SSL/TLS/HTTPS
* Over-the-Air (OTA) upgrades
* Filesystems (LittleFS and SD/SDFS)
* Multicore support (setup1() and loop1())
* FreeRTOS SMP support
* Overclocking and underclocking from the menus
* digitalWrite/Read, shiftIn/Out, tone, analogWrite(PWM)/Read, temperature
* Analog stereo audio in using DMA and the built-in ADC
* Analog stereo audio out using PWM hardware
* USB drive mode for data loggers (SingleFileDrive)
* Peripherals: SPI master, Wire(I2C) master/slave, dual UART, emulated EEPROM, I2S audio input, I2S audio output, Servo
* printf (i.e. debug) output over USB serial
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
* Servos
* Tones
* I2S Input
* I2S Output
* Software UARTs (Serial ports)
# Tutorials from Across the Web
Here are some links to coverage and additional tutorials for using `arduino-pico`
* The File:: class is taken from the ESP8266. See https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html
* Arduino Support for the Pi Pico available! And how fast is the Pico? - https://youtu.be/-XHh17cuH5E
* Pre-release Adafruit QT Py RP2040 - https://www.youtube.com/watch?v=sfC1msqXX0I
* Adafruit Feather RP2040 running LCD + TMP117 - https://www.youtube.com/watch?v=fKDeqZiIwHg
* Demonstration of Servos and I2C in Korean - https://cafe.naver.com/arduinoshield/1201
* Home Assistant Pico W integration starter project using Arduino - https://github.com/daniloc/PicoW_HomeAssistant_Starter
* Tutorials for the Raspberry Pi Pico / uPesy RP2040 DevKit board
- English version: https://www.upesy.com/blogs/tutorials/best-tutorials-for-rpi-pi-pico-with-arduino-code
- French version: https://www.upesy.fr/blogs/tutorials/best-tutorials-for-rpi-pi-pico-with-arduino-code
# Contributing
If you want to contribute or have bugfixes, drop me a note at <earlephilhower@yahoo.com> or open an issue/PR here.
# Licensing and Credits
* 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.
@@ -240,13 +255,15 @@ If you want to contribute or have bugfixes, drop me a note at <earlephilhower@ya
* [UF2CONV.PY](https://github.com/microsoft/uf2) is by Microsoft Corporation and licensed under the MIT license.
* Networking and filesystem code taken from the [ESP8266 Arduino Core](https://github.com/esp8266/Arduino) and licensed under the LGPL.
* DHCP server for AP host mode from the [Micropython Project](https://micropython.org), distributed under the MIT License.
* [FreeRTOS](https://freertos.org) is Copyright Amazon.com, Inc. or its affiliates, and distributed under the MIT license.
* [FreeRTOS](https://freertos.org) is copyright Amazon.com, Inc. or its affiliates, and distributed under the MIT license.
* [lwIP](https://savannah.nongnu.org/projects/lwip/) is (c) the Swedish Institute of Computer Science and licenced under the BSD license.
* [BearSSL](https://bearssl.org) library written by Thomas Pornin, is distributed under the [MIT License](https://bearssl.org/#legal-details).
* [UZLib](https://github.com/pfalcon/uzlib) is copyright (c) 2003 Joergen Ibsen and distributed under the zlib license.
* [LEAmDNS](https://github.com/LaborEtArs/ESP8266mDNS) is copyright multiple authors and distributed under the MIT license.
* [http-parser](https://github.com/nodejs/http-parser) is copyright Joyent, Inc. and other Node contributors.
* WebServer code modified from the [ESP32 WebServer](https://github.com/espressif/arduino-esp32/tree/master/libraries/WebServer) and is copyright (c) 2015 Ivan Grokhotkov and others
* WebServer code modified from the [ESP32 WebServer](https://github.com/espressif/arduino-esp32/tree/master/libraries/WebServer) and is copyright (c) 2015 Ivan Grokhotkov and others.
* [Xoshiro-cpp](https://github.com/Reputeless/Xoshiro-cpp) is copyright (c) 2020 Ryo Suzuki and distributed under the MIT license.
* [FatFS low-level filesystem](http://elm-chan.org/fsw/ff/) code is Copyright (C) 2024, ChaN, all rights reserved.
-Earle F. Philhower, III
+8433 -729
View File
File diff suppressed because it is too large Load Diff
+12 -1
View File
@@ -28,7 +28,7 @@
#include "api/ArduinoAPI.h"
#include "api/itoa.h" // ARM toolchain doesn't provide itoa etc, provide them
#include <pins_arduino.h>
#include "hardware/gpio.h" // Required for the port*Register macros
#include <hardware/gpio.h> // Required for the port*Register macros
#include "debug_internal.h"
#include <RP2040.h> // CMSIS
@@ -129,3 +129,14 @@ constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) {
return i < N ? (1L << a[i]) | __bitset(a, i + 1) : 0;
}
#endif
// Warn users trying to use Pico SDK's STDIO implementation
#include <pico/stdio.h> // Ensure it won't be re-included elsewhere
#undef stdio_uart_init
#define stdio_uart_init(...) static_assert(0, "stdio_uart_init is not supported or needed. Either use Serial.printf() or set the debug port in the IDE to Serial/1/2 and use printf(). See https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1540354673 and https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1546783109")
#undef stdio_init_all
#define stdio_init_all(...) static_assert(0, "stdio_init_all is not supported or needed. Either use Serial.printf() or set the debug port in the IDE to Serial/1/2 and use printf(). See https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1540354673 and https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1546783109")
#undef stdio_usb_init
#define stdio_usb_init(...) static_assert(0, "stdio_usb_init is not supported or needed. Either use Serial.printf() or set the debug port in the IDE to Serial/1/2 and use printf(). See https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1540354673 and https://github.com/earlephilhower/arduino-pico/issues/1433#issuecomment-1546783109")
+87
View File
@@ -0,0 +1,87 @@
/*
Enable BTStack debugging to a Print-able object
Copyright (c) 2023 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(ENABLE_CLASSIC) || defined(ENABLE_BLE)
#include <Arduino.h>
#include <btstack.h>
#include <hci_dump.h>
static Print *_print;
static void _log_packet(uint8_t packet_type, uint8_t in, uint8_t *packet, uint16_t len) {
if (!_print) {
return;
}
_print->printf("[BT @%lu] ", millis());
switch (packet_type) {
case HCI_COMMAND_DATA_PACKET:
_print->printf("CMD => ");
break;
case HCI_EVENT_PACKET:
_print->printf("EVT <= ");
break;
case HCI_ACL_DATA_PACKET:
_print->printf("ACL %s ", in ? "<=" : "=>");
break;
case HCI_SCO_DATA_PACKET:
_print->printf("SCO %s ", in ? "<=" : "=>");
break;
case HCI_ISO_DATA_PACKET:
_print->printf("ISO %s ", in ? "<=" : "=>");
break;
case LOG_MESSAGE_PACKET:
_print->printf("LOG -- %s\n", (char*) packet);
return;
default:
_print->printf("UNK(%x) %s ", packet_type, in ? "<=" : "=>");
break;
}
for (uint16_t i = 0; i < len; i++) {
_print->printf("%02X ", packet[i]);
}
_print->printf("\n");
}
static void _log_message(int log_level, const char * format, va_list argptr) {
(void)log_level;
char log_message_buffer[HCI_DUMP_MAX_MESSAGE_LEN];
if (!_print) {
return;
}
vsnprintf(log_message_buffer, sizeof(log_message_buffer), format, argptr);
_print->printf("[BT @%lu] LOG -- %s\n", millis(), log_message_buffer);
}
static const hci_dump_t hci_dump_instance = {
NULL,
_log_packet,
_log_message
};
void __EnableBluetoothDebug(Print &print) {
_print = &print;
hci_dump_init(&hci_dump_instance);
}
#endif
+5 -5
View File
@@ -4,11 +4,11 @@
SPDX-License-Identifier: BSD-3-Clause
*/
#include <Arduino.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/sync.h"
#include "hardware/structs/ioqspi.h"
#include "hardware/structs/sio.h"
#include <pico/stdlib.h>
#include <hardware/gpio.h>
#include <hardware/sync.h>
#include <hardware/structs/ioqspi.h>
#include <hardware/structs/sio.h>
// This example blinks the Pico LED when the BOOTSEL button is pressed.
//
+10 -6
View File
@@ -28,14 +28,18 @@ CoreMutex::CoreMutex(mutex_t *mutex, uint8_t option) {
_mutex = mutex;
_acquired = false;
_option = option;
_pxHigherPriorityTaskWoken = 0; // pdFALSE
if (__isFreeRTOS) {
auto m = __get_freertos_mutex_for_ptr(mutex);
if (_option & FromISR) {
__freertos_mutex_take_from_isr(m);
} else {
if (!__freertos_mutex_try_take(m)) {
if (__freertos_check_if_in_isr()) {
if (!__freertos_mutex_take_from_isr(m, &_pxHigherPriorityTaskWoken)) {
return;
}
// At this point we have the mutex in ISR
} else {
// Grab the mutex normally, possibly waking other tasks to get it
__freertos_mutex_take(m);
}
} else {
uint32_t owner;
@@ -56,8 +60,8 @@ CoreMutex::~CoreMutex() {
if (_acquired) {
if (__isFreeRTOS) {
auto m = __get_freertos_mutex_for_ptr(_mutex);
if (_option & FromISR) {
__freertos_mutex_give_from_isr(m);
if (__freertos_check_if_in_isr()) {
__freertos_mutex_give_from_isr(m, &_pxHigherPriorityTaskWoken);
} else {
__freertos_mutex_give(m);
}
+3 -3
View File
@@ -23,12 +23,11 @@
#pragma once
#include "pico/mutex.h"
#include <pico/mutex.h>
#include "_freertos.h"
enum {
DebugEnable = 1,
FromISR = 1 << 1,
DebugEnable = 1
};
class CoreMutex {
@@ -44,4 +43,5 @@ private:
mutex_t *_mutex;
bool _acquired;
uint8_t _option;
BaseType_t _pxHigherPriorityTaskWoken;
};
+82
View File
@@ -0,0 +1,82 @@
/*
RP2040 PIO utility class
Copyright (c) 2023 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 "PIOProgram.h"
#include <map>
static std::map<const pio_program_t *, int> __pioMap[2];
auto_init_mutex(_pioMutex);
PIOProgram::PIOProgram(const pio_program_t *pgm) {
_pgm = pgm;
_pio = nullptr;
_sm = -1;
}
// We leave the INSN loaded in INSN RAM
PIOProgram::~PIOProgram() {
if (_pio) {
pio_sm_unclaim(_pio, _sm);
}
}
// Possibly load into a PIO and allocate a SM
bool PIOProgram::prepare(PIO *pio, int *sm, int *offset) {
CoreMutex m(&_pioMutex);
PIO pi[2] = { pio0, pio1 };
// If it's already loaded into PIO IRAM, try and allocate in that specific PIO
for (int o = 0; o < 2; o++) {
auto p = __pioMap[o].find(_pgm);
if (p != __pioMap[o].end()) {
int idx = pio_claim_unused_sm(pi[o], false);
if (idx >= 0) {
_pio = pi[o];
_sm = idx;
*pio = pi[o];
*sm = idx;
*offset = p->second;
return true;
}
}
}
// Not in any PIO IRAM, so try and add
for (int o = 0; o < 2; o++) {
if (pio_can_add_program(pi[o], _pgm)) {
int idx = pio_claim_unused_sm(pi[o], false);
if (idx >= 0) {
int off = pio_add_program(pi[o], _pgm);
__pioMap[o].insert({_pgm, off});
_pio = pi[o];
_sm = idx;
*pio = pi[o];
*sm = idx;
*offset = off;
return true;
}
}
}
// Nope, no room either for SMs or INSNs
return false;
}
+37
View File
@@ -0,0 +1,37 @@
/*
RP2040 PIO utility class
Copyright (c) 2023 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 <hardware/pio.h>
// Wrapper class for PIO programs, abstracting common operations out
class PIOProgram {
public:
PIOProgram(const pio_program_t *pgm);
~PIOProgram();
// Possibly load into a PIO and allocate a SM
bool prepare(PIO *pio, int *sm, int *offset);
private:
const pio_program_t *_pgm;
PIO _pio;
int _sm;
};
+39 -66
View File
@@ -29,7 +29,9 @@
#include <pico/multicore.h>
#include <pico/rand.h>
#include <pico/util/queue.h>
#include <pico/bootrom.h>
#include "CoreMutex.h"
#include "PIOProgram.h"
#include "ccount.pio.h"
#include <malloc.h>
@@ -91,15 +93,14 @@ public:
if (!_multicore) {
return;
}
__holdUpPendSV = 1;
if (__isFreeRTOS) {
vTaskPreemptionDisable(nullptr);
vTaskSuspendAll();
__freertos_idle_other_core();
} else {
mutex_enter_blocking(&_idleMutex);
__otherCoreIdled = false;
multicore_fifo_push_blocking(_GOTOSLEEP);
while (!__otherCoreIdled) { /* noop */ }
}
mutex_enter_blocking(&_idleMutex);
__otherCoreIdled = false;
multicore_fifo_push_blocking(_GOTOSLEEP);
while (!__otherCoreIdled) { /* noop */ }
}
void resumeOtherCore() {
@@ -109,10 +110,8 @@ public:
mutex_exit(&_idleMutex);
__otherCoreIdled = false;
if (__isFreeRTOS) {
xTaskResumeAll();
vTaskPreemptionEnable(nullptr);
__freertos_resume_other_core();
}
__holdUpPendSV = 0;
// Other core will exit busy-loop and return to operation
// once __otherCoreIdled == false.
@@ -156,64 +155,12 @@ private:
class RP2040;
extern RP2040 rp2040;
extern "C" void main1();
class PIOProgram;
extern "C" char __StackLimit;
extern "C" char __bss_end__;
// Wrapper class for PIO programs, abstracting common operations out
// TODO - Add unload/destructor
class PIOProgram {
public:
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 (_offset[pio_get_index(*pio)] < 0) {
// Nope, need to load it
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
// PIO and SM already set
*offset = _offset[pio_get_index(*pio)];
return true;
}
private:
// Find an unused PIO state machine to grab, returns false when none available
static bool _findFreeSM(PIO *pio, int *sm) {
int idx = pio_claim_unused_sm(pio0, false);
if (idx >= 0) {
*pio = pio0;
*sm = idx;
return true;
}
idx = pio_claim_unused_sm(pio1, false);
if (idx >= 0) {
*pio = pio1;
*sm = idx;
return true;
}
return false;
}
private:
int _offset[2] = { -1, -1 };
const pio_program_t *_pgm;
};
extern "C" void setup1() __attribute__((weak));
extern "C" void loop1() __attribute__((weak));
extern "C" bool core1_separate_stack;
extern "C" uint32_t* core1_separate_stack_address;
class RP2040 {
public:
@@ -295,6 +242,25 @@ public:
return &__StackLimit - &__bss_end__;
}
inline uint32_t getStackPointer() {
uint32_t *sp;
asm volatile("mov %0, sp" : "=r"(sp));
return (uint32_t)sp;
}
inline int getFreeStack() {
const unsigned int sp = getStackPointer();
uint32_t ref = 0x20040000;
if (setup1 || loop1) {
if (core1_separate_stack) {
ref = cpuid() ? (unsigned int)core1_separate_stack_address : 0x20040000;
} else {
ref = cpuid() ? 0x20040000 : 0x20041000;
}
}
return sp - ref;
}
void idleOtherCore() {
fifo.idleOtherCore();
}
@@ -320,6 +286,13 @@ public:
reboot();
}
inline void rebootToBootloader() {
reset_usb_boot(0, 0);
while (1) {
continue;
}
}
static void enableDoubleResetBootloader();
void wdt_begin(uint32_t delay_ms) {
+78 -12
View File
@@ -25,17 +25,16 @@
#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"
#include "pico/usb_reset_interface.h"
#include "hardware/watchdog.h"
#include "pico/bootrom.h"
#include <tusb.h>
#include <class/hid/hid_device.h>
#include <class/audio/audio.h>
#include <pico/time.h>
#include <hardware/irq.h>
#include <pico/mutex.h>
#include <pico/unique_id.h>
#include <pico/usb_reset_interface.h>
#include <hardware/watchdog.h>
#include <pico/bootrom.h>
#include "sdkoverride/tusb_absmouse.h"
#include <device/usbd_pvt.h>
@@ -84,6 +83,8 @@ static int __usb_task_irq;
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_VENDOR_SPECIFIC, RESET_INTERFACE_SUBCLASS, RESET_INTERFACE_PROTOCOL, _stridx,
int usb_hid_poll_interval __attribute__((weak)) = 10;
const uint8_t *tud_descriptor_device_cb(void) {
static tusb_desc_device_t usbd_desc_device = {
.bLength = sizeof(tusb_desc_device_t),
@@ -264,7 +265,7 @@ void __SetupUSBDescriptor() {
uint8_t hid_itf = __USBInstallSerial ? 2 : 0;
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)
TUD_HID_DESCRIPTOR(hid_itf, 0, HID_ITF_PROTOCOL_NONE, hid_report_len, EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, (uint8_t)usb_hid_poll_interval)
};
uint8_t msd_itf = interface_count - 1;
@@ -395,6 +396,18 @@ void __USBStart() {
}
bool __USBHIDReady() {
uint32_t start = millis();
const uint32_t timeout = 500;
while (((millis() - start) < timeout) && tud_ready() && !tud_hid_ready()) {
tud_task();
delayMicroseconds(1);
}
return tud_hid_ready();
}
// 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
@@ -550,6 +563,59 @@ usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
*driver_count = 1;
return &_resetd_driver;
}
#elif defined NO_USB
// will ensure backward compatibility with existing code when using pico-debug
#warning "NO_USB selected. No output to Serial will occur!"
#include <Arduino.h>
void SerialUSB::begin(unsigned long baud) {
}
void SerialUSB::end() {
}
int SerialUSB::peek() {
return 0;
}
int SerialUSB::read() {
return -1;
}
int SerialUSB::available() {
return 0;
}
int SerialUSB::availableForWrite() {
return 0;
}
void SerialUSB::flush() {
}
size_t SerialUSB::write(uint8_t c) {
(void) c;
return 0;
}
size_t SerialUSB::write(const uint8_t *buf, size_t length) {
(void) buf;
(void) length;
return 0;
}
SerialUSB::operator bool() {
return false;
}
SerialUSB Serial;
#endif
+4 -1
View File
@@ -19,7 +19,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pico/mutex.h"
#include <pico/mutex.h>
// Weak function definitions for each type of endpoint
extern void __USBInstallSerial() __attribute__((weak));
@@ -45,3 +45,6 @@ int __USBGetJoystickReportID();
// Called by main() to init the USB HW/SW.
void __USBStart();
// Helper class for HID report sending with wait and timeout
bool __USBHIDReady();
+3 -3
View File
@@ -1,5 +1,5 @@
#pragma once
#define ARDUINO_PICO_MAJOR 3
#define ARDUINO_PICO_MINOR 2
#define ARDUINO_PICO_REVISION 0
#define ARDUINO_PICO_VERSION_STR "3.2.0"
#define ARDUINO_PICO_MINOR 9
#define ARDUINO_PICO_REVISION 3
#define ARDUINO_PICO_VERSION_STR "3.9.3"
+21 -14
View File
@@ -46,22 +46,24 @@ static pio_program_t *pio_make_uart_prog(int repl, const pio_program_t *pg) {
return p;
}
static PIOProgram *_getTxProgram(int bits) {
auto f = _txMap.find(bits);
static PIOProgram *_getTxProgram(int bits, bool inverted) {
int key = inverted ? -bits : bits;
auto f = _txMap.find(key);
if (f == _txMap.end()) {
pio_program_t * p = pio_make_uart_prog(bits, &pio_tx_program);
_txMap.insert({bits, new PIOProgram(p)});
f = _txMap.find(bits);
pio_program_t * p = pio_make_uart_prog(bits, inverted ? &pio_tx_inv_program : &pio_tx_program);
_txMap.insert({key, new PIOProgram(p)});
f = _txMap.find(key);
}
return f->second;
}
static PIOProgram *_getRxProgram(int bits) {
auto f = _rxMap.find(bits);
static PIOProgram *_getRxProgram(int bits, bool inverted) {
int key = inverted ? -bits : bits;
auto f = _rxMap.find(key);
if (f == _rxMap.end()) {
pio_program_t * p = pio_make_uart_prog(bits, &pio_rx_program);
_rxMap.insert({bits, new PIOProgram(p)});
f = _rxMap.find(bits);
pio_program_t * p = pio_make_uart_prog(bits, inverted ? &pio_rx_inv_program : &pio_rx_program);
_rxMap.insert({key, new PIOProgram(p)});
f = _rxMap.find(key);
}
return f->second;
}
@@ -96,7 +98,7 @@ void __not_in_flash_func(SerialPIO::_handleIRQ)() {
return;
}
while (!pio_sm_is_rx_fifo_empty(_rxPIO, _rxSM)) {
uint32_t decode = _rxPIO->rxf[_rxSM];
uint32_t decode = _rxPIO->rxf[_rxSM] ^ (_rxInverted ? 0xffffffff : 0);
decode >>= 33 - _rxBits;
uint32_t val = 0;
for (int b = 0; b < _bits + 1; b++) {
@@ -189,7 +191,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
if (_tx != NOPIN) {
_txBits = _bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1/*start bit*/;
_txPgm = _getTxProgram(_txBits);
_txPgm = _getTxProgram(_txBits, _txInverted);
int off;
if (!_txPgm->prepare(&_txPIO, &_txSM, &off)) {
DEBUGCORE("ERROR: Unable to allocate PIO TX UART, out of PIO resources\n");
@@ -216,7 +218,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
_reader = 0;
_rxBits = 2 * (_bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1) - 1;
_rxPgm = _getRxProgram(_rxBits);
_rxPgm = _getRxProgram(_rxBits, _rxInverted);
int off;
if (!_rxPgm->prepare(&_rxPIO, &_rxSM, &off)) {
DEBUGCORE("ERROR: Unable to allocate PIO RX UART, out of PIO resources\n");
@@ -346,6 +348,11 @@ void SerialPIO::flush() {
delay((1000 * (_txBits + 1)) / _baud);
}
void SerialPIO::setInverted(bool invTx, bool invRx) {
_txInverted = invTx;
_rxInverted = invRx;
}
size_t SerialPIO::write(uint8_t c) {
CoreMutex m(&_mutex);
if (!_running || !m || (_tx == NOPIN)) {
@@ -364,7 +371,7 @@ size_t SerialPIO::write(uint8_t c) {
}
val <<= 1; // Start bit = low
pio_sm_put_blocking(_txPIO, _txSM, val);
pio_sm_put_blocking(_txPIO, _txSM, _txInverted ? ~val : val);
return 1;
}
+5 -1
View File
@@ -41,6 +41,8 @@ public:
void begin(unsigned long baud, uint16_t config) override;
void end() override;
void setInverted(bool invTx = true, bool invRx = true);
virtual int peek() override;
virtual int read() override;
virtual int available() override;
@@ -51,7 +53,7 @@ public:
using Print::write;
operator bool() override;
// Not to be called by users, only from the IRQ handler. In public so that the C-language IQR callback can access it
// Not to be called by users, only from the IRQ handler. In public so that the C-language IRQ callback can access it
void _handleIRQ();
protected:
@@ -63,6 +65,8 @@ protected:
int _stop;
bool _overflow;
mutex_t _mutex;
bool _txInverted = false;
bool _rxInverted = false;
PIOProgram *_txPgm;
PIO _txPIO;
+17 -1
View File
@@ -40,6 +40,10 @@ bool SerialUART::setRX(pin_size_t pin) {
return true;
}
if (_rx == pin) {
return true;
}
if (_running) {
panic("FATAL: Attempting to set Serial%d.RX while running", uart_get_index(_uart) + 1);
} else {
@@ -57,6 +61,10 @@ bool SerialUART::setTX(pin_size_t pin) {
return true;
}
if (_tx == pin) {
return true;
}
if (_running) {
panic("FATAL: Attempting to set Serial%d.TX while running", uart_get_index(_uart) + 1);
} else {
@@ -74,6 +82,10 @@ bool SerialUART::setRTS(pin_size_t pin) {
return true;
}
if (_rts == pin) {
return true;
}
if (_running) {
panic("FATAL: Attempting to set Serial%d.RTS while running", uart_get_index(_uart) + 1);
} else {
@@ -91,6 +103,10 @@ bool SerialUART::setCTS(pin_size_t pin) {
return true;
}
if (_cts == pin) {
return true;
}
if (_running) {
panic("FATAL: Attempting to set Serial%d.CTS while running", uart_get_index(_uart) + 1);
} else {
@@ -185,7 +201,7 @@ void SerialUART::begin(unsigned long baud, uint16_t config) {
break;
}
uart_set_format(_uart, bits, stop, parity);
uart_set_hw_flow(_uart, _rts != UART_PIN_NOT_DEFINED, _cts != UART_PIN_NOT_DEFINED);
uart_set_hw_flow(_uart, _cts != UART_PIN_NOT_DEFINED, _rts != UART_PIN_NOT_DEFINED);
_writer = 0;
_reader = 0;
+25 -13
View File
@@ -25,15 +25,15 @@
#include <Arduino.h>
#include "CoreMutex.h"
#include "tusb.h"
#include "pico/time.h"
#include "pico/binary_info.h"
#include "pico/bootrom.h"
#include "hardware/irq.h"
#include "pico/mutex.h"
#include "hardware/watchdog.h"
#include "pico/unique_id.h"
#include "hardware/resets.h"
#include <tusb.h>
#include <pico/time.h>
#include <pico/binary_info.h>
#include <pico/bootrom.h>
#include <hardware/irq.h>
#include <pico/mutex.h>
#include <hardware/watchdog.h>
#include <pico/unique_id.h>
#include <hardware/resets.h>
#ifndef DISABLE_USB_SERIAL
// Ensure we are installed in the USB chain
@@ -130,7 +130,7 @@ size_t SerialUSB::write(const uint8_t *buf, size_t length) {
static uint64_t last_avail_time;
int written = 0;
if (tud_cdc_connected()) {
if (tud_cdc_connected() || _ignoreFlowControl) {
for (size_t i = 0; i < length;) {
int n = length - i;
int avail = tud_cdc_write_available();
@@ -171,14 +171,19 @@ SerialUSB::operator bool() {
return tud_cdc_connected();
}
void SerialUSB::ignoreFlowControl(bool ignore) {
_ignoreFlowControl = ignore;
}
static bool _dtr = false;
static bool _rts = false;
static int _bps = 115200;
static bool _rebooting = false;
static void CheckSerialReset() {
__holdUpPendSV = 1; // Ensure we don't get swapped out by FreeRTOS
if (!_rebooting && (_bps == 1200) && (!_dtr)) {
if (__isFreeRTOS) {
__freertos_idle_other_core();
}
_rebooting = true;
// Disable NVIC IRQ, so that we don't get bothered anymore
irq_set_enabled(USBCTRL_IRQ, false);
@@ -186,11 +191,18 @@ static void CheckSerialReset() {
reset_block(RESETS_RESET_USBCTRL_BITS);
unreset_block(RESETS_RESET_USBCTRL_BITS);
// Delay a bit, so the PC can figure out that we have disconnected.
sleep_ms(3);
busy_wait_ms(3);
reset_usb_boot(0, 0);
while (1); // WDT will fire here
}
__holdUpPendSV = 0;
}
bool SerialUSB::dtr() {
return _dtr;
}
bool SerialUSB::rts() {
return _rts;
}
extern "C" void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
+5
View File
@@ -43,6 +43,10 @@ public:
virtual size_t write(const uint8_t *p, size_t len) override;
using Print::write;
operator bool() override;
bool dtr();
bool rts();
void ignoreFlowControl(bool ignore = true);
// ESP8266 compat
void setDebugOutput(bool unused) {
@@ -51,6 +55,7 @@ public:
private:
bool _running = false;
bool _ignoreFlowControl = false;
};
extern SerialUSB Serial;
+474
View File
@@ -0,0 +1,474 @@
// autogenerated from https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv
// by script <rp2040 arduino core>/tools/tzupdate.sh
// Sat 20 Jan 2024 08:54:45 PM UTC
//
// This database is autogenerated from IANA timezone database
// https://raw.githubusercontent.com/nayarsystems/posix_tz_db/master/zones.csv
// (using https://www.iana.org/time-zones)
// and can be updated on demand in this repository
// or by yourself using the above script
#pragma once
#define TZ_Africa_Abidjan ("GMT0")
#define TZ_Africa_Accra ("GMT0")
#define TZ_Africa_Addis_Ababa ("EAT-3")
#define TZ_Africa_Algiers ("CET-1")
#define TZ_Africa_Asmara ("EAT-3")
#define TZ_Africa_Bamako ("GMT0")
#define TZ_Africa_Bangui ("WAT-1")
#define TZ_Africa_Banjul ("GMT0")
#define TZ_Africa_Bissau ("GMT0")
#define TZ_Africa_Blantyre ("CAT-2")
#define TZ_Africa_Brazzaville ("WAT-1")
#define TZ_Africa_Bujumbura ("CAT-2")
#define TZ_Africa_Cairo ("EET-2EEST,M4.5.5/0,M10.5.4/24")
#define TZ_Africa_Casablanca ("<+01>-1")
#define TZ_Africa_Ceuta ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Africa_Conakry ("GMT0")
#define TZ_Africa_Dakar ("GMT0")
#define TZ_Africa_Dar_es_Salaam ("EAT-3")
#define TZ_Africa_Djibouti ("EAT-3")
#define TZ_Africa_Douala ("WAT-1")
#define TZ_Africa_El_Aaiun ("<+01>-1")
#define TZ_Africa_Freetown ("GMT0")
#define TZ_Africa_Gaborone ("CAT-2")
#define TZ_Africa_Harare ("CAT-2")
#define TZ_Africa_Johannesburg ("SAST-2")
#define TZ_Africa_Juba ("CAT-2")
#define TZ_Africa_Kampala ("EAT-3")
#define TZ_Africa_Khartoum ("CAT-2")
#define TZ_Africa_Kigali ("CAT-2")
#define TZ_Africa_Kinshasa ("WAT-1")
#define TZ_Africa_Lagos ("WAT-1")
#define TZ_Africa_Libreville ("WAT-1")
#define TZ_Africa_Lome ("GMT0")
#define TZ_Africa_Luanda ("WAT-1")
#define TZ_Africa_Lubumbashi ("CAT-2")
#define TZ_Africa_Lusaka ("CAT-2")
#define TZ_Africa_Malabo ("WAT-1")
#define TZ_Africa_Maputo ("CAT-2")
#define TZ_Africa_Maseru ("SAST-2")
#define TZ_Africa_Mbabane ("SAST-2")
#define TZ_Africa_Mogadishu ("EAT-3")
#define TZ_Africa_Monrovia ("GMT0")
#define TZ_Africa_Nairobi ("EAT-3")
#define TZ_Africa_Ndjamena ("WAT-1")
#define TZ_Africa_Niamey ("WAT-1")
#define TZ_Africa_Nouakchott ("GMT0")
#define TZ_Africa_Ouagadougou ("GMT0")
#define TZ_Africa_PortomNovo ("WAT-1")
#define TZ_Africa_Sao_Tome ("GMT0")
#define TZ_Africa_Tripoli ("EET-2")
#define TZ_Africa_Tunis ("CET-1")
#define TZ_Africa_Windhoek ("CAT-2")
#define TZ_America_Adak ("HST10HDT,M3.2.0,M11.1.0")
#define TZ_America_Anchorage ("AKST9AKDT,M3.2.0,M11.1.0")
#define TZ_America_Anguilla ("AST4")
#define TZ_America_Antigua ("AST4")
#define TZ_America_Araguaina ("<-03>3")
#define TZ_America_Argentina_Buenos_Aires ("<-03>3")
#define TZ_America_Argentina_Catamarca ("<-03>3")
#define TZ_America_Argentina_Cordoba ("<-03>3")
#define TZ_America_Argentina_Jujuy ("<-03>3")
#define TZ_America_Argentina_La_Rioja ("<-03>3")
#define TZ_America_Argentina_Mendoza ("<-03>3")
#define TZ_America_Argentina_Rio_Gallegos ("<-03>3")
#define TZ_America_Argentina_Salta ("<-03>3")
#define TZ_America_Argentina_San_Juan ("<-03>3")
#define TZ_America_Argentina_San_Luis ("<-03>3")
#define TZ_America_Argentina_Tucuman ("<-03>3")
#define TZ_America_Argentina_Ushuaia ("<-03>3")
#define TZ_America_Aruba ("AST4")
#define TZ_America_Asuncion ("<-04>4<-03>,M10.1.0/0,M3.4.0/0")
#define TZ_America_Atikokan ("EST5")
#define TZ_America_Bahia ("<-03>3")
#define TZ_America_Bahia_Banderas ("CST6")
#define TZ_America_Barbados ("AST4")
#define TZ_America_Belem ("<-03>3")
#define TZ_America_Belize ("CST6")
#define TZ_America_BlancmSablon ("AST4")
#define TZ_America_Boa_Vista ("<-04>4")
#define TZ_America_Bogota ("<-05>5")
#define TZ_America_Boise ("MST7MDT,M3.2.0,M11.1.0")
#define TZ_America_Cambridge_Bay ("MST7MDT,M3.2.0,M11.1.0")
#define TZ_America_Campo_Grande ("<-04>4")
#define TZ_America_Cancun ("EST5")
#define TZ_America_Caracas ("<-04>4")
#define TZ_America_Cayenne ("<-03>3")
#define TZ_America_Cayman ("EST5")
#define TZ_America_Chicago ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Chihuahua ("CST6")
#define TZ_America_Costa_Rica ("CST6")
#define TZ_America_Creston ("MST7")
#define TZ_America_Cuiaba ("<-04>4")
#define TZ_America_Curacao ("AST4")
#define TZ_America_Danmarkshavn ("GMT0")
#define TZ_America_Dawson ("MST7")
#define TZ_America_Dawson_Creek ("MST7")
#define TZ_America_Denver ("MST7MDT,M3.2.0,M11.1.0")
#define TZ_America_Detroit ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Dominica ("AST4")
#define TZ_America_Edmonton ("MST7MDT,M3.2.0,M11.1.0")
#define TZ_America_Eirunepe ("<-05>5")
#define TZ_America_El_Salvador ("CST6")
#define TZ_America_Fortaleza ("<-03>3")
#define TZ_America_Fort_Nelson ("MST7")
#define TZ_America_Glace_Bay ("AST4ADT,M3.2.0,M11.1.0")
#define TZ_America_Godthab ("<-02>2<-01>,M3.5.0/-1,M10.5.0/0")
#define TZ_America_Goose_Bay ("AST4ADT,M3.2.0,M11.1.0")
#define TZ_America_Grand_Turk ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Grenada ("AST4")
#define TZ_America_Guadeloupe ("AST4")
#define TZ_America_Guatemala ("CST6")
#define TZ_America_Guayaquil ("<-05>5")
#define TZ_America_Guyana ("<-04>4")
#define TZ_America_Halifax ("AST4ADT,M3.2.0,M11.1.0")
#define TZ_America_Havana ("CST5CDT,M3.2.0/0,M11.1.0/1")
#define TZ_America_Hermosillo ("MST7")
#define TZ_America_Indiana_Indianapolis ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Indiana_Knox ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Indiana_Marengo ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Indiana_Petersburg ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Indiana_Tell_City ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Indiana_Vevay ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Indiana_Vincennes ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Indiana_Winamac ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Inuvik ("MST7MDT,M3.2.0,M11.1.0")
#define TZ_America_Iqaluit ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Jamaica ("EST5")
#define TZ_America_Juneau ("AKST9AKDT,M3.2.0,M11.1.0")
#define TZ_America_Kentucky_Louisville ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Kentucky_Monticello ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Kralendijk ("AST4")
#define TZ_America_La_Paz ("<-04>4")
#define TZ_America_Lima ("<-05>5")
#define TZ_America_Los_Angeles ("PST8PDT,M3.2.0,M11.1.0")
#define TZ_America_Lower_Princes ("AST4")
#define TZ_America_Maceio ("<-03>3")
#define TZ_America_Managua ("CST6")
#define TZ_America_Manaus ("<-04>4")
#define TZ_America_Marigot ("AST4")
#define TZ_America_Martinique ("AST4")
#define TZ_America_Matamoros ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Mazatlan ("MST7")
#define TZ_America_Menominee ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Merida ("CST6")
#define TZ_America_Metlakatla ("AKST9AKDT,M3.2.0,M11.1.0")
#define TZ_America_Mexico_City ("CST6")
#define TZ_America_Miquelon ("<-03>3<-02>,M3.2.0,M11.1.0")
#define TZ_America_Moncton ("AST4ADT,M3.2.0,M11.1.0")
#define TZ_America_Monterrey ("CST6")
#define TZ_America_Montevideo ("<-03>3")
#define TZ_America_Montreal ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Montserrat ("AST4")
#define TZ_America_Nassau ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_New_York ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Nipigon ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Nome ("AKST9AKDT,M3.2.0,M11.1.0")
#define TZ_America_Noronha ("<-02>2")
#define TZ_America_North_Dakota_Beulah ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_North_Dakota_Center ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_North_Dakota_New_Salem ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Nuuk ("<-02>2<-01>,M3.5.0/-1,M10.5.0/0")
#define TZ_America_Ojinaga ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Panama ("EST5")
#define TZ_America_Pangnirtung ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Paramaribo ("<-03>3")
#define TZ_America_Phoenix ("MST7")
#define TZ_America_PortmaumPrince ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Port_of_Spain ("AST4")
#define TZ_America_Porto_Velho ("<-04>4")
#define TZ_America_Puerto_Rico ("AST4")
#define TZ_America_Punta_Arenas ("<-03>3")
#define TZ_America_Rainy_River ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Rankin_Inlet ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Recife ("<-03>3")
#define TZ_America_Regina ("CST6")
#define TZ_America_Resolute ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Rio_Branco ("<-05>5")
#define TZ_America_Santarem ("<-03>3")
#define TZ_America_Santiago ("<-04>4<-03>,M9.1.6/24,M4.1.6/24")
#define TZ_America_Santo_Domingo ("AST4")
#define TZ_America_Sao_Paulo ("<-03>3")
#define TZ_America_Scoresbysund ("<-01>1<+00>,M3.5.0/0,M10.5.0/1")
#define TZ_America_Sitka ("AKST9AKDT,M3.2.0,M11.1.0")
#define TZ_America_St_Barthelemy ("AST4")
#define TZ_America_St_Johns ("NST3:30NDT,M3.2.0,M11.1.0")
#define TZ_America_St_Kitts ("AST4")
#define TZ_America_St_Lucia ("AST4")
#define TZ_America_St_Thomas ("AST4")
#define TZ_America_St_Vincent ("AST4")
#define TZ_America_Swift_Current ("CST6")
#define TZ_America_Tegucigalpa ("CST6")
#define TZ_America_Thule ("AST4ADT,M3.2.0,M11.1.0")
#define TZ_America_Thunder_Bay ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Tijuana ("PST8PDT,M3.2.0,M11.1.0")
#define TZ_America_Toronto ("EST5EDT,M3.2.0,M11.1.0")
#define TZ_America_Tortola ("AST4")
#define TZ_America_Vancouver ("PST8PDT,M3.2.0,M11.1.0")
#define TZ_America_Whitehorse ("MST7")
#define TZ_America_Winnipeg ("CST6CDT,M3.2.0,M11.1.0")
#define TZ_America_Yakutat ("AKST9AKDT,M3.2.0,M11.1.0")
#define TZ_America_Yellowknife ("MST7MDT,M3.2.0,M11.1.0")
#define TZ_Antarctica_Casey ("<+11>-11")
#define TZ_Antarctica_Davis ("<+07>-7")
#define TZ_Antarctica_DumontDUrville ("<+10>-10")
#define TZ_Antarctica_Macquarie ("AEST-10AEDT,M10.1.0,M4.1.0/3")
#define TZ_Antarctica_Mawson ("<+05>-5")
#define TZ_Antarctica_McMurdo ("NZST-12NZDT,M9.5.0,M4.1.0/3")
#define TZ_Antarctica_Palmer ("<-03>3")
#define TZ_Antarctica_Rothera ("<-03>3")
#define TZ_Antarctica_Syowa ("<+03>-3")
#define TZ_Antarctica_Troll ("<+00>0<+02>-2,M3.5.0/1,M10.5.0/3")
#define TZ_Antarctica_Vostok ("<+06>-6")
#define TZ_Arctic_Longyearbyen ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Asia_Aden ("<+03>-3")
#define TZ_Asia_Almaty ("<+06>-6")
#define TZ_Asia_Amman ("<+03>-3")
#define TZ_Asia_Anadyr ("<+12>-12")
#define TZ_Asia_Aqtau ("<+05>-5")
#define TZ_Asia_Aqtobe ("<+05>-5")
#define TZ_Asia_Ashgabat ("<+05>-5")
#define TZ_Asia_Atyrau ("<+05>-5")
#define TZ_Asia_Baghdad ("<+03>-3")
#define TZ_Asia_Bahrain ("<+03>-3")
#define TZ_Asia_Baku ("<+04>-4")
#define TZ_Asia_Bangkok ("<+07>-7")
#define TZ_Asia_Barnaul ("<+07>-7")
#define TZ_Asia_Beirut ("EET-2EEST,M3.5.0/0,M10.5.0/0")
#define TZ_Asia_Bishkek ("<+06>-6")
#define TZ_Asia_Brunei ("<+08>-8")
#define TZ_Asia_Chita ("<+09>-9")
#define TZ_Asia_Choibalsan ("<+08>-8")
#define TZ_Asia_Colombo ("<+0530>-5:30")
#define TZ_Asia_Damascus ("<+03>-3")
#define TZ_Asia_Dhaka ("<+06>-6")
#define TZ_Asia_Dili ("<+09>-9")
#define TZ_Asia_Dubai ("<+04>-4")
#define TZ_Asia_Dushanbe ("<+05>-5")
#define TZ_Asia_Famagusta ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Asia_Gaza ("EET-2EEST,M3.4.4/50,M10.4.4/50")
#define TZ_Asia_Hebron ("EET-2EEST,M3.4.4/50,M10.4.4/50")
#define TZ_Asia_Ho_Chi_Minh ("<+07>-7")
#define TZ_Asia_Hong_Kong ("HKT-8")
#define TZ_Asia_Hovd ("<+07>-7")
#define TZ_Asia_Irkutsk ("<+08>-8")
#define TZ_Asia_Jakarta ("WIB-7")
#define TZ_Asia_Jayapura ("WIT-9")
#define TZ_Asia_Jerusalem ("IST-2IDT,M3.4.4/26,M10.5.0")
#define TZ_Asia_Kabul ("<+0430>-4:30")
#define TZ_Asia_Kamchatka ("<+12>-12")
#define TZ_Asia_Karachi ("PKT-5")
#define TZ_Asia_Kathmandu ("<+0545>-5:45")
#define TZ_Asia_Khandyga ("<+09>-9")
#define TZ_Asia_Kolkata ("IST-5:30")
#define TZ_Asia_Krasnoyarsk ("<+07>-7")
#define TZ_Asia_Kuala_Lumpur ("<+08>-8")
#define TZ_Asia_Kuching ("<+08>-8")
#define TZ_Asia_Kuwait ("<+03>-3")
#define TZ_Asia_Macau ("CST-8")
#define TZ_Asia_Magadan ("<+11>-11")
#define TZ_Asia_Makassar ("WITA-8")
#define TZ_Asia_Manila ("PST-8")
#define TZ_Asia_Muscat ("<+04>-4")
#define TZ_Asia_Nicosia ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Asia_Novokuznetsk ("<+07>-7")
#define TZ_Asia_Novosibirsk ("<+07>-7")
#define TZ_Asia_Omsk ("<+06>-6")
#define TZ_Asia_Oral ("<+05>-5")
#define TZ_Asia_Phnom_Penh ("<+07>-7")
#define TZ_Asia_Pontianak ("WIB-7")
#define TZ_Asia_Pyongyang ("KST-9")
#define TZ_Asia_Qatar ("<+03>-3")
#define TZ_Asia_Qyzylorda ("<+05>-5")
#define TZ_Asia_Riyadh ("<+03>-3")
#define TZ_Asia_Sakhalin ("<+11>-11")
#define TZ_Asia_Samarkand ("<+05>-5")
#define TZ_Asia_Seoul ("KST-9")
#define TZ_Asia_Shanghai ("CST-8")
#define TZ_Asia_Singapore ("<+08>-8")
#define TZ_Asia_Srednekolymsk ("<+11>-11")
#define TZ_Asia_Taipei ("CST-8")
#define TZ_Asia_Tashkent ("<+05>-5")
#define TZ_Asia_Tbilisi ("<+04>-4")
#define TZ_Asia_Tehran ("<+0330>-3:30")
#define TZ_Asia_Thimphu ("<+06>-6")
#define TZ_Asia_Tokyo ("JST-9")
#define TZ_Asia_Tomsk ("<+07>-7")
#define TZ_Asia_Ulaanbaatar ("<+08>-8")
#define TZ_Asia_Urumqi ("<+06>-6")
#define TZ_Asia_UstmNera ("<+10>-10")
#define TZ_Asia_Vientiane ("<+07>-7")
#define TZ_Asia_Vladivostok ("<+10>-10")
#define TZ_Asia_Yakutsk ("<+09>-9")
#define TZ_Asia_Yangon ("<+0630>-6:30")
#define TZ_Asia_Yekaterinburg ("<+05>-5")
#define TZ_Asia_Yerevan ("<+04>-4")
#define TZ_Atlantic_Azores ("<-01>1<+00>,M3.5.0/0,M10.5.0/1")
#define TZ_Atlantic_Bermuda ("AST4ADT,M3.2.0,M11.1.0")
#define TZ_Atlantic_Canary ("WET0WEST,M3.5.0/1,M10.5.0")
#define TZ_Atlantic_Cape_Verde ("<-01>1")
#define TZ_Atlantic_Faroe ("WET0WEST,M3.5.0/1,M10.5.0")
#define TZ_Atlantic_Madeira ("WET0WEST,M3.5.0/1,M10.5.0")
#define TZ_Atlantic_Reykjavik ("GMT0")
#define TZ_Atlantic_South_Georgia ("<-02>2")
#define TZ_Atlantic_Stanley ("<-03>3")
#define TZ_Atlantic_St_Helena ("GMT0")
#define TZ_Australia_Adelaide ("ACST-9:30ACDT,M10.1.0,M4.1.0/3")
#define TZ_Australia_Brisbane ("AEST-10")
#define TZ_Australia_Broken_Hill ("ACST-9:30ACDT,M10.1.0,M4.1.0/3")
#define TZ_Australia_Currie ("AEST-10AEDT,M10.1.0,M4.1.0/3")
#define TZ_Australia_Darwin ("ACST-9:30")
#define TZ_Australia_Eucla ("<+0845>-8:45")
#define TZ_Australia_Hobart ("AEST-10AEDT,M10.1.0,M4.1.0/3")
#define TZ_Australia_Lindeman ("AEST-10")
#define TZ_Australia_Lord_Howe ("<+1030>-10:30<+11>-11,M10.1.0,M4.1.0")
#define TZ_Australia_Melbourne ("AEST-10AEDT,M10.1.0,M4.1.0/3")
#define TZ_Australia_Perth ("AWST-8")
#define TZ_Australia_Sydney ("AEST-10AEDT,M10.1.0,M4.1.0/3")
#define TZ_Europe_Amsterdam ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Andorra ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Astrakhan ("<+04>-4")
#define TZ_Europe_Athens ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Belgrade ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Berlin ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Bratislava ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Brussels ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Bucharest ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Budapest ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Busingen ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Chisinau ("EET-2EEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Copenhagen ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Dublin ("IST-1GMT0,M10.5.0,M3.5.0/1")
#define TZ_Europe_Gibraltar ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Guernsey ("GMT0BST,M3.5.0/1,M10.5.0")
#define TZ_Europe_Helsinki ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Isle_of_Man ("GMT0BST,M3.5.0/1,M10.5.0")
#define TZ_Europe_Istanbul ("<+03>-3")
#define TZ_Europe_Jersey ("GMT0BST,M3.5.0/1,M10.5.0")
#define TZ_Europe_Kaliningrad ("EET-2")
#define TZ_Europe_Kiev ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Kirov ("MSK-3")
#define TZ_Europe_Lisbon ("WET0WEST,M3.5.0/1,M10.5.0")
#define TZ_Europe_Ljubljana ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_London ("GMT0BST,M3.5.0/1,M10.5.0")
#define TZ_Europe_Luxembourg ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Madrid ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Malta ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Mariehamn ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Minsk ("<+03>-3")
#define TZ_Europe_Monaco ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Moscow ("MSK-3")
#define TZ_Europe_Oslo ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Paris ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Podgorica ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Prague ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Riga ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Rome ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Samara ("<+04>-4")
#define TZ_Europe_San_Marino ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Sarajevo ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Saratov ("<+04>-4")
#define TZ_Europe_Simferopol ("MSK-3")
#define TZ_Europe_Skopje ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Sofia ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Stockholm ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Tallinn ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Tirane ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Ulyanovsk ("<+04>-4")
#define TZ_Europe_Uzhgorod ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Vaduz ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Vatican ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Vienna ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Vilnius ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Volgograd ("MSK-3")
#define TZ_Europe_Warsaw ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Zagreb ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Europe_Zaporozhye ("EET-2EEST,M3.5.0/3,M10.5.0/4")
#define TZ_Europe_Zurich ("CET-1CEST,M3.5.0,M10.5.0/3")
#define TZ_Indian_Antananarivo ("EAT-3")
#define TZ_Indian_Chagos ("<+06>-6")
#define TZ_Indian_Christmas ("<+07>-7")
#define TZ_Indian_Cocos ("<+0630>-6:30")
#define TZ_Indian_Comoro ("EAT-3")
#define TZ_Indian_Kerguelen ("<+05>-5")
#define TZ_Indian_Mahe ("<+04>-4")
#define TZ_Indian_Maldives ("<+05>-5")
#define TZ_Indian_Mauritius ("<+04>-4")
#define TZ_Indian_Mayotte ("EAT-3")
#define TZ_Indian_Reunion ("<+04>-4")
#define TZ_Pacific_Apia ("<+13>-13")
#define TZ_Pacific_Auckland ("NZST-12NZDT,M9.5.0,M4.1.0/3")
#define TZ_Pacific_Bougainville ("<+11>-11")
#define TZ_Pacific_Chatham ("<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45")
#define TZ_Pacific_Chuuk ("<+10>-10")
#define TZ_Pacific_Easter ("<-06>6<-05>,M9.1.6/22,M4.1.6/22")
#define TZ_Pacific_Efate ("<+11>-11")
#define TZ_Pacific_Enderbury ("<+13>-13")
#define TZ_Pacific_Fakaofo ("<+13>-13")
#define TZ_Pacific_Fiji ("<+12>-12")
#define TZ_Pacific_Funafuti ("<+12>-12")
#define TZ_Pacific_Galapagos ("<-06>6")
#define TZ_Pacific_Gambier ("<-09>9")
#define TZ_Pacific_Guadalcanal ("<+11>-11")
#define TZ_Pacific_Guam ("ChST-10")
#define TZ_Pacific_Honolulu ("HST10")
#define TZ_Pacific_Kiritimati ("<+14>-14")
#define TZ_Pacific_Kosrae ("<+11>-11")
#define TZ_Pacific_Kwajalein ("<+12>-12")
#define TZ_Pacific_Majuro ("<+12>-12")
#define TZ_Pacific_Marquesas ("<-0930>9:30")
#define TZ_Pacific_Midway ("SST11")
#define TZ_Pacific_Nauru ("<+12>-12")
#define TZ_Pacific_Niue ("<-11>11")
#define TZ_Pacific_Norfolk ("<+11>-11<+12>,M10.1.0,M4.1.0/3")
#define TZ_Pacific_Noumea ("<+11>-11")
#define TZ_Pacific_Pago_Pago ("SST11")
#define TZ_Pacific_Palau ("<+09>-9")
#define TZ_Pacific_Pitcairn ("<-08>8")
#define TZ_Pacific_Pohnpei ("<+11>-11")
#define TZ_Pacific_Port_Moresby ("<+10>-10")
#define TZ_Pacific_Rarotonga ("<-10>10")
#define TZ_Pacific_Saipan ("ChST-10")
#define TZ_Pacific_Tahiti ("<-10>10")
#define TZ_Pacific_Tarawa ("<+12>-12")
#define TZ_Pacific_Tongatapu ("<+13>-13")
#define TZ_Pacific_Wake ("<+12>-12")
#define TZ_Pacific_Wallis ("<+12>-12")
#define TZ_Etc_GMT ("GMT0")
#define TZ_Etc_GMTm0 ("GMT0")
#define TZ_Etc_GMTm1 ("<+01>-1")
#define TZ_Etc_GMTm2 ("<+02>-2")
#define TZ_Etc_GMTm3 ("<+03>-3")
#define TZ_Etc_GMTm4 ("<+04>-4")
#define TZ_Etc_GMTm5 ("<+05>-5")
#define TZ_Etc_GMTm6 ("<+06>-6")
#define TZ_Etc_GMTm7 ("<+07>-7")
#define TZ_Etc_GMTm8 ("<+08>-8")
#define TZ_Etc_GMTm9 ("<+09>-9")
#define TZ_Etc_GMTm10 ("<+10>-10")
#define TZ_Etc_GMTm11 ("<+11>-11")
#define TZ_Etc_GMTm12 ("<+12>-12")
#define TZ_Etc_GMTm13 ("<+13>-13")
#define TZ_Etc_GMTm14 ("<+14>-14")
#define TZ_Etc_GMT0 ("GMT0")
#define TZ_Etc_GMTp0 ("GMT0")
#define TZ_Etc_GMTp1 ("<-01>1")
#define TZ_Etc_GMTp2 ("<-02>2")
#define TZ_Etc_GMTp3 ("<-03>3")
#define TZ_Etc_GMTp4 ("<-04>4")
#define TZ_Etc_GMTp5 ("<-05>5")
#define TZ_Etc_GMTp6 ("<-06>6")
#define TZ_Etc_GMTp7 ("<-07>7")
#define TZ_Etc_GMTp8 ("<-08>8")
#define TZ_Etc_GMTp9 ("<-09>9")
#define TZ_Etc_GMTp10 ("<-10>10")
#define TZ_Etc_GMTp11 ("<-11>11")
#define TZ_Etc_GMTp12 ("<-12>12")
#define TZ_Etc_UCT ("UTC0")
#define TZ_Etc_UTC ("UTC0")
#define TZ_Etc_Greenwich ("GMT0")
#define TZ_Etc_Universal ("UTC0")
#define TZ_Etc_Zulu ("UTC0")
+2 -2
View File
@@ -16,8 +16,8 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "stdlib.h"
#include "stdint.h"
#include <stdlib.h>
#include <stdint.h>
void randomSeed(uint32_t dwSeed) {
if (dwSeed != 0) {
+1 -43
View File
@@ -19,7 +19,7 @@
*/
#include "_freertos.h"
#include "pico/mutex.h"
#include <pico/mutex.h>
#include <stdlib.h>
#include "Arduino.h"
@@ -60,45 +60,3 @@ SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive) {
}
return nullptr; // Need to make space for more mutex maps!
}
// The HW Random code needs a precise sleep_until() in order to assure it
// grabs the ROSC bit when it wants. Unfortunately, under FreeRTOS the
// sleep_until() becomes imprecise and the "did I get the bit when I wanted"
// check in the pico_rand code always fails and you get an infinite loop.
// This block wraps the 2 get_rand calls to set a flag to convert
// sleep_until() (which can do a task swap and cause bad timing) into a
// busy wait.
extern "C" {
static bool __inRand = false;
extern uint64_t __real_get_rand_64();
uint64_t __wrap_get_rand_64() {
if (__isFreeRTOS) {
rp2040.idleOtherCore();
__inRand = true;
auto r = __real_get_rand_64();
__inRand = false;
rp2040.resumeOtherCore();
return r;
} else {
return __real_get_rand_64();
}
}
uint32_t __wrap_get_rand_32() {
return (uint32_t) __wrap_get_rand_64();
}
extern void __real_sleep_until(absolute_time_t t);
void __wrap_sleep_until(absolute_time_t t) {
if (__inRand) {
busy_wait_until(t);
} else {
__real_sleep_until(t);
}
}
}
+9 -15
View File
@@ -19,7 +19,7 @@
*/
#pragma once
#include "pico/mutex.h"
#include <pico/mutex.h>
// Cannot include refs to FreeRTOS's actual semaphore calls because they
// are implemented as macros, so we have a wrapper in our variant hook
@@ -35,32 +35,26 @@ extern "C" {
struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */
typedef struct QueueDefinition * QueueHandle_t;
typedef QueueHandle_t SemaphoreHandle_t;
typedef int32_t BaseType_t;
#endif
extern bool __freertos_check_if_in_isr() __attribute__((weak));
extern SemaphoreHandle_t __freertos_mutex_create() __attribute__((weak));
extern SemaphoreHandle_t _freertos_recursive_mutex_create() __attribute__((weak));
extern void __freertos_mutex_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_take_from_isr(SemaphoreHandle_t mtx) __attribute__((weak));
extern int __freertos_mutex_take_from_isr(SemaphoreHandle_t mtx, BaseType_t* pxHigherPriorityTaskWoken) __attribute__((weak));
extern int __freertos_mutex_try_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_give(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_give_from_isr(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_mutex_give_from_isr(SemaphoreHandle_t mtx, BaseType_t* pxHigherPriorityTaskWoken) __attribute__((weak));
extern void __freertos_recursive_mutex_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern int __freertos_recursive_mutex_try_take(SemaphoreHandle_t mtx) __attribute__((weak));
extern void __freertos_recursive_mutex_give(SemaphoreHandle_t mtx) __attribute__((weak));
#ifndef INC_FREERTOS_H
extern void vTaskSuspendAll() __attribute__((weak));
extern int32_t xTaskResumeAll() __attribute__((weak));
typedef struct tskTaskControlBlock * TaskHandle_t;
extern void vTaskPreemptionDisable(TaskHandle_t p) __attribute__((weak));
extern void vTaskPreemptionEnable(TaskHandle_t p) __attribute__((weak));
#endif
extern void __freertos_idle_other_core() __attribute__((weak));
extern void __freertos_resume_other_core() __attribute__((weak));
}
extern SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive = false);
// Halt the FreeRTOS PendSV task switching magic
extern "C" int __holdUpPendSV;
File diff suppressed because it is too large Load Diff
+32
View File
@@ -0,0 +1,32 @@
// Use to create a callback thunk from C to C++
// #define CCALLBACKNAME to a unique per-file name and #include this file
// To make a CB use a define of the form:
/*
#define PACKETHANDLERCB(class, cbFcn) \
(CCALLBACKNAME<void(uint8_t, uint16_t, uint8_t*, uint16_t), __COUNTER__>::func = std::bind(&class::cbFcn, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), \
static_cast<btstack_packet_handler_t>(<CCALLBACKNAMEvoid(uint8_t, uint16_t, uint8_t*, uint16_t), __COUNTER__ - 1>::callback))
*/
#include <functional>
// Thank you to https://stackoverflow.com/questions/66474621/multiple-non-static-callbacks-of-c-member-functions for the following beautiful hack
#ifndef CCALLBACKNAME
#define CCALLBACKNAME _CCallback
#endif
template <typename T, int tag>
struct CCALLBACKNAME;
template <typename Ret, typename... Params, int tag>
struct CCALLBACKNAME<Ret(Params...), tag> {
template <typename... Args>
static Ret callback(Args... args) {
return func(args...);
}
int _tag = tag;
static std::function<Ret(Params...)> func;
};
template <typename Ret, typename... Params, int tag>
std::function<Ret(Params...)> CCALLBACKNAME<Ret(Params...), tag>::func;
+4 -4
View File
@@ -19,12 +19,12 @@
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
#include "lwip/netif.h"
#include <lwip/netif.h>
extern "C" {
#include "cyw43.h"
#include "cyw43_stats.h"
#include <cyw43.h>
#include <cyw43_stats.h>
}
#include "pico/cyw43_arch.h"
#include <pico/cyw43_arch.h>
#include <Arduino.h>
// From cyw43_ctrl.c
+69 -3
View File
@@ -1,7 +1,7 @@
/*
LWIP wrappers to protect against timer-based re-entrancy
Copyright (c) 202s Earle F. Philhower, III <earlephilhower@yahoo.com>
Copyright (c) 2023 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
@@ -18,6 +18,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
#include <pico/mutex.h>
#include <lwip/pbuf.h>
#include <lwip/udp.h>
@@ -26,20 +27,73 @@
#include <lwip/raw.h>
#include <lwip/timeouts.h>
#include <pico/cyw43_arch.h>
#include <pico/mutex.h>
#include <sys/lock.h>
#include "_xoshiro.h"
extern void ethernet_arch_lwip_begin() __attribute__((weak));
extern void ethernet_arch_lwip_end() __attribute__((weak));
extern void ethernet_arch_lwip_gpio_mask() __attribute__((weak));
extern void ethernet_arch_lwip_gpio_unmask() __attribute__((weak));
auto_init_recursive_mutex(__lwipMutex); // Only for case with no Ethernet or PicoW, but still doing LWIP (PPP?)
class LWIPMutex {
public:
LWIPMutex() {
cyw43_arch_lwip_begin();
if (ethernet_arch_lwip_gpio_mask) {
ethernet_arch_lwip_gpio_mask();
}
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
if (rp2040.isPicoW()) {
cyw43_arch_lwip_begin();
return;
}
#endif
if (ethernet_arch_lwip_begin) {
ethernet_arch_lwip_begin();
} else {
recursive_mutex_enter_blocking(&__lwipMutex);
}
}
~LWIPMutex() {
cyw43_arch_lwip_end();
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
if (rp2040.isPicoW()) {
cyw43_arch_lwip_end();
} else {
#endif
if (ethernet_arch_lwip_end) {
ethernet_arch_lwip_end();
} else {
recursive_mutex_exit(&__lwipMutex);
}
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
}
#endif
if (ethernet_arch_lwip_gpio_unmask) {
ethernet_arch_lwip_gpio_unmask();
}
}
};
extern "C" {
static XoshiroCpp::Xoshiro256PlusPlus *_lwip_rng = nullptr;
// Random number generator for LWIP
unsigned long __lwip_rand() {
return (unsigned long)(*_lwip_rng)();
}
// Avoid calling lwip_init multiple times
extern void __real_lwip_init();
void __wrap_lwip_init() {
if (!_lwip_rng) {
_lwip_rng = new XoshiroCpp::Xoshiro256PlusPlus(micros() * rp2040.getCycleCount());
__real_lwip_init();
}
}
extern u8_t __real_pbuf_header(struct pbuf *p, s16_t header_size);
u8_t __wrap_pbuf_header(struct pbuf *p, s16_t header_size) {
LWIPMutex m;
@@ -304,4 +358,16 @@ extern "C" {
__real_raw_remove(pcb);
}
extern struct netif *__real_netif_add(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input);
struct netif *__wrap_netif_add(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input) {
LWIPMutex m;
return __real_netif_add(netif, ipaddr, netmask, gw, state, init, input);
}
extern void __real_netif_remove(struct netif *netif);
void __wrap_netif_remove(struct netif *netif) {
LWIPMutex m;
__real_netif_remove(netif);
}
}; // extern "C"
+13 -6
View File
@@ -27,11 +27,9 @@
RP2040 rp2040;
extern "C" {
volatile bool __otherCoreIdled = false;
int __holdUpPendSV = 0;
uint32_t* core1_separate_stack_address = nullptr;
};
mutex_t _pioMutex;
extern void setup();
extern void loop();
@@ -41,12 +39,14 @@ extern void startFreeRTOS() __attribute__((weak));
bool __isFreeRTOS;
volatile bool __freeRTOSinitted;
extern void __EnableBluetoothDebug(Print &);
// Weak empty variant initialization. May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
// Optional 2nd core setup and loop
bool core1_separate_stack __attribute__((weak)) = false;
extern void setup1() __attribute__((weak));
extern void loop1() __attribute__((weak));
extern "C" void main1() {
@@ -92,8 +92,6 @@ extern "C" int main() {
_REENT_INIT_PTR(_impure_ptr1);
}
mutex_init(&_pioMutex);
rp2040.begin();
initVariant();
@@ -122,6 +120,9 @@ extern "C" int main() {
#if defined DEBUG_RP2040_PORT
if (!__isFreeRTOS) {
DEBUG_RP2040_PORT.begin(115200);
#if (defined(ENABLE_BLUETOOTH) || defined(ENABLE_BLE)) && defined(DEBUG_RP2040_BLUETOOTH)
__EnableBluetoothDebug(DEBUG_RP2040_PORT);
#endif
}
#endif
@@ -137,7 +138,12 @@ extern "C" int main() {
if (!__isFreeRTOS) {
if (setup1 || loop1) {
delay(1); // Needed to make Picoprobe upload start 2nd core
multicore_launch_core1(main1);
if (core1_separate_stack) {
core1_separate_stack_address = (uint32_t*)malloc(0x2000);
multicore_launch_core1_with_stack(main1, core1_separate_stack_address, 0x2000);
} else {
multicore_launch_core1(main1);
}
}
setup();
while (true) {
@@ -163,6 +169,7 @@ extern "C" void __register_impure_ptr(struct _reent *p) {
}
}
extern "C" struct _reent *__wrap___getreent() __attribute__((weak));
extern "C" struct _reent *__wrap___getreent() {
if (get_core_num() == 0) {
return _impure_ptr;
+43 -2
View File
@@ -29,7 +29,7 @@
; We shift out the start and stop bit as part of the FIFO
set x, 9
pull side 1 ; Force stop bit
pull side 1 ; Force stop bit high
; Send the bits
bitloop:
@@ -41,6 +41,26 @@ wait_bit:
; inverted-logic version (inverts the stop bit)
.program pio_tx_inv
.side_set 1 opt
; We shift out the start and stop bit as part of the FIFO
set x, 9
pull side 0 ; Force stop bit low
; Send the bits
bitloop:
out pins, 1
mov y, isr ; ISR is loaded by the setup routine with the period-1 count
wait_bit:
jmp y-- wait_bit
jmp x-- bitloop
% c-sdk {
static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_tx) {
@@ -68,7 +88,7 @@ static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_t
}
%}
.program pio_rx
@@ -91,6 +111,27 @@ wait_half:
push ; Stuff it and wait for next start
.program pio_rx_inv
; IN pin 0 and JMP pin are both mapped to the GPIO used as UART RX.
start:
set x, 18 ; Preload bit counter...we'll shift in the start bit and stop bit, and each bit will be double-recorded (to be fixed by RP2040 code)
wait 1 pin 0 ; Stall until start bit is asserted
bitloop:
; Delay until 1/2 way into the bit time
mov y, osr
wait_half:
jmp y-- wait_half
; Read in the bit
in pins, 1 ; Shift data bit into ISR
jmp x-- bitloop ; Loop all bits
push ; Stuff it and wait for next start
% c-sdk {
static inline void pio_rx_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
+68
View File
@@ -2,6 +2,8 @@
// This file is autogenerated by pioasm; do not edit! //
// -------------------------------------------------- //
#pragma once
#if !PICO_NO_HARDWARE
#include "hardware/pio.h"
#endif
@@ -37,6 +39,39 @@ static inline pio_sm_config pio_tx_program_get_default_config(uint offset) {
sm_config_set_sideset(&c, 2, true, false);
return c;
}
#endif
// ---------- //
// pio_tx_inv //
// ---------- //
#define pio_tx_inv_wrap_target 0
#define pio_tx_inv_wrap 5
static const uint16_t pio_tx_inv_program_instructions[] = {
// .wrap_target
0xe029, // 0: set x, 9
0x90a0, // 1: pull block side 0
0x6001, // 2: out pins, 1
0xa046, // 3: mov y, isr
0x0084, // 4: jmp y--, 4
0x0042, // 5: jmp x--, 2
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program pio_tx_inv_program = {
.instructions = pio_tx_inv_program_instructions,
.length = 6,
.origin = -1,
};
static inline pio_sm_config pio_tx_inv_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + pio_tx_inv_wrap_target, offset + pio_tx_inv_wrap);
sm_config_set_sideset(&c, 2, true, false);
return c;
}
static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_tx) {
// Tell PIO to initially drive output-high on the selected pin, then map PIO
@@ -90,6 +125,39 @@ static inline pio_sm_config pio_rx_program_get_default_config(uint offset) {
sm_config_set_wrap(&c, offset + pio_rx_wrap_target, offset + pio_rx_wrap);
return c;
}
#endif
// ---------- //
// pio_rx_inv //
// ---------- //
#define pio_rx_inv_wrap_target 0
#define pio_rx_inv_wrap 6
static const uint16_t pio_rx_inv_program_instructions[] = {
// .wrap_target
0xe032, // 0: set x, 18
0x20a0, // 1: wait 1 pin, 0
0xa047, // 2: mov y, osr
0x0083, // 3: jmp y--, 3
0x4001, // 4: in pins, 1
0x0042, // 5: jmp x--, 2
0x8020, // 6: push block
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program pio_rx_inv_program = {
.instructions = pio_rx_inv_program_instructions,
.length = 7,
.origin = -1,
};
static inline pio_sm_config pio_rx_inv_program_get_default_config(uint offset) {
pio_sm_config c = pio_get_default_sm_config();
sm_config_set_wrap(&c, offset + pio_rx_inv_wrap_target, offset + pio_rx_inv_wrap);
return c;
}
static inline void pio_rx_program_init(PIO pio, uint sm, uint offset, uint pin) {
pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, false);
+39 -13
View File
@@ -33,7 +33,9 @@
extern "C" int errno;
extern "C" ssize_t _write(int fd, const void *buf, size_t count) {
extern "C"
__attribute((weak))
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);
@@ -45,7 +47,9 @@ extern "C" ssize_t _write(int fd, const void *buf, size_t count) {
#endif
}
extern "C" int _chown(const char *path, uid_t owner, gid_t group) {
extern "C"
__attribute((weak))
int _chown(const char *path, uid_t owner, gid_t group) {
(void) path;
(void) owner;
(void) group;
@@ -53,7 +57,9 @@ extern "C" int _chown(const char *path, uid_t owner, gid_t group) {
return -1;
}
extern "C" int _close(int fd) {
extern "C"
__attribute((weak))
int _close(int fd) {
(void) fd;
errno = ENOSYS;
return -1;
@@ -72,7 +78,9 @@ extern "C" int _fork(void) {
return -1;
}
extern "C" int _fstat(int fd, struct stat *st) {
extern "C"
__attribute((weak))
int _fstat(int fd, struct stat *st) {
(void) fd;
(void) st;
errno = ENOSYS;
@@ -115,7 +123,9 @@ extern "C" void __setSystemTime(unsigned long long sec, unsigned long usec) {
__timedelta_us = newnow_us - now_us;
}
extern "C" int _isatty(int file) {
extern "C"
__attribute((weak))
int _isatty(int file) {
(void) file;
errno = ENOSYS;
return 0;
@@ -128,14 +138,18 @@ extern "C" int _kill(int pid, int sig) {
return -1;
}
extern "C" int _link(char *existing, char *newlink) {
extern "C"
__attribute((weak))
int _link(char *existing, char *newlink) {
(void) existing;
(void) newlink;
errno = ENOSYS;
return -1;
}
extern "C" int _lseek(int file, int ptr, int dir) {
extern "C"
__attribute((weak))
int _lseek(int file, int ptr, int dir) {
(void) file;
(void) ptr;
(void) dir;
@@ -143,7 +157,9 @@ extern "C" int _lseek(int file, int ptr, int dir) {
return -1;
}
extern "C" int _open(char *file, int flags, int mode) {
extern "C"
__attribute((weak))
int _open(char *file, int flags, int mode) {
(void) file;
(void) flags;
(void) mode;
@@ -151,7 +167,9 @@ extern "C" int _open(char *file, int flags, int mode) {
return -1;
}
extern "C" int _read(int file, char *ptr, int len) {
extern "C"
__attribute((weak))
int _read(int file, char *ptr, int len) {
(void) file;
(void) ptr;
(void) len;
@@ -159,7 +177,9 @@ extern "C" int _read(int file, char *ptr, int len) {
return -1;
}
extern "C" int _readlink(const char *path, char *buf, size_t bufsize) {
extern "C"
__attribute((weak))
int _readlink(const char *path, char *buf, size_t bufsize) {
(void) path;
(void) buf;
(void) bufsize;
@@ -167,14 +187,18 @@ extern "C" int _readlink(const char *path, char *buf, size_t bufsize) {
return -1;
}
extern "C" int _stat(const char *file, struct stat *st) {
extern "C"
__attribute((weak))
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) {
extern "C"
__attribute((weak))
int _symlink(const char *path1, const char *path2) {
(void) path1;
(void) path2;
errno = ENOSYS;
@@ -187,7 +211,9 @@ extern "C" clock_t _times(struct tms *buf) {
return -1;
}
extern "C" int _unlink(char *name) {
extern "C"
__attribute((weak))
int _unlink(char *name) {
(void) name;
errno = ENOSYS;
return -1;
File diff suppressed because it is too large Load Diff
+443
View File
@@ -0,0 +1,443 @@
/*
Copyright (C) 2014 BlueKitchen GmbH
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
4. Any redistribution, use, or modification is done solely for
personal benefit and not for any commercial purpose or for
monetary gain.
THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Please inquire about commercial licensing options at
contact@bluekitchen-gmbh.com
*/
/**
@title ATT Database Engine
*/
#ifndef ATT_DB_H
#define ATT_DB_H
#if defined ENABLE_CLASSIC
#include <stdint.h>
#include <sdkoverride/bluetooth.h>
#include "btstack_linked_list.h"
#include "btstack_defines.h"
#include "btstack_bool.h"
#if defined __cplusplus
extern "C" {
#endif
// MARK: Attribute PDU Opcodes
#define ATT_ERROR_RESPONSE 0x01u
#define ATT_EXCHANGE_MTU_REQUEST 0x02u
#define ATT_EXCHANGE_MTU_RESPONSE 0x03u
#define ATT_FIND_INFORMATION_REQUEST 0x04u
#define ATT_FIND_INFORMATION_REPLY 0x05u
#define ATT_FIND_BY_TYPE_VALUE_REQUEST 0x06u
#define ATT_FIND_BY_TYPE_VALUE_RESPONSE 0x07u
#define ATT_READ_BY_TYPE_REQUEST 0x08u
#define ATT_READ_BY_TYPE_RESPONSE 0x09u
#define ATT_READ_REQUEST 0x0au
#define ATT_READ_RESPONSE 0x0bu
#define ATT_READ_BLOB_REQUEST 0x0cu
#define ATT_READ_BLOB_RESPONSE 0x0du
#define ATT_READ_MULTIPLE_REQUEST 0x0eu
#define ATT_READ_MULTIPLE_RESPONSE 0x0fu
#define ATT_READ_BY_GROUP_TYPE_REQUEST 0x10u
#define ATT_READ_BY_GROUP_TYPE_RESPONSE 0x11u
#define ATT_WRITE_REQUEST 0x12u
#define ATT_WRITE_RESPONSE 0x13u
#define ATT_PREPARE_WRITE_REQUEST 0x16u
#define ATT_PREPARE_WRITE_RESPONSE 0x17u
#define ATT_EXECUTE_WRITE_REQUEST 0x18u
#define ATT_EXECUTE_WRITE_RESPONSE 0x19u
#define ATT_HANDLE_VALUE_NOTIFICATION 0x1bu
#define ATT_HANDLE_VALUE_INDICATION 0x1du
#define ATT_HANDLE_VALUE_CONFIRMATION 0x1eu
#define ATT_READ_MULTIPLE_VARIABLE_REQ 0x20u
#define ATT_READ_MULTIPLE_VARIABLE_RSP 0x21u
#define ATT_MULTIPLE_HANDLE_VALUE_NTF 0x23u
#define ATT_WRITE_COMMAND 0x52u
#define ATT_SIGNED_WRITE_COMMAND 0xD2u
// internal additions
// 128 bit UUID used
#define ATT_PROPERTY_UUID128 0x200u
// Read/Write Permission bits
#define ATT_PROPERTY_READ_PERMISSION_BIT_0 0x0400u
#define ATT_PROPERTY_READ_PERMISSION_BIT_1 0x0800u
#define ATT_PROPERTY_WRITE_PERMISSION_BIT_0 0x0001u
#define ATT_PROPERTY_WRITE_PERMISSION_BIT_1 0x0010u
#define ATT_PROPERTY_READ_PERMISSION_SC 0x0020u
#define ATT_PROPERTY_WRITE_PERMISSION_SC 0x0080u
typedef struct att_connection {
hci_con_handle_t con_handle;
uint16_t mtu; // initialized to ATT_DEFAULT_MTU (23), negotiated during MTU exchange
uint16_t max_mtu; // local maximal L2CAP_MTU, set to l2cap_max_le_mtu()
bool mtu_exchanged;
uint8_t encryption_key_size;
uint8_t authenticated;
uint8_t authorized;
uint8_t secure_connection;
} att_connection_t;
/* API_START */
// map ATT ERROR CODES on to att_read_callback length
#define ATT_READ_ERROR_CODE_OFFSET 0xfe00u
// custom BTstack ATT Response Pending for att_read_callback
#define ATT_READ_RESPONSE_PENDING 0xffffu
// internally used to signal write response pending
#define ATT_INTERNAL_WRITE_RESPONSE_PENDING 0xfffeu
/**
@brief ATT Client Read Callback for Dynamic Data
- if buffer == NULL, don't copy data, just return size of value
- if buffer != NULL, copy data and return number bytes copied
If ENABLE_ATT_DELAYED_READ_RESPONSE is defined, you may return ATT_READ_RESPONSE_PENDING if data isn't available yet
@param con_handle of hci le connection
@param attribute_handle to be read
@param offset defines start of attribute value
@param buffer
@param buffer_size
@return size of value if buffer is NULL, otherwise number of bytes copied
*/
typedef uint16_t (*att_read_callback_t)(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size);
/**
@brief ATT Client Write Callback for Dynamic Data
Each Prepared Write Request triggers a callback with transaction mode ATT_TRANSACTION_MODE_ACTIVE.
On Execute Write, the callback will be called with ATT_TRANSACTION_MODE_VALIDATE and allows to validate all queued writes and return an application error.
If none of the registered callbacks return an error for ATT_TRANSACTION_MODE_VALIDATE and the callback will be called with ATT_TRANSACTION_MODE_EXECUTE.
Otherwise, all callbacks will be called with ATT_TRANSACTION_MODE_CANCEL.
If the additional validation step is not needed, just return 0 for all callbacks with transaction mode ATT_TRANSACTION_MODE_VALIDATE.
@param con_handle of hci le connection
@param attribute_handle to be written
@param transaction - ATT_TRANSACTION_MODE_NONE for regular writes. For prepared writes: ATT_TRANSACTION_MODE_ACTIVE, ATT_TRANSACTION_MODE_VALIDATE, ATT_TRANSACTION_MODE_EXECUTE, ATT_TRANSACTION_MODE_CANCEL
@param offset into the value - used for queued writes and long attributes
@param buffer
@param buffer_size
@param signature used for signed write commands
@return 0 if write was ok, ATT_ERROR_PREPARE_QUEUE_FULL if no space in queue, ATT_ERROR_INVALID_OFFSET if offset is larger than max buffer
*/
typedef int (*att_write_callback_t)(hci_con_handle_t con_handle, uint16_t attribute_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size);
// Read & Write Callbacks for handle range
typedef struct att_service_handler {
btstack_linked_item_t * item;
uint16_t start_handle;
uint16_t end_handle;
att_read_callback_t read_callback;
att_write_callback_t write_callback;
btstack_packet_handler_t packet_handler;
} att_service_handler_t;
// MARK: ATT Operations
/**
@brief setup ATT database
@param db
*/
void att_set_db(uint8_t const * db);
/*
@brief set callback for read of dynamic attributes
@param callback
*/
void att_set_read_callback(att_read_callback_t callback);
/**
@brief set callback for write of dynamic attributes
@param callback
*/
void att_set_write_callback(att_write_callback_t callback);
/**
@brief debug helper, dump ATT database to stdout using log_info
*/
void att_dump_attributes(void);
/**
@brief process ATT request against database and put response into response buffer
@param att_connection used for mtu and security properties
@param request_buffer, request_len: ATT request from client
@param response_buffer for result
@return len of data in response buffer. 0 = no response,
ATT_READ_RESPONSE_PENDING if it was returned at least once for dynamic data (requires ENABLE_ATT_DELAYED_READ_RESPONSE)
*/
uint16_t att_handle_request(att_connection_t * att_connection,
uint8_t * request_buffer,
uint16_t request_len,
uint8_t * response_buffer);
/**
@brief setup value notification in response buffer for a given handle and value
@param att_connection
@param attribute_handle
@param value
@param value_len
@param response_buffer for notification
*/
uint16_t att_prepare_handle_value_notification(att_connection_t * att_connection,
uint16_t attribute_handle,
const uint8_t *value,
uint16_t value_len,
uint8_t * response_buffer);
/**
@brief setup value notification in response buffer for multiple handles and values
@param att_connection
@param attribute_handle
@param value
@param value_len
@param response_buffer for notification
*/
uint16_t att_prepare_handle_value_multiple_notification(att_connection_t * att_connection,
uint8_t num_attributes,
const uint16_t * attribute_handles,
const uint8_t ** values_data,
const uint16_t * values_len,
uint8_t * response_buffer);
/**
@brief setup value indication in response buffer for a given handle and value
@param att_connection
@param attribute_handle
@param value
@param value_len
@param response_buffer for indication
*/
uint16_t att_prepare_handle_value_indication(att_connection_t * att_connection,
uint16_t attribute_handle,
const uint8_t *value,
uint16_t value_len,
uint8_t * response_buffer);
/**
@brief transaction queue of prepared writes, e.g., after disconnect
@return att_connection
*/
void att_clear_transaction_queue(att_connection_t * att_connection);
// att_read_callback helpers for a various data types
/**
@brief Handle read of blob like data for att_read_callback
@param blob of data
@param blob_size of blob
@param offset from att_read_callback
@param buffer from att_read_callback
@param buffer_size from att_read_callback
@return value size for buffer == 0 and num bytes copied otherwise
*/
uint16_t att_read_callback_handle_blob(const uint8_t * blob, uint16_t blob_size, uint16_t offset, uint8_t * buffer, uint16_t buffer_size);
/**
@brief Handle read of little endian unsigned 32 bit value for att_read_callback
@param value
@param offset from att_read_callback
@param buffer from att_read_callback
@param buffer_size from att_read_callback
@return value size for buffer == 0 and num bytes copied otherwise
*/
uint16_t att_read_callback_handle_little_endian_32(uint32_t value, uint16_t offset, uint8_t * buffer, uint16_t buffer_size);
/**
@brief Handle read of little endian unsigned 16 bit value for att_read_callback
@param value
@param offset from att_read_callback
@param buffer from att_read_callback
@param buffer_size from att_read_callback
@return value size for buffer == 0 and num bytes copied otherwise
*/
uint16_t att_read_callback_handle_little_endian_16(uint16_t value, uint16_t offset, uint8_t * buffer, uint16_t buffer_size);
/**
@brief Handle read of single byte for att_read_callback
@param blob of data
@param blob_size of blob
@param offset from att_read_callback
@param buffer from att_read_callback
@param buffer_size from att_read_callback
@return value size for buffer == 0 and num bytes copied otherwise
*/
uint16_t att_read_callback_handle_byte(uint8_t value, uint16_t offset, uint8_t * buffer, uint16_t buffer_size);
// experimental client API
/**
@brief Get UUID for handle
@param attribute_handle
@return 0 if not found
*/
uint16_t att_uuid_for_handle(uint16_t attribute_handle);
/**
@brief Get const value for handle
@param attribute_handle
@param out_value_len output variable that hold value len
@return value
*/
const uint8_t * gatt_server_get_const_value_for_handle(uint16_t attribute_handle, uint16_t * out_value_len);
// experimental GATT Server API
/**
@brief Get handle range for primary service.
@param uuid16
@param start_handle
@param end_handle
@return false if not found
*/
bool gatt_server_get_handle_range_for_service_with_uuid16(uint16_t uuid16, uint16_t * start_handle, uint16_t * end_handle);
/**
@brief Get handle range for included service.
@param start_handle
@param end_handle
@param uuid16
@param out_included_service_handle
@param out_included_service_start_handle
@param out_included_service_end_handle
@return false if not found
*/
bool gatt_server_get_included_service_with_uuid16(uint16_t start_handle, uint16_t end_handle, uint16_t uuid16,
uint16_t * out_included_service_handle, uint16_t * out_included_service_start_handle, uint16_t * out_included_service_end_handle);
/**
@brief Get value handle for characteristic.
@param start_handle
@param end_handle
@param uuid16
@return 0 if not found
*/
uint16_t gatt_server_get_value_handle_for_characteristic_with_uuid16(uint16_t start_handle, uint16_t end_handle, uint16_t uuid16);
/**
@brief Get descriptor handle for characteristic.
@param start_handle
@param end_handle
@param characteristic_uuid16
@param descriptor_uuid16
@return 0 if not found
*/
uint16_t gatt_server_get_descriptor_handle_for_characteristic_with_uuid16(uint16_t start_handle, uint16_t end_handle, uint16_t characteristic_uuid16, uint16_t descriptor_uuid16);
/**
@brief Get client configuration handle for characteristic.
@param start_handle
@param end_handle
@param characteristic_uuid16
@return 0 if not found
*/
uint16_t gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(uint16_t start_handle, uint16_t end_handle, uint16_t characteristic_uuid16);
/**
@brief Get server configuration handle for characteristic.
@param start_handle
@param end_handle
@param characteristic_uuid16
@param descriptor_uuid16
@return 0 if not found
*/
uint16_t gatt_server_get_server_configuration_handle_for_characteristic_with_uuid16(uint16_t start_handle, uint16_t end_handle, uint16_t characteristic_uuid16);
/**
@brief Get handle range for primary service.
@param uuid128
@param start_handle
@param end_handle
@return false if not found
*/
bool gatt_server_get_handle_range_for_service_with_uuid128(const uint8_t * uuid128, uint16_t * start_handle, uint16_t * end_handle);
/**
@brief Get value handle.
@param start_handle
@param end_handle
@param uuid128
@return 0 if not found
*/
uint16_t gatt_server_get_value_handle_for_characteristic_with_uuid128(uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128);
/**
@brief Get client configuration handle.
@param start_handle
@param end_handle
@param uuid128
@return 0 if not found
*/
uint16_t gatt_server_get_client_configuration_handle_for_characteristic_with_uuid128(uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128);
/* API_END */
// non-user functionality for att_server
/**
@brief Check if writes to handle should be persistent
@param handle
@return 1 if persistent
*/
bool att_is_persistent_ccc(uint16_t handle);
// auto-pts testing, returns response size
#ifdef ENABLE_BTP
uint16_t btp_att_get_attributes_by_uuid16(uint16_t start_handle, uint16_t end_handle, uint16_t uuid16, uint8_t * response_buffer, uint16_t response_buffer_size);
uint16_t btp_att_get_attributes_by_uuid128(uint16_t start_handle, uint16_t end_handle, const uint8_t * uuid128, uint8_t * response_buffer, uint16_t response_buffer_size);
uint16_t btp_att_get_attribute_value(att_connection_t * att_connection, uint16_t attribute_handle, uint8_t * response_buffer, uint16_t response_buffer_size);
#endif
#if defined __cplusplus
}
#endif
#endif
#endif // ATT_H
+926
View File
@@ -0,0 +1,926 @@
/*
Copyright (C) 2015 BlueKitchen GmbH
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
4. Any redistribution, use, or modification is done solely for
personal benefit and not for any commercial purpose or for
monetary gain.
THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Please inquire about commercial licensing options at
contact@bluekitchen-gmbh.com
*/
/*
bluetooth.h
Numbers defined or derived from the official Bluetooth specification
*/
#ifndef BLUETOOTH_H
#define BLUETOOTH_H
#include <stdint.h>
/**
@brief hci connection handle type
*/
typedef uint16_t hci_con_handle_t;
/**
@brief Length of a bluetooth device address.
*/
#define BD_ADDR_LEN 6
/**
@brief Bluetooth address
*/
typedef uint8_t bd_addr_t[BD_ADDR_LEN];
/**
Address types
*/
typedef enum {
// Public Device Address
BD_ADDR_TYPE_LE_PUBLIC = 0,
// Random Device Address
BD_ADDR_TYPE_LE_RANDOM = 1,
// Public Identity Address (Corresponds to Resolved Private Address)
BD_ADDR_TYPE_LE_PUBLIC_IDENTITY = 2,
// Random (static) Identity Address (Corresponds to Resolved Private Address)
BD_ADDR_TYPE_LE_RANDOM_IDENTITY = 3,
// internal BTstack addr types for Classic connections
BD_ADDR_TYPE_SCO = 0xfc,
BD_ADDR_TYPE_ACL = 0xfd,
BD_ADDR_TYPE_UNKNOWN = 0xfe, // also used as 'invalid'
} bd_addr_type_t;
/**
Link types for BR/EDR Connections
*/
typedef enum {
HCI_LINK_TYPE_SCO = 0,
HCI_LINK_TYPE_ACL = 1,
HCI_LINK_TYPE_ESCO = 2,
} hci_link_type_t;
/**
@brief link key
*/
#define LINK_KEY_LEN 16
#define LINK_KEY_STR_LEN (LINK_KEY_LEN*2)
typedef uint8_t link_key_t[LINK_KEY_LEN];
/**
@brief link key type
*/
typedef enum {
INVALID_LINK_KEY = 0xffff,
COMBINATION_KEY = 0, // standard pairing
LOCAL_UNIT_KEY, // ?
REMOTE_UNIT_KEY, // ?
DEBUG_COMBINATION_KEY, // SSP with debug
UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P192, // SSP Simple Pairing
AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P192, // SSP Passkey, Number confirm, OOB
CHANGED_COMBINATION_KEY, // Link key changed using Change Connection Lnk Key
UNAUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256, // SSP Simpe Pairing
AUTHENTICATED_COMBINATION_KEY_GENERATED_FROM_P256, // SSP Passkey, Number confirm, OOB
} link_key_type_t;
/**
LE Privacy 1.2
*/
typedef enum {
LE_PRIVACY_MODE_NETWORK = 0,
LE_PRIVACY_MODE_DEVICE = 1,
} le_privacy_mode_t;
/**
@brief Extended Inquiry Response
*/
#define EXTENDED_INQUIRY_RESPONSE_DATA_LEN 240
/**
@brief Inquiry modes
*/
typedef enum {
INQUIRY_MODE_STANDARD = 0,
INQUIRY_MODE_RSSI,
INQUIRY_MODE_RSSI_AND_EIR,
} inquiry_mode_t;
/**
@brief Page Scan Types
*/
typedef enum {
PAGE_SCAN_MODE_STANDARD = 0,
PAGE_SCAN_MODE_INTERLACED,
} page_scan_type_t;
/**
@brief Inquiry Scan Types
*/
typedef enum {
INQUIRY_SCAN_MODE_STANDARD = 0,
INQUIRY_SCAN_MODE_INTERLACED,
} inquiry_scan_type_t;
/**
Link Supervision Timeout Default, 0x7d00 * 0.625ms = 20s
*/
#define HCI_LINK_SUPERVISION_TIMEOUT_DEFAULT 0x7D00
/**
Service Type used for QoS Setup and Flow Specification
*/
typedef enum {
HCI_SERVICE_TYPE_NO_TRAFFIC = 0,
HCI_SERVICE_TYPE_BEST_EFFORT,
HCI_SERVICE_TYPE_GUARANTEED,
HCI_SERVICE_TYPE_INVALID,
} hci_service_type_t;
/**
HCI Transport
*/
/**
packet types - used in BTstack and over the H4 UART interface
*/
#define HCI_COMMAND_DATA_PACKET 0x01
#define HCI_ACL_DATA_PACKET 0x02
#define HCI_SCO_DATA_PACKET 0x03
#define HCI_EVENT_PACKET 0x04
#define HCI_ISO_DATA_PACKET 0x05
/**
Other assigned numbers, Assigned_Numbers_Host Controller Interface.pdf
*/
typedef enum {
HCI_AUDIO_CODING_FORMAT_U_LAW_LOG = 0x00,
HCI_AUDIO_CODING_FORMAT_A_LAW_LOG,
HCI_AUDIO_CODING_FORMAT_CVSD,
HCI_AUDIO_CODING_FORMAT_TRANSPARENT, // Indicates that the controller does not do any transcoding or resampling. This is also used for test mode.
HCI_AUDIO_CODING_FORMAT_LINEAR_PCM,
HCI_AUDIO_CODING_FORMAT_MSBC,
HCI_AUDIO_CODING_FORMAT_LC3,
HCI_AUDIO_CODING_FORMAT_G_729A,
HCI_AUDIO_CODING_FORMAT_RFU,
HCI_AUDIO_CODING_FORMAT_VENDOR_SPECIFIC = 0xFF
} hci_audio_coding_format_t;
/**
HCI Layer
*/
//
// Error Codes rfom Bluetooth Core Specification
//
/* ENUM_START: BLUETOOTH_ERROR_CODE */
#define ERROR_CODE_SUCCESS 0x00
#define ERROR_CODE_UNKNOWN_HCI_COMMAND 0x01
#define ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02
#define ERROR_CODE_HARDWARE_FAILURE 0x03
#define ERROR_CODE_PAGE_TIMEOUT 0x04
#define ERROR_CODE_AUTHENTICATION_FAILURE 0x05
#define ERROR_CODE_PIN_OR_KEY_MISSING 0x06
#define ERROR_CODE_MEMORY_CAPACITY_EXCEEDED 0x07
#define ERROR_CODE_CONNECTION_TIMEOUT 0x08
#define ERROR_CODE_CONNECTION_LIMIT_EXCEEDED 0x09
#define ERROR_CODE_SYNCHRONOUS_CONNECTION_LIMIT_TO_A_DEVICE_EXCEEDED 0x0A
#define ERROR_CODE_ACL_CONNECTION_ALREADY_EXISTS 0x0B
#define ERROR_CODE_COMMAND_DISALLOWED 0x0C
#define ERROR_CODE_CONNECTION_REJECTED_DUE_TO_LIMITED_RESOURCES 0x0D
#define ERROR_CODE_CONNECTION_REJECTED_DUE_TO_SECURITY_REASONS 0x0E
#define ERROR_CODE_CONNECTION_REJECTED_DUE_TO_UNACCEPTABLE_BD_ADDR 0x0F
#define ERROR_CODE_CONNECTION_ACCEPT_TIMEOUT_EXCEEDED 0x10
#define ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE 0x11
#define ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS 0x12
#define ERROR_CODE_REMOTE_USER_TERMINATED_CONNECTION 0x13
#define ERROR_CODE_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES 0x14
#define ERROR_CODE_REMOTE_DEVICE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF 0x15
#define ERROR_CODE_CONNECTION_TERMINATED_BY_LOCAL_HOST 0x16
#define ERROR_CODE_REPEATED_ATTEMPTS 0x17
#define ERROR_CODE_PAIRING_NOT_ALLOWED 0x18
#define ERROR_CODE_UNKNOWN_LMP_PDU 0x19
#define ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE_UNSUPPORTED_LMP_FEATURE 0x1A
#define ERROR_CODE_SCO_OFFSET_REJECTED 0x1B
#define ERROR_CODE_SCO_INTERVAL_REJECTED 0x1C
#define ERROR_CODE_SCO_AIR_MODE_REJECTED 0x1D
#define ERROR_CODE_INVALID_LMP_PARAMETERS_INVALID_LL_PARAMETERS 0x1E
#define ERROR_CODE_UNSPECIFIED_ERROR 0x1F
#define ERROR_CODE_UNSUPPORTED_LMP_PARAMETER_VALUE_UNSUPPORTED_LL_PARAMETER_VALUE 0x20
#define ERROR_CODE_ROLE_CHANGE_NOT_ALLOWED 0x21
#define ERROR_CODE_LMP_RESPONSE_TIMEOUT_LL_RESPONSE_TIMEOUT 0x22
#define ERROR_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23
#define ERROR_CODE_LMP_PDU_NOT_ALLOWED 0x24
#define ERROR_CODE_ENCRYPTION_MODE_NOT_ACCEPTABLE 0x25
#define ERROR_CODE_LINK_KEY_CANNOT_BE_CHANGED 0x26
#define ERROR_CODE_REQUESTED_QOS_NOT_SUPPORTED 0x27
#define ERROR_CODE_INSTANT_PASSED 0x28
#define ERROR_CODE_PAIRING_WITH_UNIT_KEY_NOT_SUPPORTED 0x29
#define ERROR_CODE_DIFFERENT_TRANSACTION_COLLISION 0x2A
#define ERROR_CODE_RESERVED 0x2B
#define ERROR_CODE_QOS_UNACCEPTABLE_PARAMETER 0x2C
#define ERROR_CODE_QOS_REJECTED 0x2D
#define ERROR_CODE_CHANNEL_CLASSIFICATION_NOT_SUPPORTED 0x2E
#define ERROR_CODE_INSUFFICIENT_SECURITY 0x2F
#define ERROR_CODE_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30
// #define ERROR_CODE_RESERVED
#define ERROR_CODE_ROLE_SWITCH_PENDING 0x32
// #define ERROR_CODE_RESERVED
#define ERROR_CODE_RESERVED_SLOT_VIOLATION 0x34
#define ERROR_CODE_ROLE_SWITCH_FAILED 0x35
#define ERROR_CODE_EXTENDED_INQUIRY_RESPONSE_TOO_LARGE 0x36
#define ERROR_CODE_SECURE_SIMPLE_PAIRING_NOT_SUPPORTED_BY_HOST 0x37
#define ERROR_CODE_HOST_BUSY_PAIRING 0x38
#define ERROR_CODE_CONNECTION_REJECTED_DUE_TO_NO_SUITABLE_CHANNEL_FOUND 0x39
#define ERROR_CODE_CONTROLLER_BUSY 0x3A
#define ERROR_CODE_UNACCEPTABLE_CONNECTION_PARAMETERS 0x3B
#define ERROR_CODE_DIRECTED_ADVERTISING_TIMEOUT 0x3C
#define ERROR_CODE_CONNECTION_TERMINATED_DUE_TO_MIC_FAILURE 0x3D
#define ERROR_CODE_CONNECTION_FAILED_TO_BE_ESTABLISHED 0x3E
#define ERROR_CODE_MAC_CONNECTION_FAILED 0x3F
#define ERROR_CODE_COARSE_CLOCK_ADJUSTMENT_REJECTED_BUT_WILL_TRY_TO_ADJUST_USING_CLOCK_DRAGGING 0x40
// BTstack defined ERRORS, mapped into BLuetooth status code range
#define BTSTACK_CONNECTION_TO_BTDAEMON_FAILED 0x50
#define BTSTACK_ACTIVATION_FAILED_SYSTEM_BLUETOOTH 0x51
#define BTSTACK_ACTIVATION_POWERON_FAILED 0x52
#define BTSTACK_ACTIVATION_FAILED_UNKNOWN 0x53
#define BTSTACK_NOT_ACTIVATED 0x54
#define BTSTACK_BUSY 0x55
#define BTSTACK_MEMORY_ALLOC_FAILED 0x56
#define BTSTACK_ACL_BUFFERS_FULL 0x57
// l2cap errors - enumeration by the command that created them
#define L2CAP_COMMAND_REJECT_REASON_COMMAND_NOT_UNDERSTOOD 0x60
#define L2CAP_COMMAND_REJECT_REASON_SIGNALING_MTU_EXCEEDED 0x61
#define L2CAP_COMMAND_REJECT_REASON_INVALID_CID_IN_REQUEST 0x62
#define L2CAP_CONNECTION_RESPONSE_RESULT_SUCCESSFUL 0x63
#define L2CAP_CONNECTION_RESPONSE_RESULT_PENDING 0x64
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_PSM 0x65
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_SECURITY 0x66
#define L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_RESOURCES 0x67
#define L2CAP_CONNECTION_RESPONSE_RESULT_ERTM_NOT_SUPPORTED 0x68
// should be L2CAP_CONNECTION_RTX_TIMEOUT
#define L2CAP_CONNECTION_RESPONSE_RESULT_RTX_TIMEOUT 0x69
#define L2CAP_CONNECTION_BASEBAND_DISCONNECT 0x6A
#define L2CAP_SERVICE_ALREADY_REGISTERED 0x6B
#define L2CAP_DATA_LEN_EXCEEDS_REMOTE_MTU 0x6C
#define L2CAP_SERVICE_DOES_NOT_EXIST 0x6D
#define L2CAP_LOCAL_CID_DOES_NOT_EXIST 0x6E
#define L2CAP_CONNECTION_RESPONSE_UNKNOWN_ERROR 0x6F
#define RFCOMM_MULTIPLEXER_STOPPED 0x70
#define RFCOMM_CHANNEL_ALREADY_REGISTERED 0x71
#define RFCOMM_NO_OUTGOING_CREDITS 0x72
#define RFCOMM_AGGREGATE_FLOW_OFF 0x73
#define RFCOMM_DATA_LEN_EXCEEDS_MTU 0x74
#define HFP_REMOTE_REJECTS_AUDIO_CONNECTION 0x7F
#define SDP_HANDLE_ALREADY_REGISTERED 0x80
#define SDP_QUERY_INCOMPLETE 0x81
#define SDP_SERVICE_NOT_FOUND 0x82
#define SDP_HANDLE_INVALID 0x83
#define SDP_QUERY_BUSY 0x84
#define ATT_HANDLE_VALUE_INDICATION_IN_PROGRESS 0x90
#define ATT_HANDLE_VALUE_INDICATION_TIMEOUT 0x91
#define ATT_HANDLE_VALUE_INDICATION_DISCONNECT 0x92
#define GATT_CLIENT_NOT_CONNECTED 0x93
#define GATT_CLIENT_BUSY 0x94
#define GATT_CLIENT_IN_WRONG_STATE 0x95
#define GATT_CLIENT_DIFFERENT_CONTEXT_FOR_ADDRESS_ALREADY_EXISTS 0x96
#define GATT_CLIENT_VALUE_TOO_LONG 0x97
#define GATT_CLIENT_CHARACTERISTIC_NOTIFICATION_NOT_SUPPORTED 0x98
#define GATT_CLIENT_CHARACTERISTIC_INDICATION_NOT_SUPPORTED 0x99
#define BNEP_SERVICE_ALREADY_REGISTERED 0xA0
#define BNEP_CHANNEL_NOT_CONNECTED 0xA1
#define BNEP_DATA_LEN_EXCEEDS_MTU 0xA2
// OBEX ERRORS
#define OBEX_UNKNOWN_ERROR 0xB0
#define OBEX_CONNECT_FAILED 0xB1
#define OBEX_DISCONNECTED 0xB2
#define OBEX_NOT_FOUND 0xB3
#define OBEX_NOT_ACCEPTABLE 0xB4
#define OBEX_ABORTED 0xB5
#define MESH_ERROR_APPKEY_INDEX_INVALID 0xD0
/* ENUM_END */
/* ENUM_START: AVRCP_BROWSING_ERROR_CODE */
#define AVRCP_BROWSING_ERROR_CODE_INVALID_COMMAND 0x00 // Sent if TG received a PDU that it did not understand. Valid for All.
#define AVRCP_BROWSING_ERROR_CODE_INVALID_PARAMETER 0x01 // Sent if the TG received a PDU with a parameter ID that it did not understand. Sent if there is only one parameter ID in the PDU. Valid for All.
#define AVRCP_BROWSING_ERROR_CODE_SPECIFIED_PARAMETER_NOT_FOUND 0x02 // Sent if the parameter ID is understood, but content is wrong or corrupted. Valid for All.
#define AVRCP_BROWSING_ERROR_CODE_INTERNAL_ERROR 0x03 // Sent if there are error conditions not covered by a more specific error code. Valid for All.
#define AVRCP_BROWSING_ERROR_CODE_SUCCESS 0x04 // This is the status that should be returned if the operation was successful. Valid for All except where the response CType is AV/C REJECTED.
#define AVRCP_BROWSING_ERROR_CODE_UID_CHANGED 0x05 // The UIDs on the device have changed. Valid for All.
#define AVRCP_BROWSING_ERROR_CODE_RESERVED_06 0x06 // Valid for All.
#define AVRCP_BROWSING_ERROR_CODE_INVALID_DIRECTION 0x07 // The Direction parameter is invalid. Valid for Change Path.
#define AVRCP_BROWSING_ERROR_CODE_NOT_A_DIRECTORY 0x08 // The UID provided does not refer to a folder item. Valid for Change Path.
#define AVRCP_BROWSING_ERROR_CODE_DOES_NOT_EXIST 0x09 // The UID provided does not refer to any currently valid. Valid for Change Path, PlayItem, AddToNowPlaying, GetItemAttributes.
#define AVRCP_BROWSING_ERROR_CODE_INVALID_SCOPE 0x0a // The scope parameter is invalid. Valid for GetFolderItems, PlayItem, AddToNowPlayer, GetItemAttributes,.
#define AVRCP_BROWSING_ERROR_CODE_RANGE_OUT_OF_BOUNDS 0x0b // The start of range provided is not valid. Valid for GetFolderItems.
#define AVRCP_BROWSING_ERROR_CODE_UID_IS_A_DIRECTORY 0x0c // The UID provided refers to a directory, which cannot be handled by this media player. Valid for PlayItem, AddToNowPlaying.
#define AVRCP_BROWSING_ERROR_CODE_MEDIA_IN_USES 0x0d // The media is not able to be used for this operation at this time. Valid for PlayItem, AddToNowPlaying.
#define AVRCP_BROWSING_ERROR_CODE_NOW_PLAYING_LIST_FULL 0x0e // No more items can be added to the Now Playing List. Valid for AddToNowPlaying.
#define AVRCP_BROWSING_ERROR_CODE_SEARCH_NOT_SUPPORTED 0x0f // The Browsed Media Player does not support search. Valid for Search.
#define AVRCP_BROWSING_ERROR_CODE_SEARCH_IN_PROGRESS 0x10 // A search operation is already in progress. Valid for Search.
#define AVRCP_BROWSING_ERROR_CODE_INVALID_PLAYER_ID 0x11 // The specified Player Id does not refer to a valid player. Valid for SetAddressedPlayer, SetBrowsedPlayer.
#define AVRCP_BROWSING_ERROR_CODE_PLAYER_NOT_BROWSABLE 0x12 // The Player Id supplied refers to a Media Player which does not support browsing. Valid for SetBrowsedPlayer.
#define AVRCP_BROWSING_ERROR_CODE_PLAYER_NOT_ADDRESSED 0x13 // The Player Id supplied refers to a player which is not currently addressed, and the command is not able to be performed if the player is not set as addressed. Valid for Search SetBrowsedPlayer.
#define AVRCP_BROWSING_ERROR_CODE_NO_VALID_SEARCH_RESULTS 0x14 // The Search result list does not contain valid entries, e.g. after being invalidated due to change of browsed player. Valid for GetFolderItems.
#define AVRCP_BROWSING_ERROR_CODE_NO_AVAILABLE_PLAYERS 0x15 // Valid for All.
#define AVRCP_BROWSING_ERROR_CODE_ADDRESSED_PLAYER_CHANGED 0x16 // Valid for Register Notification.
// 0x17-0xff Reserved
/* ENUM_END */
// HCI roles
typedef enum {
HCI_ROLE_MASTER = 0,
HCI_ROLE_SLAVE = 1,
HCI_ROLE_INVALID = 0xff,
} hci_role_t;
// packet sizes (max payload)
#define HCI_ACL_DM1_SIZE 17
#define HCI_ACL_DH1_SIZE 27
#define HCI_ACL_2DH1_SIZE 54
#define HCI_ACL_3DH1_SIZE 83
#define HCI_ACL_DM3_SIZE 121
#define HCI_ACL_DH3_SIZE 183
#define HCI_ACL_DM5_SIZE 224
#define HCI_ACL_DH5_SIZE 339
#define HCI_ACL_2DH3_SIZE 367
#define HCI_ACL_3DH3_SIZE 552
#define HCI_ACL_2DH5_SIZE 679
#define HCI_ACL_3DH5_SIZE 1021
#define HCI_SCO_HV1_SIZE 10
#define HCI_SCO_HV2_SIZE 20
#define HCI_SCO_HV3_SIZE 30
#define HCI_SCO_EV3_SIZE 30
#define HCI_SCO_EV4_SIZE 120
#define HCI_SCO_EV5_SIZE 180
#define HCI_SCO_2EV3_SIZE 60
#define HCI_SCO_2EV5_SIZE 360
#define HCI_SCO_3EV3_SIZE 90
#define HCI_SCO_3EV5_SIZE 540
#define LE_ADVERTISING_DATA_SIZE 31
#define LE_EXTENDED_ADVERTISING_DATA_SIZE 229
#define LE_EXTENDED_ADVERTISING_MAX_HANDLE 0xEFu
#define LE_EXTENDED_ADVERTISING_MAX_CHUNK_LEN 251
// advertising event properties for extended advertising
#define LE_ADVERTISING_PROPERTIES_CONNECTABLE (1u<<0)
#define LE_ADVERTISING_PROPERTIES_SCANNABLE (1u<<1)
#define LE_ADVERTISING_PROPERTIES_DIRECTED (1u<<2)
#define LE_ADVERTISING_PROPERTIES_HIGH_DUTY_CYCLE (1u<<3)
#define LE_ADVERTISING_PROPERTIES_LEGACY (1u<<4)
#define LE_ADVERTISING_PROPERTIES_ANONYMOUS (1u<<5)
#define LE_ADVERTISING_PROPERTIES_INCLUDE_TX_POWER (1u<<6)
// SCO Packet Types
#define SCO_PACKET_TYPES_NONE 0x0000
#define SCO_PACKET_TYPES_HV1 0x0001
#define SCO_PACKET_TYPES_HV2 0x0002
#define SCO_PACKET_TYPES_HV3 0x0004
#define SCO_PACKET_TYPES_EV3 0x0008
#define SCO_PACKET_TYPES_EV4 0x0010
#define SCO_PACKET_TYPES_EV5 0x0020
#define SCO_PACKET_TYPES_2EV3 0x0040
#define SCO_PACKET_TYPES_3EV3 0x0080
#define SCO_PACKET_TYPES_2EV5 0x0100
#define SCO_PACKET_TYPES_3EV5 0x0200
#define SCO_PACKET_TYPES_ALL 0x03FF
#define SCO_PACKET_TYPES_SCO 0x0007
#define SCO_PACKET_TYPES_ESCO 0x03F8
// Link Policy Settings
#define LM_LINK_POLICY_DISABLE_ALL_LM_MODES 0
#define LM_LINK_POLICY_ENABLE_ROLE_SWITCH 1
#define LM_LINK_POLICY_ENABLE_HOLD_MODE 2
#define LM_LINK_POLICY_ENABLE_SNIFF_MODE 4
// ACL Connection Modes
#define ACL_CONNECTION_MODE_ACTIVE 0
#define ACL_CONNECTION_MODE_HOLD 1
#define ACL_CONNECTION_MODE_SNIFF 2
/**
Default INQ Mode
*/
#define GAP_IAC_GENERAL_INQUIRY 0x9E8B33L // General/Unlimited Inquiry Access Code (GIAC)
#define GAP_IAC_LIMITED_INQUIRY 0x9E8B00L // Limited Dedicated Inquiry Access Code (LIAC)
/**
SSP IO Capabilities
*/
#define SSP_IO_CAPABILITY_DISPLAY_ONLY 0
#define SSP_IO_CAPABILITY_DISPLAY_YES_NO 1
#define SSP_IO_CAPABILITY_KEYBOARD_ONLY 2
#define SSP_IO_CAPABILITY_NO_INPUT_NO_OUTPUT 3
#define SSP_IO_CAPABILITY_UNKNOWN 0xff
/**
SSP Authentication Requirements, see IO Capability Request Reply Command
*/
// Numeric comparison with automatic accept allowed.
#define SSP_IO_AUTHREQ_MITM_PROTECTION_NOT_REQUIRED_NO_BONDING 0x00
// Use IO Capabilities to deter- mine authentication procedure
#define SSP_IO_AUTHREQ_MITM_PROTECTION_REQUIRED_NO_BONDING 0x01
// Numeric compar- ison with automatic accept allowed.
#define SSP_IO_AUTHREQ_MITM_PROTECTION_NOT_REQUIRED_DEDICATED_BONDING 0x02
// Use IO Capabilities to determine authentication procedure
#define SSP_IO_AUTHREQ_MITM_PROTECTION_REQUIRED_DEDICATED_BONDING 0x03
// Numeric Compari- son with automatic accept allowed.
#define SSP_IO_AUTHREQ_MITM_PROTECTION_NOT_REQUIRED_GENERAL_BONDING 0x04
// Use IO capabilities to determine authentication procedure.
#define SSP_IO_AUTHREQ_MITM_PROTECTION_REQUIRED_GENERAL_BONDING 0x05
// OGFs
#define OGF_LINK_CONTROL 0x01
#define OGF_LINK_POLICY 0x02
#define OGF_CONTROLLER_BASEBAND 0x03
#define OGF_INFORMATIONAL_PARAMETERS 0x04
#define OGF_STATUS_PARAMETERS 0x05
#define OGF_TESTING 0x06
#define OGF_LE_CONTROLLER 0x08
#define OGF_VENDOR 0x3f
/**
L2CAP Layer
*/
#define L2CAP_HEADER_SIZE 4
// minimum signaling MTU
#define L2CAP_MINIMAL_MTU 48
#define L2CAP_DEFAULT_MTU 672
// Minimum/default MTU
#define L2CAP_LE_DEFAULT_MTU 23
// L2CAP Fixed Channel IDs
#define L2CAP_CID_SIGNALING 0x0001
#define L2CAP_CID_CONNECTIONLESS_CHANNEL 0x0002
#define L2CAP_CID_ATTRIBUTE_PROTOCOL 0x0004
#define L2CAP_CID_SIGNALING_LE 0x0005
#define L2CAP_CID_SECURITY_MANAGER_PROTOCOL 0x0006
#define L2CAP_CID_BR_EDR_SECURITY_MANAGER 0x0007
// L2CAP Channels in Basic and Enhanced Retransmission Mode
// connection response result
#define L2CAP_CONNECTION_RESULT_SUCCESS 0x0000
#define L2CAP_CONNECTION_RESULT_PENDING 0x0001
#define L2CAP_CONNECTION_RESULT_PSM_NOT_SUPPORTED 0x0002
#define L2CAP_CONNECTION_RESULT_SECURITY_BLOCK 0x0003
#define L2CAP_CONNECTION_RESULT_NO_RESOURCES_AVAILABLE 0x0004
#define L2CAP_CONNECTION_RESULT_INVALID_SOURCE_CID 0x0006
#define L2CAP_CONNECTION_RESULT_SOURCE_CID_ALREADY_ALLOCATED 0x0007
// L2CAP Channels in LE Credit-Based Flow-Control Mode
// connection response result
#define L2CAP_CBM_CONNECTION_RESULT_SUCCESS 0x0000
#define L2CAP_CBM_CONNECTION_RESULT_SPSM_NOT_SUPPORTED 0x0002
#define L2CAP_CBM_CONNECTION_RESULT_NO_RESOURCES_AVAILABLE 0x0004
#define L2CAP_CBM_CONNECTION_RESULT_INSUFFICIENT_AUTHENTICATION 0x0005
#define L2CAP_CBM_CONNECTION_RESULT_INSUFFICIENT_AUTHORIZATION 0x0006
#define L2CAP_CBM_CONNECTION_RESULT_ENCYRPTION_KEY_SIZE_TOO_SHORT 0x0007
#define L2CAP_CBM_CONNECTION_RESULT_INSUFFICIENT_ENCRYPTION 0x0008
#define L2CAP_CBM_CONNECTION_RESULT_INVALID_SOURCE_CID 0x0009
#define L2CAP_CBM_CONNECTION_RESULT_SOURCE_CID_ALREADY_ALLOCATED 0x000A
#define L2CAP_CBM_CONNECTION_RESULT_UNACCEPTABLE_PARAMETERS 0x000B
// L2CAP Channels in Enhanced Credit-Based Flow-Control Mode
// number of CIDs in single connection+reconfiguration request/response
#define L2CAP_ECBM_MAX_CID_ARRAY_SIZE 5
// connection response result
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_SUCCESS 0x0000
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_REFUSED_SPSM_NOT_SUPPORTED 0x0002
#define L2CAP_ECBM_CONNECTION_RESULT_SOME_REFUSED_INSUFFICIENT_RESOURCES_AVAILABLE 0x0004
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_REFUSED_INSUFFICIENT_AUTHENTICATION 0x0005
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_REFUSED_INSUFFICIENT_AUTHORIZATION 0x0006
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_REFUSED_ENCYRPTION_KEY_SIZE_TOO_SHORT 0x0007
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_REFUSED_INSUFFICIENT_ENCRYPTION 0x0008
#define L2CAP_ECBM_CONNECTION_RESULT_SOME_REFUSED_INVALID_SOURCE_CID 0x0009
#define L2CAP_ECBM_CONNECTION_RESULT_SOME_REFUSED_SOURCE_CID_ALREADY_ALOCATED 0x000A
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_REFUSED_UNACCEPTABLE_PARAMETERS 0x000B
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_REFUSED_INVALID_PARAMETERS 0x000C
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_PENDING_NO_FURTHER_INFORMATION 0x000D
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_PENDING_AUTHENTICATION 0x000E
#define L2CAP_ECBM_CONNECTION_RESULT_ALL_PENDING_AUTHORIZATION 0x000F
// Result for Reconfigure Request
#define L2CAP_ECBM_RECONFIGURE_SUCCESS 0
#define L2CAP_ECBM_RECONFIGURE_FAILED_MTU_REDUCTION_NOT_ALLOWED 1
#define L2CAP_ECBM_RECONFIGURE_FAILED_MPS_REDUCTION_MULTIPLE_CHANNELS 2
#define L2CAP_ECBM_RECONFIGURE_FAILED_DESTINATION_CID_INVALID 3
#define L2CAP_ECBM_RECONFIGURE_FAILED_UNACCEPTABLE_PARAMETERS 4
/**
SDP Protocol
*/
// Device Vendor ID Sources
#define DEVICE_ID_VENDOR_ID_SOURCE_BLUETOOTH 0x0001
#define DEVICE_ID_VENDOR_ID_SOURCE_USB 0x0002
// OBEX
#define SDP_vCard_2_1 0x01
#define SDP_vCard_3_0 0x02
#define SDP_vCal_1_0 0x03
#define SDP_iCal_2_0 0x04
#define SDP_vNote 0x05
#define SDP_vMessage 0x06
#define SDP_OBEXFileTypeAny 0xFF
/**
RFCOMM Protocol
*/
// Line Status
#define LINE_STATUS_NO_ERROR 0x00
#define LINE_STATUS_OVERRUN_ERROR 0x03
#define LINE_STATUS_PARITY_ERORR 0x05
#define LINE_STATUS_FRAMING_ERROR 0x09
// Modem Status Flags
#define MODEM_STATUS_FC 0x02
#define MODEM_STATUS_RTC 0x04
#define MODEM_STATUS_RTR 0x08
#define MODEM_STATUS_IC 0x40
#define MODEM_STATUS_DV 0x80
typedef enum rpn_baud {
RPN_BAUD_2400 = 0,
RPN_BAUD_4800,
RPN_BAUD_7200,
RPN_BAUD_9600,
RPN_BAUD_19200,
RPN_BAUD_38400,
RPN_BAUD_57600,
RPN_BAUD_115200,
RPN_BAUD_230400
} rpn_baud_t;
typedef enum rpn_data_bits {
RPN_DATA_BITS_5 = 0,
RPN_DATA_BITS_6 = 0,
RPN_DATA_BITS_7 = 0,
RPN_DATA_BITS_8 = 0
} rpn_data_bits_t;
typedef enum rpn_stop_bits {
RPN_STOP_BITS_1_0 = 0,
RPN_STOP_BITS_1_5
} rpn_stop_bits_t;
typedef enum rpn_parity {
RPN_PARITY_NONE = 0,
RPN_PARITY_ODD = 1,
RPN_PARITY_EVEN = 3,
RPN_PARITY_MARK = 5,
RPN_PARITY_SPACE = 7,
} rpn_parity_t;
#define RPN_FLOW_CONTROL_XONXOFF_ON_INPUT 0x01
#define RPN_FLOW_CONTROL_XONXOFF_ON_OUTPUT 0x02
#define RPN_FLOW_CONTROL_RTR_ON_INPUT 0x04
#define RPN_FLOW_CONTROL_RTR_ON_OUTPUT 0x08
#define RPN_FLOW_CONTROL_RTC_ON_INPUT 0x10
#define RPN_FLOW_CONTROL_RTC_ON_OUTPUT 0x20
#define RPN_PARAM_MASK_0_BAUD 0x01
#define RPN_PARAM_MASK_0_DATA_BITS 0x02
#define RPN_PARAM_MASK_0_STOP_BITS 0x04
#define RPN_PARAM_MASK_0_PARITY 0x08
#define RPN_PARAM_MASK_0_PARITY_TYPE 0x10
#define RPN_PARAM_MASK_0_XON_CHAR 0x20
#define RPN_PARAM_MASK_0_XOFF_CHAR 0x40
#define RPN_PARAM_MASK_0_RESERVED 0x80
// @note: values are identical to rpn_flow_control_t
#define RPN_PARAM_MASK_1_XONOFF_ON_INPUT 0x01
#define RPN_PARAM_MASK_1_XONOFF_ON_OUTPUT 0x02
#define RPN_PARAM_MASK_1_RTR_ON_INPUT 0x04
#define RPN_PARAM_MASK_1_RTR_ON_OUTPUT 0x08
#define RPN_PARAM_MASK_1_RTC_ON_INPUT 0x10
#define RPN_PARAM_MASK_1_RTC_ON_OUTPUT 0x20
#define RPN_PARAM_MASK_1_RESERVED_0 0x40
#define RPN_PARAM_MASK_1_RESERVED_1 0x80
/**
BNEP Protocol
*/
#ifndef ETHER_ADDR_LEN
#define ETHER_ADDR_LEN 6
#endif
#ifndef ETHERTYPE_VLAN
#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tag */
#endif
#define BNEP_MTU_MIN 1691
/**
PAN Profile
*/
typedef enum {
BNEP_SECURITY_NONE = 0x0000,
BNEP_SECURITY_SERVICE_LEVEL_ENFORCED,
BNEP_SECURITY_802_1X
} security_description_t;
typedef enum {
PAN_NET_ACCESS_TYPE_PSTN = 0x0000,
PAN_NET_ACCESS_TYPE_ISDN,
PAN_NET_ACCESS_TYPE_DSL,
PAN_NET_ACCESS_TYPE_CABLE_MODEM,
PAN_NET_ACCESS_TYPE_10MB_ETHERNET,
PAN_NET_ACCESS_TYPE_100MB_ETHERNET,
PAN_NET_ACCESS_TYPE_4MB_TOKEN_RING,
PAN_NET_ACCESS_TYPE_16MB_TOKEN_RING,
PAN_NET_ACCESS_TYPE_100MB_TOKEN_RING,
PAN_NET_ACCESS_TYPE_FDDI,
PAN_NET_ACCESS_TYPE_GSM,
PAN_NET_ACCESS_TYPE_CDMA,
PAN_NET_ACCESS_TYPE_GPRS,
PAN_NET_ACCESS_TYPE_3G,
PAN_NET_ACCESS_TYPE_CELULAR,
PAN_NET_ACCESS_TYPE_OTHER = 0xFFFE,
PAN_NET_ACCESS_TYPE_NONE
} net_access_type_t;
/**
ATT
*/
// Minimum/default MTU
#define ATT_DEFAULT_MTU 23
// MARK: ATT Error Codes
#define ATT_ERROR_SUCCESS 0x00
#define ATT_ERROR_INVALID_HANDLE 0x01
#define ATT_ERROR_READ_NOT_PERMITTED 0x02
#define ATT_ERROR_WRITE_NOT_PERMITTED 0x03
#define ATT_ERROR_INVALID_PDU 0x04
#define ATT_ERROR_INSUFFICIENT_AUTHENTICATION 0x05
#define ATT_ERROR_REQUEST_NOT_SUPPORTED 0x06
#define ATT_ERROR_INVALID_OFFSET 0x07
#define ATT_ERROR_INSUFFICIENT_AUTHORIZATION 0x08
#define ATT_ERROR_PREPARE_QUEUE_FULL 0x09
#define ATT_ERROR_ATTRIBUTE_NOT_FOUND 0x0a
#define ATT_ERROR_ATTRIBUTE_NOT_LONG 0x0b
#define ATT_ERROR_INSUFFICIENT_ENCRYPTION_KEY_SIZE 0x0c
#define ATT_ERROR_INVALID_ATTRIBUTE_VALUE_LENGTH 0x0d
#define ATT_ERROR_UNLIKELY_ERROR 0x0e
#define ATT_ERROR_INSUFFICIENT_ENCRYPTION 0x0f
#define ATT_ERROR_UNSUPPORTED_GROUP_TYPE 0x10
#define ATT_ERROR_INSUFFICIENT_RESOURCES 0x11
#define ATT_ERROR_VALUE_NOT_ALLOWED 0x13
// MARK: ATT Error Codes defined by BTstack
#define ATT_ERROR_HCI_DISCONNECT_RECEIVED 0x1f
#define ATT_ERROR_BONDING_INFORMATION_MISSING 0x70
#define ATT_ERROR_DATA_MISMATCH 0x7e
#define ATT_ERROR_TIMEOUT 0x7F
#define ATT_ERROR_WRITE_RESPONSE_PENDING 0x100
// MARK: ATT Error Codes from Bluetooth Core Specification Supplement, Version 9 or later
#define ATT_ERROR_WRITE_REQUEST_REJECTED 0xFC
#define ATT_ERROR_CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR_IMPROPERLY_CONFIGURED 0xFD
#define ATT_ERROR_PROCEDURE_ALREADY_IN_PROGRESS 0xFE
#define ATT_ERROR_OUT_OF_RANGE 0xFF
// MARK: ATT Error Codes from Cycling Power Service spec
#define CYCLING_POWER_ERROR_CODE_INAPPROPRIATE_CONNECTION_PARAMETERS 0x80
#define CYCLING_POWER_ERROR_CODE_PROCEDURE_ALREADY_IN_PROGRESS 0xFE
#define CYCLING_POWER_ERROR_CODE_CCC_DESCRIPTOR_IMPROPERLY_CONFIGURED 0xFD
// MARK: ATT Error Codes from Cycling Speed and Cadence Service spec
#define CYCLING_SPEED_AND_CADENCE_ERROR_CODE_PROCEDURE_ALREADY_IN_PROGRESS 0x80
#define CYCLING_SPEED_AND_CADENCE_ERROR_CODE_CCC_DESCRIPTOR_IMPROPERLY_CONFIGURED 0x81
// MARK: Attribute Property Flags
#define ATT_PROPERTY_BROADCAST 0x01
#define ATT_PROPERTY_READ 0x02
#define ATT_PROPERTY_WRITE_WITHOUT_RESPONSE 0x04
#define ATT_PROPERTY_WRITE 0x08
#define ATT_PROPERTY_NOTIFY 0x10
#define ATT_PROPERTY_INDICATE 0x20
#define ATT_PROPERTY_AUTHENTICATED_SIGNED_WRITE 0x40
#define ATT_PROPERTY_EXTENDED_PROPERTIES 0x80
// MARK: Attribute Property Flag, BTstack extension
// value is asked from client
#define ATT_PROPERTY_DYNAMIC 0x100
// Security levels
#define ATT_SECURITY_NONE 0
#define ATT_SECURITY_ENCRYPTED 1
#define ATT_SECURITY_AUTHENTICATED 2
#define ATT_SECURITY_AUTHORIZED 3
#define ATT_SECURITY_AUTHENTICATED_SC 4
// ATT Transaction Timeout of 30 seconds for Command/Response or Indication/Confirmation
#define ATT_TRANSACTION_TIMEOUT_MS 30000
#define ATT_TRANSACTION_MODE_NONE 0x0
#define ATT_TRANSACTION_MODE_ACTIVE 0x1
#define ATT_TRANSACTION_MODE_EXECUTE 0x2
#define ATT_TRANSACTION_MODE_CANCEL 0x3
#define ATT_TRANSACTION_MODE_VALIDATE 0x4
// MARK: GATT UUIDs
#define GATT_PRIMARY_SERVICE_UUID 0x2800
#define GATT_SECONDARY_SERVICE_UUID 0x2801
#define GATT_INCLUDE_SERVICE_UUID 0x2802
#define GATT_CHARACTERISTICS_UUID 0x2803
#define GATT_CHARACTERISTIC_EXTENDED_PROPERTIES 0x2900
#define GATT_CHARACTERISTIC_USER_DESCRIPTION 0x2901
#define GATT_CLIENT_CHARACTERISTICS_CONFIGURATION 0x2902
#define GATT_SERVER_CHARACTERISTICS_CONFIGURATION 0x2903
#define GATT_CHARACTERISTIC_PRESENTATION_FORMAT 0x2904
#define GATT_CHARACTERISTIC_AGGREGATE_FORMAT 0x2905
#define GATT_CLIENT_SUPPORTED_FEATURES 0x2B29
#define GATT_SERVER_SUPPORTED_FEATURES 0x2B3A
#define GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NONE 0
#define GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATION 1
#define GATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION 2
#define GATT_CLIENT_ANY_CONNECTION 0xffff
#define GATT_CLIENT_ANY_VALUE_HANDLE 0x0000
// GAP Service and Characteristics
#define GAP_SERVICE_UUID 0x1800
#define GAP_DEVICE_NAME_UUID 0x2a00
#define GAP_APPEARANCE_UUID 0x2a01
#define GAP_PERIPHERAL_PRIVACY_FLAG 0x2a02
#define GAP_RECONNECTION_ADDRESS_UUID 0x2a03
#define GAP_PERIPHERAL_PREFERRED_CONNECTION_PARAMETERS_UUID 0x2a04
#define GAP_SERVICE_CHANGED 0x2a05
// Bluetooth GATT types
typedef struct {
uint16_t year; // 0 - year is not known; or [1582,9999]
uint8_t month; // 0 - month is not known; or [1,12]
uint8_t day; // 0 - day is not known; or [1,31]
uint8_t hours; // [0,23]
uint8_t minutes; // [0,59]
uint8_t seconds; // [0,59]
} gatt_date_time_t;
typedef enum {
GATT_MICROPHONE_CONTROL_MUTE_OFF = 0x00,
GATT_MICROPHONE_CONTROL_MUTE_ON,
GATT_MICROPHONE_CONTROL_MUTE_DISABLED
} gatt_microphone_control_mute_t;
/**
SM - LE Security Manager
*/
// Bluetooth Spec definitions
typedef enum {
SM_CODE_PAIRING_REQUEST = 0X01,
SM_CODE_PAIRING_RESPONSE,
SM_CODE_PAIRING_CONFIRM,
SM_CODE_PAIRING_RANDOM,
SM_CODE_PAIRING_FAILED,
SM_CODE_ENCRYPTION_INFORMATION,
SM_CODE_MASTER_IDENTIFICATION,
SM_CODE_IDENTITY_INFORMATION,
SM_CODE_IDENTITY_ADDRESS_INFORMATION,
SM_CODE_SIGNING_INFORMATION,
SM_CODE_SECURITY_REQUEST,
SM_CODE_PAIRING_PUBLIC_KEY,
SM_CODE_PAIRING_DHKEY_CHECK,
SM_CODE_KEYPRESS_NOTIFICATION,
} SECURITY_MANAGER_COMMANDS;
// IO Capability Values
typedef enum {
IO_CAPABILITY_DISPLAY_ONLY = 0,
IO_CAPABILITY_DISPLAY_YES_NO,
IO_CAPABILITY_KEYBOARD_ONLY,
IO_CAPABILITY_NO_INPUT_NO_OUTPUT,
IO_CAPABILITY_KEYBOARD_DISPLAY, // not used by secure simple pairing
} io_capability_t;
// Authentication requirement flags
#define SM_AUTHREQ_NO_BONDING 0x00
#define SM_AUTHREQ_BONDING 0x01
#define SM_AUTHREQ_MITM_PROTECTION 0x04
#define SM_AUTHREQ_SECURE_CONNECTION 0x08
#define SM_AUTHREQ_KEYPRESS 0x10
#define SM_AUTHREQ_CT2 0x20
// Key distribution flags used by spec
#define SM_KEYDIST_ENC_KEY 0x01
#define SM_KEYDIST_ID_KEY 0x02
#define SM_KEYDIST_SIGN 0x04
#define SM_KEYDIST_LINK_KEY 0x08
// Key distribution flags used internally
#define SM_KEYDIST_FLAG_ENCRYPTION_INFORMATION 0x01
#define SM_KEYDIST_FLAG_MASTER_IDENTIFICATION 0x02
#define SM_KEYDIST_FLAG_IDENTITY_INFORMATION 0x04
#define SM_KEYDIST_FLAG_IDENTITY_ADDRESS_INFORMATION 0x08
#define SM_KEYDIST_FLAG_SIGNING_IDENTIFICATION 0x10
// STK Generation Methods
#define SM_STK_GENERATION_METHOD_JUST_WORKS 0x01
#define SM_STK_GENERATION_METHOD_OOB 0x02
#define SM_STK_GENERATION_METHOD_PASSKEY 0x04
#define SM_STK_GENERATION_METHOD_NUMERIC_COMPARISON 0x08
// Pairing Failed Reasons
#define SM_REASON_RESERVED 0x00
#define SM_REASON_PASSKEY_ENTRY_FAILED 0x01
#define SM_REASON_OOB_NOT_AVAILABLE 0x02
#define SM_REASON_AUTHENTHICATION_REQUIREMENTS 0x03
#define SM_REASON_CONFIRM_VALUE_FAILED 0x04
#define SM_REASON_PAIRING_NOT_SUPPORTED 0x05
#define SM_REASON_ENCRYPTION_KEY_SIZE 0x06
#define SM_REASON_COMMAND_NOT_SUPPORTED 0x07
#define SM_REASON_UNSPECIFIED_REASON 0x08
#define SM_REASON_REPEATED_ATTEMPTS 0x09
#define SM_REASON_INVALID_PARAMETERS 0x0a
#define SM_REASON_DHKEY_CHECK_FAILED 0x0b
#define SM_REASON_NUMERIC_COMPARISON_FAILED 0x0c
#define SM_REASON_BR_EDR_PAIRING_IN_PROGRESS 0x0d
#define SM_REASON_CROSS_TRANSPORT_KEY_DERIVATION_NOT_ALLOWED 0x0e
#define SM_REASON_KEY_REJECTED 0x0f
// also, invalid parameters
// and reserved
// Keypress Notifications
#define SM_KEYPRESS_PASSKEY_ENTRY_STARTED 0x00
#define SM_KEYPRESS_PASSKEY_DIGIT_ENTERED 0x01
#define SM_KEYPRESS_PASSKEY_DIGIT_ERASED 0x02
#define SM_KEYPRESS_PASSKEY_CLEARED 0x03
#define SM_KEYPRESS_PASSKEY_ENTRY_COMPLETED 0x04
#endif
+524
View File
@@ -0,0 +1,524 @@
/*
Copyright (C) 2014 BlueKitchen GmbH
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
4. Any redistribution, use, or modification is done solely for
personal benefit and not for any commercial purpose or for
monetary gain.
THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Please inquire about commercial licensing options at
contact@bluekitchen-gmbh.com
*/
#if defined ENABLE_CLASSIC
#define BTSTACK_FILE__ "hids_device.c"
/**
Implementation of the GATT HIDS Device
To use with your application, add '#import <hids.gatt>' to your .gatt file
*/
#include "hids_device.h"
#include "ble/att_db.h"
#include "ble/att_server.h"
#include "bluetooth_gatt.h"
#include "btstack_util.h"
#include "btstack_debug.h"
#define HIDS_DEVICE_ERROR_CODE_INAPPROPRIATE_CONNECTION_PARAMETERS 0x80
// storage for 'generic' HID Device with single Input, Output, and Feature Report
static hids_device_report_t hid_reports_generic_storage[3];
typedef struct {
uint16_t con_handle;
uint8_t hid_country_code;
const uint8_t * hid_descriptor;
uint16_t hid_descriptor_size;
uint16_t hid_report_map_handle;
uint8_t hid_protocol_mode;
uint16_t hid_protocol_mode_value_handle;
uint16_t hid_boot_mouse_input_value_handle;
uint16_t hid_boot_mouse_input_client_configuration_handle;
uint16_t hid_boot_mouse_input_client_configuration_value;
uint16_t hid_boot_keyboard_input_value_handle;
uint16_t hid_boot_keyboard_input_client_configuration_handle;
uint16_t hid_boot_keyboard_input_client_configuration_value;
hids_device_report_t * hid_reports;
uint8_t hid_input_reports_num;
uint8_t hid_output_reports_num;
uint8_t hid_feature_reports_num;
uint16_t hid_control_point_value_handle;
uint8_t hid_control_point_suspend;
btstack_context_callback_registration_t battery_callback;
} hids_device_t;
static hids_device_t hids_device;
static btstack_packet_handler_t packet_handler;
static att_service_handler_t hid_service;
// TODO: store hids device connection into list
static hids_device_t * hids_device_get_instance_for_con_handle(uint16_t con_handle) {
UNUSED(con_handle);
return &hids_device;
}
static hids_device_t * hids_device_create_instance(void) {
memset(&hids_device, 0, sizeof(hids_device_t));
return &hids_device;
}
static hids_device_report_t * hids_device_get_report_for_client_configuration_handle(hids_device_t * device, uint16_t client_configuration_handle) {
uint8_t pos;
uint8_t total_reports = device->hid_input_reports_num + device->hid_output_reports_num + device->hid_feature_reports_num;
for (pos = 0 ; pos < total_reports ; pos++) {
if (device->hid_reports[pos].client_configuration_handle == client_configuration_handle) {
return &device->hid_reports[pos];
}
}
return NULL;
}
static hids_device_report_t *
hids_device_get_report_for_id_and_type(hids_device_t *device, uint16_t report_id, hid_report_type_t type) {
uint8_t pos;
uint8_t total_reports = device->hid_input_reports_num + device->hid_output_reports_num + device->hid_feature_reports_num;
for (pos = 0 ; pos < total_reports ; pos++) {
if ((device->hid_reports[pos].type == type) && (device->hid_reports[pos].id == report_id)) {
return &device->hid_reports[pos];
}
}
return NULL;
}
static void hids_device_emit_event_with_uint8(uint8_t event, hci_con_handle_t con_handle, uint8_t value) {
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return;
}
if (!packet_handler) {
return;
}
uint8_t buffer[6];
buffer[0] = HCI_EVENT_HIDS_META;
buffer[1] = 4;
buffer[2] = event;
little_endian_store_16(buffer, 3, (uint16_t) con_handle);
buffer[5] = value;
(*packet_handler)(HCI_EVENT_PACKET, 0, buffer, sizeof(buffer));
}
static void hids_device_emit_event_with_uint8_uint8_t(uint8_t event, hci_con_handle_t con_handle, uint8_t value_1, uint8_t value_2) {
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return;
}
if (!packet_handler) {
return;
}
uint8_t buffer[7];
buffer[0] = HCI_EVENT_HIDS_META;
buffer[1] = 4;
buffer[2] = event;
little_endian_store_16(buffer, 3, (uint16_t) con_handle);
buffer[5] = value_1;
buffer[6] = value_2;
(*packet_handler)(HCI_EVENT_PACKET, 0, buffer, sizeof(buffer));
}
static void hids_device_emit_event(uint8_t event, hci_con_handle_t con_handle) {
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return;
}
if (!packet_handler) {
return;
}
uint8_t buffer[5];
buffer[0] = HCI_EVENT_HIDS_META;
buffer[1] = 4;
buffer[2] = event;
little_endian_store_16(buffer, 3, (uint16_t) con_handle);
(*packet_handler)(HCI_EVENT_PACKET, 0, buffer, sizeof(buffer));
}
static void hids_device_can_send_now(void * context) {
hci_con_handle_t con_handle = (hci_con_handle_t)(uintptr_t) context;
// notify client
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return;
}
if (!packet_handler) {
return;
}
uint8_t buffer[5];
buffer[0] = HCI_EVENT_HIDS_META;
buffer[1] = 3;
buffer[2] = HIDS_SUBEVENT_CAN_SEND_NOW;
little_endian_store_16(buffer, 3, (uint16_t) con_handle);
(*packet_handler)(HCI_EVENT_PACKET, 0, buffer, sizeof(buffer));
}
// ATT Client Read Callback for Dynamic Data
// - if buffer == NULL, don't copy data, just return size of value
// - if buffer != NULL, copy data and return number bytes copied
static uint16_t att_read_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size) {
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return HIDS_DEVICE_ERROR_CODE_INAPPROPRIATE_CONNECTION_PARAMETERS;
}
if (att_handle == instance->hid_protocol_mode_value_handle) {
log_info("Read protocol mode");
return att_read_callback_handle_byte(instance->hid_protocol_mode, offset, buffer, buffer_size);
}
if (att_handle == instance->hid_report_map_handle) {
log_info("Read report map");
return att_read_callback_handle_blob(instance->hid_descriptor, instance->hid_descriptor_size, offset, buffer, buffer_size);
}
if (att_handle == instance->hid_boot_mouse_input_client_configuration_handle) {
return att_read_callback_handle_little_endian_16(instance->hid_boot_mouse_input_client_configuration_value, offset, buffer, buffer_size);
}
if (att_handle == instance->hid_boot_keyboard_input_client_configuration_handle) {
return att_read_callback_handle_little_endian_16(instance->hid_boot_keyboard_input_client_configuration_value, offset, buffer, buffer_size);
}
if (att_handle == instance->hid_control_point_value_handle) {
if (buffer && (buffer_size >= 1u)) {
buffer[0] = instance->hid_control_point_suspend;
}
return 1;
}
hids_device_report_t * report = hids_device_get_report_for_client_configuration_handle(instance, att_handle);
if (report != NULL) {
return att_read_callback_handle_little_endian_16(report->client_configuration_value, offset, buffer, buffer_size);
}
return 0;
}
static int att_write_callback(hci_con_handle_t con_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size) {
UNUSED(transaction_mode);
UNUSED(buffer_size);
UNUSED(offset);
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return HIDS_DEVICE_ERROR_CODE_INAPPROPRIATE_CONNECTION_PARAMETERS;
}
if (att_handle == instance->hid_boot_mouse_input_client_configuration_handle) {
uint16_t new_value = little_endian_read_16(buffer, 0);
instance->hid_boot_mouse_input_client_configuration_value = new_value;
hids_device_emit_event_with_uint8(HIDS_SUBEVENT_BOOT_MOUSE_INPUT_REPORT_ENABLE, con_handle, (uint8_t) new_value);
}
if (att_handle == instance->hid_boot_keyboard_input_client_configuration_handle) {
uint16_t new_value = little_endian_read_16(buffer, 0);
instance->hid_boot_keyboard_input_client_configuration_value = new_value;
hids_device_emit_event_with_uint8(HIDS_SUBEVENT_BOOT_KEYBOARD_INPUT_REPORT_ENABLE, con_handle, (uint8_t) new_value);
}
if (att_handle == instance->hid_protocol_mode_value_handle) {
instance->hid_protocol_mode = buffer[0];
log_info("Set protocol mode: %u", instance->hid_protocol_mode);
hids_device_emit_event_with_uint8(HIDS_SUBEVENT_PROTOCOL_MODE, con_handle, instance->hid_protocol_mode);
}
if (att_handle == instance->hid_control_point_value_handle) {
if (buffer_size < 1u) {
return ATT_ERROR_INVALID_OFFSET;
}
instance->hid_control_point_suspend = buffer[0];
instance->con_handle = con_handle;
log_info("Set suspend tp: %u", instance->hid_control_point_suspend);
if (instance->hid_control_point_suspend == 0u) {
hids_device_emit_event(HIDS_SUBEVENT_SUSPEND, con_handle);
} else if (instance->hid_control_point_suspend == 1u) {
hids_device_emit_event(HIDS_SUBEVENT_EXIT_SUSPEND, con_handle);
}
}
hids_device_report_t * report = hids_device_get_report_for_client_configuration_handle(instance, att_handle);
if (report != NULL) {
uint16_t new_value = little_endian_read_16(buffer, 0);
report->client_configuration_value = new_value;
log_info("Enable Report (type %u) notifications: %x", (uint8_t) report->type, new_value);
switch (report->type) {
case HID_REPORT_TYPE_INPUT:
hids_device_emit_event_with_uint8_uint8_t(HIDS_SUBEVENT_INPUT_REPORT_ENABLE, con_handle, report->id, (uint8_t) new_value);
break;
case HID_REPORT_TYPE_OUTPUT:
hids_device_emit_event_with_uint8_uint8_t(HIDS_SUBEVENT_OUTPUT_REPORT_ENABLE, con_handle, report->id, (uint8_t) new_value);
break;
case HID_REPORT_TYPE_FEATURE:
hids_device_emit_event_with_uint8_uint8_t(HIDS_SUBEVENT_FEATURE_REPORT_ENABLE, con_handle, report->id, (uint8_t) new_value);
break;
default:
btstack_unreachable();
break;
}
}
return 0;
}
void hids_device_init_with_storage(uint8_t hid_country_code, const uint8_t * hid_descriptor, uint16_t hid_descriptor_size,
uint16_t num_reports, hids_device_report_t * report_storage) {
hids_device_t * instance = hids_device_create_instance();
btstack_assert(num_reports > 0);
btstack_assert(report_storage != NULL);
instance->hid_country_code = hid_country_code;
instance->hid_descriptor = hid_descriptor;
instance->hid_descriptor_size = hid_descriptor_size;
// default
instance->hid_protocol_mode = 1;
// get service handle range
uint16_t start_handle = 0;
uint16_t end_handle = 0xffff;
int service_found = gatt_server_get_handle_range_for_service_with_uuid16(ORG_BLUETOOTH_SERVICE_HUMAN_INTERFACE_DEVICE, &start_handle, &end_handle);
btstack_assert(service_found != 0);
UNUSED(service_found);
// get report map handle
instance->hid_report_map_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(start_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_REPORT_MAP);
// get report map handle
instance->hid_protocol_mode_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(start_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_PROTOCOL_MODE);
// get value and client configuration handles for boot mouse input, boot keyboard input and report input
instance->hid_boot_mouse_input_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(start_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_BOOT_MOUSE_INPUT_REPORT);
instance->hid_boot_mouse_input_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(start_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_BOOT_MOUSE_INPUT_REPORT);
instance->hid_boot_keyboard_input_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(start_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_INPUT_REPORT);
instance->hid_boot_keyboard_input_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(start_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_BOOT_KEYBOARD_INPUT_REPORT);
instance->hid_control_point_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(start_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_HID_CONTROL_POINT);
log_info("hid_report_map_handle 0x%02x", instance->hid_report_map_handle);
log_info("hid_protocol_mode_value_handle 0x%02x", instance->hid_protocol_mode_value_handle);
log_info("hid_boot_mouse_input_value_handle 0x%02x", instance->hid_boot_mouse_input_value_handle);
log_info("hid_boot_mouse_input_client_configuration_handle 0x%02x", instance->hid_boot_mouse_input_client_configuration_handle);
log_info("hid_boot_keyboard_input_value_handle 0x%02x", instance->hid_boot_keyboard_input_value_handle);
log_info("hid_boot_keyboard_input_client_configuration_handle 0x%02x", instance->hid_boot_keyboard_input_client_configuration_handle);
log_info("hid_control_point_value_handle 0x%02x", instance->hid_control_point_value_handle);
instance->hid_reports = report_storage;
uint16_t hid_reports_num = num_reports;
uint16_t assigned_reports_num = 0;
uint16_t start_chr_handle = start_handle;
while ((start_chr_handle < end_handle) && (assigned_reports_num < hid_reports_num)) {
// mandatory
uint16_t chr_value_handle = gatt_server_get_value_handle_for_characteristic_with_uuid16(start_chr_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_REPORT);
if (chr_value_handle == 0) {
break;
}
// optional
uint16_t chr_client_configuration_handle = gatt_server_get_client_configuration_handle_for_characteristic_with_uuid16(start_chr_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_REPORT);
// mandatory
uint16_t report_reference_handle = gatt_server_get_descriptor_handle_for_characteristic_with_uuid16(start_chr_handle, end_handle, ORG_BLUETOOTH_CHARACTERISTIC_REPORT, ORG_BLUETOOTH_DESCRIPTOR_REPORT_REFERENCE);
if (report_reference_handle == 0) {
break;
}
// get report id and type from report reference
uint16_t report_reference_value_len;
const uint8_t * report_reference_value = gatt_server_get_const_value_for_handle(report_reference_handle, &report_reference_value_len);
if (report_reference_value == NULL) {
break;
}
if (report_reference_value_len != 2) {
break;
}
uint8_t report_id = report_reference_value[0];
hid_report_type_t report_type = (hid_report_type_t) report_reference_value[1];
// store report info
hids_device_report_t * report = &report_storage[assigned_reports_num];
report->value_handle = chr_value_handle;
report->client_configuration_handle = chr_client_configuration_handle;
report->client_configuration_value = 0;
report->id = report_id;
report->type = report_type;
switch (report->type) {
case HID_REPORT_TYPE_INPUT:
instance->hid_input_reports_num++;
break;
case HID_REPORT_TYPE_OUTPUT:
instance->hid_output_reports_num++;
break;
case HID_REPORT_TYPE_FEATURE:
instance->hid_feature_reports_num++;
break;
default:
btstack_unreachable();
return;
}
log_info("hid_report_value_handle 0x%02x, id %u, type %u", report->value_handle, report->id, (uint8_t)report->type);
if (report->client_configuration_handle != 0) {
log_info("hid_report_client_configuration_handle 0x%02x", report->client_configuration_handle);
}
assigned_reports_num++;
start_chr_handle = report_reference_handle + 1;
}
// register service with ATT Server
hid_service.start_handle = start_handle;
hid_service.end_handle = end_handle;
hid_service.read_callback = &att_read_callback;
hid_service.write_callback = &att_write_callback;
att_server_register_service_handler(&hid_service);
}
/**
@brief Set up HIDS Device
*/
void hids_device_init(uint8_t country_code, const uint8_t * descriptor, uint16_t descriptor_size) {
uint16_t hid_reports_num = sizeof(hid_reports_generic_storage) / sizeof(hids_device_report_t);
hids_device_init_with_storage(country_code, descriptor, descriptor_size, hid_reports_num, hid_reports_generic_storage);
}
/**
@brief Register callback for the HIDS Device client.
@param callback
*/
void hids_device_register_packet_handler(btstack_packet_handler_t callback) {
packet_handler = callback;
}
/**
@brief Request can send now event to send HID Report
Generates an HIDS_SUBEVENT_CAN_SEND_NOW subevent
@param hid_cid
*/
void hids_device_request_can_send_now_event(hci_con_handle_t con_handle) {
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return;
}
instance->battery_callback.callback = &hids_device_can_send_now;
instance->battery_callback.context = (void*)(uintptr_t) con_handle;
att_server_register_can_send_now_callback(&instance->battery_callback, con_handle);
}
uint8_t hids_device_send_input_report_for_id(hci_con_handle_t con_handle, uint16_t report_id, const uint8_t * report, uint16_t report_len) {
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
hids_device_report_t * report_storage = hids_device_get_report_for_id_and_type(instance, report_id,
HID_REPORT_TYPE_INPUT);
if (report_storage == NULL) {
return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
}
return att_server_notify(con_handle, report_storage->value_handle, report, report_len);
}
uint8_t hids_device_send_input_report(hci_con_handle_t con_handle, const uint8_t * report, uint16_t report_len) {
hids_device_t * device = hids_device_get_instance_for_con_handle(con_handle);
if (!device) {
log_error("no instance for handle 0x%02x", con_handle);
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
uint8_t pos;
uint8_t total_reports = device->hid_input_reports_num + device->hid_output_reports_num + device->hid_feature_reports_num;
for (pos = 0 ; pos < total_reports ; pos++) {
hids_device_report_t * report_storage = &device->hid_reports[pos];
if (report_storage->type == HID_REPORT_TYPE_INPUT) {
return att_server_notify(con_handle, report_storage->value_handle, report, report_len);
}
}
return ERROR_CODE_UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
}
/**
@brief Send HID Boot Mouse Input Report
*/
uint8_t hids_device_send_boot_mouse_input_report(hci_con_handle_t con_handle, const uint8_t * report, uint16_t report_len) {
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
return att_server_notify(con_handle, instance->hid_boot_mouse_input_value_handle, report, report_len);
}
/**
@brief Send HID Boot Mouse Input Report
*/
uint8_t hids_device_send_boot_keyboard_input_report(hci_con_handle_t con_handle, const uint8_t * report, uint16_t report_len) {
hids_device_t * instance = hids_device_get_instance_for_con_handle(con_handle);
if (!instance) {
log_error("no instance for handle 0x%02x", con_handle);
return ERROR_CODE_UNKNOWN_CONNECTION_IDENTIFIER;
}
return att_server_notify(con_handle, instance->hid_boot_keyboard_input_value_handle, report, report_len);
}
#endif
+143
View File
@@ -0,0 +1,143 @@
/*
Copyright (C) 2014 BlueKitchen GmbH
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
4. Any redistribution, use, or modification is done solely for
personal benefit and not for any commercial purpose or for
monetary gain.
THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Please inquire about commercial licensing options at
contact@bluekitchen-gmbh.com
*/
/**
@title HID Service Server
*/
#ifndef HIDS_DEVICE_H
#define HIDS_DEVICE_H
#if defined ENABLE_CLASSIC
#include <sdkoverride/att_db.h>
#include <stdint.h>
#include "btstack_defines.h"
#include "btstack_hid.h"
#include "bluetooth.h"
#if defined __cplusplus
extern "C" {
#endif
/* API_START */
typedef struct {
uint16_t value_handle;
uint16_t client_configuration_handle;
uint16_t client_configuration_value;
hid_report_type_t type;
uint16_t id;
} hids_device_report_t;
/**
@text Implementation of the GATT HIDS Device
To use with your application, add '#import <hids.gatt>' to your .gatt file
*/
/**
@brief Set up HIDS Device with single INPUT, OUTPUT and FEATURE report
*/
void hids_device_init(uint8_t hid_country_code, const uint8_t * hid_descriptor, uint16_t hid_descriptor_size);
/**
@brief Set up HIDS Device for multiple instances of INPUT, OUTPUT and FEATURE reports
*/
void hids_device_init_with_storage(uint8_t hid_country_code, const uint8_t * hid_descriptor, uint16_t hid_descriptor_size,
uint16_t num_reports, hids_device_report_t * report_storage);
/**
@brief Register callback for the HIDS Device client.
@param callback
*/
void hids_device_register_packet_handler(btstack_packet_handler_t callback);
/**
@brief Request can send now event to send HID Report
Generates an HIDS_SUBEVENT_CAN_SEND_NOW subevent
@param hid_cid
*/
void hids_device_request_can_send_now_event(hci_con_handle_t con_handle);
/**
@brief Send HID Input Report for Report ID
@param con_handle
@param report_id
@param report
@param report_len
@returns status
*/
uint8_t hids_device_send_input_report_for_id(hci_con_handle_t con_handle, uint16_t report_id, const uint8_t * report, uint16_t report_len);
/**
@brief Send HID Input Report for first Input Report
@param con_handle
@param report
@param report_len
@returns status
*/
uint8_t hids_device_send_input_report(hci_con_handle_t con_handle, const uint8_t * report, uint16_t report_len);
/**
@brief Send HID Boot Mouse Input Report
@param con_handle
@param report
@param report_len
@returns status
*/
uint8_t hids_device_send_boot_mouse_input_report(hci_con_handle_t con_handle, const uint8_t * report, uint16_t report_len);
/**
@brief Send HID Boot Mouse Input Report
@param con_handle
@param report
@param report_len
@returns status
*/
uint8_t hids_device_send_boot_keyboard_input_report(hci_con_handle_t con_handle, const uint8_t * report, uint16_t report_len);
/* API_END */
#if defined __cplusplus
}
#endif
#endif
#endif
+121
View File
@@ -0,0 +1,121 @@
// Taken from LWIP's inet_chksum.c just to set the -O2 flag
/*
Copyright (c) 2001-2004 Swedish Institute of Computer Science.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
This file is part of the lwIP TCP/IP stack.
Author: Adam Dunkels <adam@sics.se>
*/
#include "lwip/opt.h"
#include "lwip/inet_chksum.h"
#include "lwip/def.h"
#include "lwip/ip_addr.h"
#pragma GCC optimize ("O2")
/**
An optimized checksum routine. Basically, it uses loop-unrolling on
the checksum loop, treating the head and tail bytes specially, whereas
the inner loop acts on 8 bytes at a time.
@arg start of buffer to be checksummed. May be an odd byte address.
@len number of bytes in the buffer to be checksummed.
@return host order (!) lwip checksum (non-inverted Internet sum)
by Curt McDowell, Broadcom Corp. December 8th, 2005
*/
extern "C" u16_t lwip_standard_chksum(const void *dataptr, int len) {
const u8_t *pb = (const u8_t *)dataptr;
const u16_t *ps;
u16_t t = 0;
const u32_t *pl;
u32_t sum = 0, tmp;
/* starts at odd byte address? */
int odd = ((mem_ptr_t)pb & 1);
if (odd && len > 0) {
((u8_t *)&t)[1] = *pb++;
len--;
}
ps = (const u16_t *)(const void *)pb;
if (((mem_ptr_t)ps & 3) && len > 1) {
sum += *ps++;
len -= 2;
}
pl = (const u32_t *)(const void *)ps;
while (len > 7) {
tmp = sum + *pl++; /* ping */
if (tmp < sum) {
tmp++; /* add back carry */
}
sum = tmp + *pl++; /* pong */
if (sum < tmp) {
sum++; /* add back carry */
}
len -= 8;
}
/* make room in upper bits */
sum = FOLD_U32T(sum);
ps = (const u16_t *)pl;
/* 16-bit aligned word remaining? */
while (len > 1) {
sum += *ps++;
len -= 2;
}
/* dangling tail byte remaining? */
if (len > 0) { /* include odd byte */
((u8_t *)&t)[0] = *(const u8_t *)ps;
}
sum += t; /* add end bytes */
/* Fold 32-bit sum to 16 bits
calling this twice is probably faster than if statements... */
sum = FOLD_U32T(sum);
sum = FOLD_U32T(sum);
if (odd) {
sum = SWAP_BYTES_IN_WORD(sum);
}
return (u16_t)sum;
}
@@ -6,10 +6,9 @@
SPDX-License-Identifier: BSD-3-Clause
*/
#include "pico.h"
#include "pico/time.h"
#include "pico/bootrom.h"
#include "pico/binary_info.h"
#include <pico/time.h>
#include <pico/bootrom.h>
#include <pico/binary_info.h>
// PICO_CONFIG: PICO_BOOTSEL_VIA_DOUBLE_RESET_TIMEOUT_MS, Window of opportunity for a second press of a reset button to enter BOOTSEL mode (milliseconds), type=int, default=200, group=pico_bootsel_via_double_reset
#ifndef PICO_BOOTSEL_VIA_DOUBLE_RESET_TIMEOUT_MS
+1 -1
View File
@@ -77,7 +77,7 @@ static std::map<pin_size_t, CBInfo> _map;
void _gpioInterruptDispatcher(uint gpio, uint32_t events) {
(void) events;
// Only need to lock around the std::map check, not the whole IRQ callback
CoreMutex m(&_irqMutex, (FromISR | DebugEnable));
CoreMutex m(&_irqMutex);
if (m) {
auto irq = _map.find(gpio);
if (irq != _map.end()) {
+5 -1
View File
@@ -66,10 +66,14 @@ typedef enum {
} wl_status_t;
/* Encryption modes */
enum wl_enc_type { /* Values map to 802.11 encryption suites... */
enum wl_enc_type { /* Values map to 802.11 Cipher Algorithm Identifier */
ENC_TYPE_WEP = 5,
ENC_TYPE_TKIP = 2,
ENC_TYPE_WPA = ENC_TYPE_TKIP,
ENC_TYPE_CCMP = 4,
ENC_TYPE_WPA2 = ENC_TYPE_CCMP,
ENC_TYPE_GCMP = 6,
ENC_TYPE_WPA3 = ENC_TYPE_GCMP,
/* ... except these two, 7 and 8 are reserved in 802.11-2007 */
ENC_TYPE_NONE = 7,
ENC_TYPE_AUTO = 8,
+39
View File
@@ -0,0 +1,39 @@
Bluetooth Audio (A2DP Source and Sink)
======================================
The PicoW can be used as a Bluetooth Audio sink or source with the ``BluetoothAudio`` class.
Operation is generally handled "automatically" in the background so while the audio is
playing or streaming the main application can perform other operations (like displaying
playback info, polling buttons for controls, etc.)
.. code :: cpp
#include <BluetoothAudio.h>
...
**Note about CPU usage:** Bluetooth SBC audio is a compressed format. That means
that it takes non-trivial amounts of CPU to compress on send, or decompress on receive.
Transmitting precompressed audio from, say, MP3 or AAC, requires first decompressing
the source file into raw PCM and then re-compressing them in the SBC format. You may
want to consider overclocking in this case to avoid underflow.
A2DPSink
--------
This class implements slave sink-mode operation with player control (play, pause, etc.) and
can play the received and decoded SBC audio to ``PWMAudio``, ``I2S``, or a user-created
`BluetoothAudioConsumer`` class.
The ``A2DPSink.ino`` example demonstrates turning a PicoW into a Bluetooth headset with
``PWMAudio``.
A2DPSource
-----------
This class implements a master source-mode SBC Bluetooth A2DP audio connection which
transmits audio using the standard ``Stream`` interface (like ``I2S`` or ``PWMAudio``.
The main application connects to a Bluetooth speaker and then writes samples into a buffer
that's automatically transmitted behind the scenes.
The ``A2DPSource.ino`` example shows how to connect to a Bluetooth speaker, transmit
data, and respond to commands from the speaker.
+2 -2
View File
@@ -12,7 +12,7 @@ need to be periodically sampled to be read by applications, easily, such as:
* Light dependent resistors (LDR), etc.
Up to 4 analog samples can be recorded by the hardware (``A0`` ... ``A4``), and all
Up to 4 analog samples can be recorded by the hardware (``A0`` ... ``A3``), and all
recording is done at 16-bit levels (but be aware that the ADC in the Pico will only
ever return values between 0...4095).
@@ -29,7 +29,7 @@ ADC Input API
ADCInput(pin0 [, pin1, pin2, pin3])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Creates an ADC input object which will record the pins specified in the code.
Only pins ``A0`` ... ``A4`` can be used, and they must be specified in increasing
Only pins ``A0`` ... ``A3`` can be used, and they must be specified in increasing
order (i.e. ``ADCInput(A0, A1);`` is valid, but ``ADCInput(A1, A0)`` is not.
bool setBuffers(size_t buffers, size_t bufferWords)
+4 -2
View File
@@ -30,7 +30,7 @@ Analog Outputs
--------------
The RP2040 does not have any onboard DACs, so analog outputs are
simulated using the standard method of using pulse width modulation
(PWM) using the RP20400's hardware PWM units.
(PWM) using the RP2040's hardware PWM units.
While up to 16 PWM channels can be generated, they are not independent
and there are significant restrictions as to allowed pins in parallel.
@@ -40,7 +40,9 @@ Analog Output Restrictions
--------------------------
The PWM generator source clock restricts the legal combinations of
frequency and ranges. For example, at 1MHz only about 6 bits of range
frequency and ranges.
At a CPU frequency of 133MHz, the 16 bit maximum range decreases by 1 bit for every doubling of the default PWM frequency of 1 kHz.
For example, at 1MHz only about 6 bits of range
are possible. When you define an ``analogWriteFreq`` and ``analogWriteRange``
that can't be fulfilled by the hardware, the frequency will be preserved
but the accuracy (range) will be reduced automatically. Your code will
+1 -1
View File
@@ -13,7 +13,7 @@ Similar to the `BearSSL::WiFiClientSecure` method, sets the receive and transmit
Setting Server Certificates
~~~~~~~~~~~~~~~~~~~~~~~~~~~
TLS servers require a certificate identifying itself and containing its public key, and a private key they will use to encrypt information with. The application author is responsible for generating this certificate and key, either using a self-signed generator or using a commercial certification authority. **Do not re-use the certificates included in the examples provided.**
TLS servers require a certificate identifying itself and containing its public key, and a private key they will use to encrypt information with. The application author is responsible for generating this certificate and key, either using a self-signed generator or using a commercial certification authority. **Do not reuse the certificates included in the examples provided.**
This example command will generate a RSA 2048-bit key and certificate:
+7 -5
View File
@@ -2,9 +2,6 @@ Bluetooth on PicoW Support
==========================
As of the Pico-SDK version 1.5.0, the PicoW has **BETA** Bluetooth support.
So, since this core builds off the SDK the best that can be suggested it
that we have **ALPHA** Bluetooth support. As such, bug reports are welcome,
but Pull Requests fixing problems you find are seriously appreciated.
Enabling Bluetooth
------------------
@@ -24,6 +21,11 @@ Bluetooth Low Energy (BLE) HID device using the same API as their USB versions.
The ``SerialBT`` library implements a very simple SPP (Serial Port Profile)
Serial-compatible port.
Connect and use Bluetooth peripherals with the PicoW using the
``BluetoothHIDMaster`` library.
``BluetoothAudio`` (A2DP) is also supported, both sink and source.
Writing Custom Bluetooth Applications
-------------------------------------
You may also write full applications using the ``BTStack`` standard callback
@@ -40,8 +42,8 @@ For many BTStack examples, you simply need call the included
called afterwards to start processing (in the background).
You will also need to acquire the BT ``async_context`` system lock before
calling any BTStack APIs. See the ``libraries/PicoBluetoothHID`` helper
class for an example of how to do this.
calling any BTStack APIs. ``__lockBluetooth`` and ``unlockBluetooth`` are
provided in the PicoW variant code.
Note that if you need to modify the system ``btstack_config.h`` file, do so
in the ``tools/libpico`` directory and rebuild the Pico SDK static library.
+21
View File
@@ -0,0 +1,21 @@
BOOTSEL Button
==============
The BOOTSEL button on the Pico is not connected to a standard GPIO, so
it cannot be read using the usual ``digitalRead`` function. It **can**,
however, be read using a special (relatively slow) method.
The ``BOOTSEL`` object implements a simple way of reading the BOOTSEL
button. Simply use the object ``BOOTSEL`` as a boolean (as a conditional
in an ``if`` or ``while``, or assigning to a ``bool``):
.. code:: cpp
// Print "BEEP" if the BOOTSEL button is pressed
if (BOOTSEL) {
Serial.println("BEEP!");
// Wait until BOOTSEL is released
while (BOOTSEL) {
delay(1);
}
}
+2 -2
View File
@@ -54,9 +54,9 @@ author = u'Earle F. Philhower, III'
# built documents.
#
# The short X.Y version.
version = u'3.2.0'
version = u'3.9.3'
# The full version, including alpha/beta/rc tags.
release = u'3.2.0'
release = u'3.9.3'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
+3 -2
View File
@@ -10,7 +10,8 @@ Contributing to the Core (Pull Requests)
----------------------------------------
We use the standard GitHub Pull Request model. If you're unfamiliar with it,
this `guide <https://www.freecodecamp.org/news/how-to-make-your-first-pull-request-on-github-3/>` gives a simple overview of the process.
this `guide <https://www.freecodecamp.org/news/how-to-make-your-first-pull-request-on-github-3/>`__
gives a simple overview of the process.
All pull requests have to pass a set of Continuous Integration (CI) checks
which help make sure the code compiles under different configurations and has
@@ -84,7 +85,7 @@ code that only runs on this core, use the following define.
.. code:: cpp
#if defined(ARDUINO_ARCH_RP2040)
#if defined(ARDUINO_ARCH_RP2040) && !defined(__MBED__)
~~~ your changes ~~~
#endif
+172
View File
@@ -0,0 +1,172 @@
EthernetLWIP (Wired Ethernet) Support
=====================================
Wired Ethernet interfaces are supported for all the internal networking
libraries (``WiFiClient``, ``WiFiClientSecure``, ``WiFiServer``,
``WiFiServerSecure``, ``WiFiUDP``, ``WebServer``, ``Updater``,
``HTTPClient``, etc.).
Using these wired interfaces is very similar to using the Pico-W WiFi
so most examples in the core only require minor modifications to use
a wired interface.
Supported Wired Ethernet Modules
--------------------------------
* Wiznet W5100(s)
* Wiznet W5500
* ENC28J60
Enabling Wired Ethernet
-----------------------
Simply replace the WiFi include at the top with:
.. code:: cpp
#include <W5500lwIP.h> // Or W5100lwIP.h or ENC28J60.h
And add a global Ethernet object of the same type:
.. code:: cpp
Wiznet5500lwIP eth(1); // Parameter is the Chip Select pin
In your ``setup()`` you may adjust the SPI pins you're using to
match your hardware (be sure they are legal for the RP2040!), or
skip this if you're using the default ones:
.. code:: cpp
void setup() {
SPI.setRX(0);
SPI.setCS(1);
SPI.setSCK(2);
SPI.setTX(3);
....
}
And finally replace the ``WiFi.begin()`` and ``WiFi.connected()``
calls with ``eth.begin()`` and ``eth.connected()``:
.. code:: cpp
void setup() {
....
// WiFi.begin(SSID, PASS)
eth.begin();
//while (!WiFi.connected()) {
while (!eth.connected()) {
Serial.print(".");
}
Serial.print("IP address: ");
//Serial.println(WiFi.localIP());
Serial.println(eth.localIP());
....
}
Adjusting LWIP Polling
----------------------
LWIP operates in a polling mode for the wired Ethernet devices. By default it will run
every 20ms, meaning that on average it will take half that time (10ms) before a packet
received in the Ethernet module is received and operated upon by the Pico. This gives
very low CPU utilization but in some cases this latency can affect performance.
Adding a call to ``lwipPollingPeriod(XXX)`` (where ``XXXX`` is the polling period in
milliseconds) can adjust this setting on the fly. Note that if you set it too low, the
Pico may not have enough time to service the Ethernet port before the timer fires again,
leading to a lock up and hang.
Using Interrupt-Driven Handling
-------------------------------
The WizNet and ENC28J60 devices support generating an interrupt when a packet is received,
removing the need for polling and decreasing latency. Simply specify the SPI object to use and the
interrupt pin when instantiating the Ethernet object:
.. code:: cpp
#include <W5100lwIP.h>
Wiznet5100lwIP eth(SS /* Chip Select*/, SPI /* SPI interface */, 17 /* Interrupt GPIO */ );
Adjusting SPI Speed
-------------------
By default a 4MHz clock will be used to clock data into and out of the Ethernet module.
Depending on the module and your wiring, a higher SPI clock may increase performance (but
too high of a clock will cause communications problems or hangs).
This value may be adjusted using the ``eth.setSPISpeed(hz)`` call **before** starting the
device. (You may also use custom ``SPISettings`` instead via ``eth.setSPISettings(spis)```)
For example, to set the W5500 to use a 30MHZ clock:
.. code:: cpp
#include <W5500lwIP.h>
Wiznet5500lwIP eth(1);
void setup() {
eth.setSPISpeed(30000000);
lwipPollingPeriod(3);
...
eth.begin();
...
}
Using the WIZnet W5100S-EVB-Pico
--------------------------------
You can use the onboard Ethernet chip with these drivers, in interrupt mode, by utilizing the following options:
.. code:: cpp
#include <W5100lwIP.h>
Wiznet5100lwIP eth(17, SPI, 21); // Note chip select is **17**
void setup() {
// Set SPI to the onboard Wiznet chip
SPI.setRX(16);
SPI.setCS(17);
SPI.setSCK(18);
SPI.setTX(19);
...
eth.begin();
...
}
Example Code
------------
The following examples allow switching between WiFi and Ethernet:
* ``WebServer/AdvancedWebServer``
* ``HTTPClient/BasicHTTPSClient``
Caveats
-------
The same restrictions for ``WiFi`` apply to these Ethernet classes, namely:
* Only core 0 may run any networking related code.
* In FreeRTOS, only the ``setup`` and ``loop`` task can call networking libraries, not any tasks.
Special Thanks
--------------
* LWIPEthernet classes come from the ESP8266 Arduino team
* Individual Ethernet drivers were written by Nicholas Humfrey
+42
View File
@@ -0,0 +1,42 @@
FatFSUSB
========
When the onboard flash memory is used as a ``FatFS`` filesystem, the
``FatFSUSB`` can be used to allow exporting it to a PC as a standard
memory stick. The PC can then access, add, and remove files as if the
Pico was a USB memory stick, and upon ejection the Pico can access
any new files just as if it made them itself.
(Note, if you are using LittleFS then you need to use ``SingleFileDrive``
to export a single file, not this class, because the PC does not
understand the LittleFS disk format.)
Callbacks, Interrupt Safety, and File Operations
------------------------------------------------
The ``FatFSUSB`` library allows your application to get a callback
when a PC attempts to mount or unmount the Pico as a FAT drive.
When the drive is being used by the Pico (i.e. any ``File`` is open for
read or write, the ``FatFS`` is not ``end()`` -ed and still mounted,
etc.) the host may not access it. Conversely, while the host PC is
connected to the drive no ``FatFS`` access by the Pico is allowed.
Your ``driveReady`` callback will be called when the PC attempts to mount
the drive. If you have any files open, then this callback can report back
that the drive is not yet ready. When you complete file processing, the PC
can re-attempt to mount the drive and your callback can return ``true`` .
The ``onPlug`` callback will generally ``FatFS.end()`` and set a
global flag letting your application know not to touch the filesystem until
the flag is cleared by the ``onUnplug`` callback (which will also do a
``FatFS.begin()`` call).
Failing to close all files **and** ``FatFS.end()`` before granting the
PC access to flash memory will result in corruption. FAT does not allow multiple
writers to access the same drive. Even mounting and only reading files from
the PC may cause hidden writes (things like access time, etc.) which would
also cause corruption.
See the included ``Listfiles-USB`` sketch for an example of working with
these limitations.
+82 -35
View File
@@ -18,12 +18,12 @@ The following diagram shows the flash layout used in Arduino-Pico:
::
|---------------------|-------------|----|
^ ^ ^
Sketch File system EEPROM
|----|---------------------|-------------|----|
^ ^ ^ ^
OTA Sketch File system EEPROM
The file system size is configurable via the IDE menus, rom 64k up to 15MB
(assuming you have an RP2040 boad with that much flash)
The file system size is configurable via the IDE menus, from 64k up to 15MB
(assuming you have an RP2040 board with that much flash)
**Note:** to use any of file system functions in the sketch, add the
following include to the sketch:
@@ -33,25 +33,61 @@ following include to the sketch:
#include "LittleFS.h" // LittleFS is declared
// #include <SDFS.h>
// #include <SD.h>
// #include <FatFS.h>
Compatible Filesystem APIs
--------------------------
LittleFS is an onboard filesystem that sets asidesome program flash for
LittleFS is an onboard filesystem that sets aside some program flash for
use as a filesystem without requiring any external hardware.
SDFS is a filesystem for SD cards, based on [SdFat 2.0](https://github.com/earlephilhower/ESP8266SdFat).
It supports FAT16 and FAT32 formatted cards, and requires an external
SD card reader.
SD is the Arduino supported, somewhat old and limited SD card filesystem.
SD is the Arduino-supported, somewhat old and limited SD card filesystem.
It is recommended to use SDFS for new applications instead of SD.
All three of these filesystems can open and manipulate ``File`` and ``Dir``
FatFS implements a wear-leveled, FTL-backed FAT filesystem in the onboard
flash which can be easily accessed over USB as a standard memory stick
via FatFSUSB.
All of these filesystems can open and manipulate ``File`` and ``Dir``
objects with the same code because the implement a common end-user
filesystem API.
FatFS File System Caveats and Warnings
--------------------------------------
The FAT filesystem is ubiquitous, but it is also around 50 years old and ill
suited to SPI flash memory due to having "hot spots" like the FAT copies that
are rewritten many times over. SPI flash allows a high, but limited, number
of writes before losing the ability to write safely. Applications like
data loggers where many writes occur could end up wearing out the SPI flash
sector that holds the FAT **years** before coming close to the write limits of
the data sectors.
To circumvent this issue, the FatFS implementation here uses a flash translation
layer (FTL) developed for SPI flash on embedded systems. This allows for the
same LBA to be written over and over by the FAT filesystem, but use different
flash locations. For more information see
[SPIFTL](https://github.com/earlephilhower/SPIFTL). In this mode the Pico
flash appears as a normal, 512-byte sector drive to the FAT.
What this means, practically, is that about 5KB of RAM per megabyte of flash
is required for housekeeping. Writes can also become very slow if most of the
flash LBA range is used (i.e. if the FAT drive is 99% full) due to the need
for garbage collection processes to move data around and preserve the flash
lifetime.
Alternatively, if an FTL is not desired or memory is tight, FatFS can use the
raw flash directly. In this mode sectors are 4K in size and flash is mapped
1:1 to sectors, so things like the FAT table updates will all use the same
physical flash bits. For low-utilization operations this may be fine, but if
significant writes are done (from the Pico or the PC host) this may wear out
portions of flash very quickly , rendering it unusable.
LittleFS File System Limitations
--------------------------------
@@ -75,22 +111,28 @@ Uploading Files to the LittleFS File System
menu item to **Tools** menu for uploading the contents of sketch data
directory into a new LittleFS flash file system.
**IDE 1.x**
- Download the tool: https://github.com/earlephilhower/arduino-pico-littlefs-plugin/releases
- In your Arduino sketchbook directory, create ``tools`` directory if
it doesn't exist yet.
- Unpack the tool into ``tools`` directory (the path will look like
``<home_dir>/Arduino/tools/PicoLittleFS/tool/picolittlefs.jar``)
- In your Arduino sketchbook directory, create ``tools`` directory if it doesn't exist yet.
- Unpack the tool into ``tools`` directory (the path will look like ``<home_dir>/Arduino/tools/PicoLittleFS/tool/picolittlefs.jar``)
If upgrading, overwrite the existing JAR file with the newer version.
- Restart Arduino IDE.
- Open a sketch (or create a new one and save it).
- Go to sketch directory (choose Sketch > Show Sketch Folder).
- Create a directory named ``data`` and any files you want in the file
system there.
- Create a directory named ``data`` and any files you want in the file system there.
- Make sure you have selected a board, port, and closed Serial Monitor.
- Double check theSerial Monitor is closed. Uploads will fail if the Serial
Monitor has control of the serial port.
- Select ``Tools > Pico LittleFS Data Upload``. This should start
uploading the files into the flash file system.
- Double check the Serial Monitor is closed. Uploads will fail if the Serial Monitor has control of the serial port.
- Select ``Tools > Pico LittleFS Data Upload``. This should start uploading the files into the flash file system.
**IDE 2.x**
- Download the new tool: https://github.com/earlephilhower/arduino-littlefs-upload/releases
- Exit the IDE, if running
- Copy the VSIX file manually to (Linux/Mac) ``~/.arduinoIDE/plugins/`` (you may need to make this directory yourself beforehand) or to (Windows) ``C:\Users\<username>\.arduinoIDE\``
- Restart the IDE
- Double check the Serial Monitor is closed. Uploads will fail if the Serial Monitor has control of the serial port.
- Enter ``[Ctrl]`` + ``[Shift]`` + ``[P]`` to bring up the command palette, then select/type ``Upload LittleFS to Pico/ESP8266``
SD Library Information
----------------------
@@ -109,8 +151,8 @@ second SPI port, ``SPI1``. Just use the following call in place of
SD.begin(cspin, SPI1);
File system object (LittleFS/SD/SDFS)
-------------------------------------
File system object (LittleFS/SD/SDFS/FatFS)
-------------------------------------------
setConfig
~~~~~~~~~
@@ -125,14 +167,22 @@ setConfig
c2.setCSPin(12);
SDFS.setConfig(c2);
FatFSConfig c3;
c3.setUseFTL(false); // Directly access flash memory
c3.setDirEntries(256); // We need 256 root directory entries on a format()
c3.setFATCopies(1); // Only 1 FAT to save 4K of space and extra writes
FatFS.setConfig(c3);
FatFS.format(); // Format using these settings, erasing everything
This method allows you to configure the parameters of a filesystem
before mounting. All filesystems have their own ``*Config`` (i.e.
``SDFSConfig`` or ``LittleFSConfig`` with their custom set of options.
All filesystems allow explicitly enabling/disabling formatting when
mounts fail. If you do not call this ``setConfig`` method before
perforing ``begin()``, you will get the filesystem's default
behavior and configuration. By default, SPIFFS will autoformat the
filesystem if it cannot mount it, while SDFS will not.
behavior and configuration. By default, LittleFS and FatFS will autoformat the
filesystem if it cannot mount it, while SDFS will not. FatFS will also use
the built-in FTL to support 512 byte sectors and higher write lifetime.
begin
~~~~~
@@ -144,11 +194,10 @@ begin
This method mounts file system. It must be called before any
other FS APIs are used. Returns *true* if file system was mounted
successfully, false otherwise. With no options it will format SPIFFS
if it is unable to mount it on the first try.
successfully, false otherwise.
Note that LittleFS will automatically format the filesystem
if one is not detected. This is configurable via ``setConfig``
if one is not detected. This is configurable via ``setConfig``.
end
~~~
@@ -181,8 +230,8 @@ open
Opens a file. ``path`` should be an absolute path starting with a slash
(e.g. ``/dir/filename.txt``). ``mode`` is a string specifying access
mode. It can be one of "r", "w", "a", "r+", "w+", "a+". Meaning of these
modes is the same as for ``fopen`` C function.
mode. It can be one of "r", "w", "a", "r+", "w+", "a+". The meaning of these
modes is the same as for the ``fopen`` C function.
::
@@ -258,8 +307,6 @@ openDir
or LittleFS.openDir(path)
Opens a directory given its absolute path. Returns a *Dir* object.
Please note the previous discussion on the difference in behavior between
LittleFS and SPIFFS for this call.
remove
~~~~~~
@@ -325,8 +372,8 @@ info64
.. code:: cpp
FSInfo64 fsinfo;
SDFS.info(fsinfo);
or LittleFS(fsinfo);
SDFS.info64(fsinfo);
or LittleFS.info64(fsinfo);
Performs the same operation as ``info`` but allows for reporting greater than
4GB for filesystem size/used/etc. Should be used with the SD and SDFS
@@ -550,8 +597,8 @@ close
Close the file. No other operations should be performed on *File* object
after ``close`` function was called.
openNextFile (compatibiity method, not recommended for new code)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
openNextFile (compatibility method, not recommended for new code)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: cpp
@@ -562,8 +609,8 @@ openNextFile (compatibiity method, not recommended for new code)
Opens the next file in the directory pointed to by the File. Only valid
when ``File.isDirectory() == true``.
rewindDirectory (compatibiity method, not recommended for new code)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rewindDirectory (compatibility method, not recommended for new code)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: cpp
+208
View File
@@ -0,0 +1,208 @@
Bluetooth HID Master
====================
The PicoW can connect to a Bluetooth Classic or Bluetooth BLE keyboard,
mouse, or joystick and receive input events from it. As opposed to
the ``Keyboard``, ``Mouse``, and ``Joystick`` libraries, which make
the PicoW into a peripheral others can use, this lets the PicoW use the
same kinds of peripherals in a master rols.
BTDeviceInfo Class
------------------
The ``BluetoothHCI`` class implements a scanning function for classic
and BLE devices and can return a ``std::vector`` of discovered devices to an application.
Iterate over the list using any of the STL iteration methods (i.e. ``for (auto e : list)``).
The elements of this list are ``BTDeviceInfo`` objects which have the following
member functions:
``BTDeviceInfo::deviceClass()`` returns the Bluetooth BLE UUID or the Blustooth device
class for the device. This specifies the general class of the device (keyboard, mouse,
etc.).
``BTDeviceInfo::address()`` and ``BTDeviceInfo::addressString()`` return the
Bluetooth address as a binary array or a string that can be used to ``print``.
``BTDeviceInfo::addressType()`` returns whether the BLE address is random or not, and
is not generally needed by a user application.
``BTDeviceInfo::rssi()`` returns an approximate dB level for the device. Less
negative is stronger signal.
``BTDeviceInfo::name()`` returns the advertised name of the device, if present. Some
devices or scans do not return names for valid devices.
BluetoothHCI Class
------------------
The ``BluetoothHCI`` class is responsible for scanning for devices and the lower-level
housekeeping for a master-mode Bluetooth application. Most applications will not need
to access it directly, but it can be used to discover nearby BT devices. As
part of the application Bluetooth setup, call ``BluetoothHCI::install()`` and then
``BluetoothHCI::begin()`` to start BT processing. Your application is still responsible
for all the non-default HCI initialization and customization. See the ``BluetoothScanner.ino``
example for more info.
BluetoothHIDMaster Operation
----------------------------
Most applications will use the ``BluetoothHIDMaster`` class and, after connecting, receive
callbacks from the Bluetooth stack when input events (key presses, mouse moves, button
mashes) occur.
Application flow will generally be:
1. Install the appropriate callbacks using the ``BluetoothHIDMaster::onXXX`` methods
2. Start the Bluetooth processing with ``BluetoothHIDMaster::begin()`` or ``BluetoothHIDMaster::beginBLE()``
3. Connect to the first device found with ``BluetoothHIDMaster::connectXXX()`` and start receiving callbacks.
4. Callbacks will come at interrupt time and set global state variables, which the main ``loop()`` will process
Callback Event Handlers
-----------------------
The main application is informed of new inputs via a standard callback mechanism. These callbacks run at
interrupt time and should not do significant work, ``delay()``, or allocate or free memory. The most common
way of handling this is setting global ``volatile`` flags and variables that the main ``loop()`` will poll
and process.
Mouse Callbacks
~~~~~~~~~~~~~~~
The ``BluetoothHIDMaster::onMouseMove`` callback gets the delta X, Y, and wheel reported by the device.
The ``BluetoothHIDMaster::onMouseButton`` gets a button number and state (up or down) and will be called
each time an individual button is reported changed by the mouse.
.. code :: cpp
void mouseMoveCB(void *cbdata, int dx, int dy, int dw) {
// Process the deltas, adjust global mouse state
}
void mouseButtonCB(void *cbdata, int butt, bool down) {
// Set the global button array with this new info
}
Meyboard Callbacks
~~~~~~~~~~~~~~~~~~
The `BluetoothHIDMaster::onKeyDown`` callback receives the raw HID key (**NOT ASCII**) sent by the device on a key press
while `BluetoothHIDMaster::onKeyUp`` gets the same when a key is released. Note that up to 6 keys can be pressed at any
one time. For media keys ("consumer keys" in the USB HID documentation) the ``BluetoothHIDMaster::onConsumerKeyDown`` and
``BluetoothHIDMaster::onConsumerKeyUp`` perform the same function (and receive the consumer key IDs defined by the
USB HID spec and not ASCII).
To convert the key press and release (including SHIFT handling), use a ``HIDKeyStream`` object. Simply write the raw
HID key and the up/down state to the stream and read back the ASCII for use in an application.
.. code :: cpp
HIDKeyStream keystream;
void keyDownCB(void *cbdata, int key) {
keystream.write((uint8_t )key);
keystream.write((uint8_t) true); // Keystream now has 1 ASCII character to read out and use
char ascii = keystream.read();
// ....
}
void keyUpCB(void *cbdata, int key) {
// Normally don't do anything on this, the character was read in the keyDownCB
}
void consumerKeyDownCB(void *cbdata, int key) {
// switch(key) and use cases from the USB Consumer Key page
}
void consumerKeyUpCB(void *cbdata, int key) {
// switch(key) and use cases from the USB Consumer Key page
}
Joystick Callbacks
~~~~~~~~~~~~~~~~~~
A single ``BluetoothHIDMaster::onJoystick`` callback gets activated every time a report from a joystick is processed.
It receives (potentially, if supported by the device) 4 analog axes, one 8-way digital hat switch position, and up
to 32 button states at a time.
.. code :: cpp
void joystickCB(void *cbdata, int x, int y, int z, int rz, uint8_t hat, uint32_t buttons) {
// HAT 0 = UP and continues clockwise. If no hat direction it is set to 0x0f.
// Use "buttons & (1 << buttonNumber)" to look at the individual button states
// ...
}
PianoKeyboard Example
~~~~~~~~~~~~~~~~~~~~~
See the ``PianoKeyboard.ino`` and ``PianoKeyboardBLE.ino`` examples for more information on callback operation.
BluetoothHIDMaster::onXXX Callback Installers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code :: cpp
void BluetoothHIDMaster::onMouseMove(void (*)(void *, int, int, int), void *cbData = nullptr);
void BluetoothHIDMaster::onMouseButton(void (*)(void *, int, bool), void *cbData = nullptr);
void BluetoothHIDMaster::onKeyDown(void (*)(void *, int), void *cbData = nullptr);
void BluetoothHIDMaster::onKeyUp(void (*)(void *, int), void *cbData = nullptr);
void BluetoothHIDMaster::onConsumerKeyDown(void (*)(void *, int), void *cbData = nullptr);
void BluetoothHIDMaster::onConsumerKeyUp(void (*)(void *, int), void *cbData = nullptr);
void BluetoothHIDMaster::onJoystick(void (*)(void *, int, int, int, int, uint8_t, uint32_t), void *cbData = nullptr);
BluetoothHIDMaster Class
------------------------
bool BluetoothHIDMaster::begin()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Installs and configures the Bluetooth Classic stack and starts processing events. No connections are made at this point.
When running in Classic mode, no BLE devices can be detected or used.
bool BluetoothHIDMaster::begin(const char *BLEName)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Installs and configures the Bluetooth BLE stack and starts processing events. No connections are made at this point.
When running in BLE mode, no Classic devices can be detected or used.
bool BluetoothHIDMaster::connected()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns if the Bluetooth stack is up and running and a connection to a device is currently active.
void BluetoothHIDMaster::end()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Disables the Bluetooth stack. Note that with the current Bluetooth implementation restarting the stack (i.e. calling ``begin()`` after ``end()``) is not stable and will not work. Consider storing state and rebooting completely if this is necessary.
bool BluetoothHIDMaster::running()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns if the Bluetooth stack is running at all. Does not indicate if there is an active connection or not.
bool BluetoothHIDMaster::hciRunning()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns if the Bluetooth stack has passed the initial HCI start up phase. Until this returns ``true`` no Bluetooth operations can be performed.
std::vector<BTDeviceInfo> BluetoothHIDMaster::scan(uint32_t mask, int scanTimeSec, bool async)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Passes through the ``BluetoothHCI::scan()`` function to manually scan for a list of nearby devices. If you want to connect to the first found device, this is not needed.
bool BluetoothHIDMaster::connect(const uint8_t *addr)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Start the connection process to the Bluetooth Classic device with the given MAC. Note that this returns immediately, but it may take several seconds until ``connected()`` reports that the connection has been established.
bool BluetoothHIDMaster::connectKeyboard(), connectMouse(), connectJoystick(), connectAny()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Connect to the first found specified Bluetooth Classic device type (or any HID device) in pairing mode. No need to call ``scan()`` or have an address.
bool BluetoothHIDMaster::connectBLE(const uint8_t *addr, int addrType)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Start the connection process to the Bluetooth BLE device with the given MAC. Note that this returns immediately, but it may take several seconds until ``connected()`` reports that the connection has been established.
bool BluetoothHIDMaster::connectBLE()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Connect to the first found BLE device that has a HID service UUID (keyboard, mouse, or joystick)
bool BluetoothHIDMaster::disconnect()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Shuts down the connection to the currently connected device.
void BluetoothHIDMaster::clearPairing()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Erases all Bluetooth keys from memory. This effectively "forgets" all pairing between devices and can help avoid issues with the beta Bluetooth stack in the SDK.
+1 -1
View File
@@ -1,7 +1,7 @@
HTTPClient Library
==================
A simple HTTP requestor that can handle both HTTP and HTTP requests is
A simple HTTP requester that can handle both HTTP and HTTPS requests is
included as the ``HTTPClient`` library.
Check the examples for use under HTTP and HTTPS configurations. In general,
+32 -1
View File
@@ -40,6 +40,16 @@ bool setDATA(pin_size_t pin)
Sets the DOUT or DIN pin of the I2S device. Any pin may be used.
Call before ``I2S::begin()``
bool setMCLK(pin_size_t pin)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the MCLK pin of the I2S device and enables MCLK output. Any pin may be used.
Call before ``I2S::begin()``
bool setMCLKmult(int mult)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the sample rate to MCLK multiplier value. Only multiples of 64 are valid.
Call before ``I2S::begin()``
bool setBitsPerSample(int bits)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Specify how many bits per audio sample to read or write. Note that
@@ -58,12 +68,28 @@ Sets the word clock frequency, but does not start the I2S device if not
already running. May be called after ``I2S::begin()`` to change the
sample rate on-the-fly.
bool setSysClk(int samplerate)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Changes the PICO system clock to optimise for the desired samplerate.
The clock changes to 147.6 MHz for samplerates that are a multiple of 8 kHz, and 135.6 MHz for multiples of 11.025 kHz.
Note that using ``setSysClk()`` may affect the timing of other sysclk-dependent functions.
Should be called before any I2S functions and any other sysclk dependent initialisations.
bool setLSBJFormat()
~~~~~~~~~~~~~~~~~~~~
Enables LSB-J format for I2S output. In this mode the MSB comes out at the
same time as the LRCLK changes, and not the normal 1-cycle delay. Useful for
DAC chips like the PT8211.
bool setTDMFormat()
~~~~~~~~~~~~~~~~~~~
Enabled TDM formatted multi-channel output. Be sure to set the number of channels to
the expected value (8 normally) and the bits per sample to 32.
bool setTDMChannels(int channels)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the number of TDM channels between frame syncs. Generally should be set to 8.
bool swapClocks()
~~~~~~~~~~~~~~~~~
Certain boards are hardwired with the WCLK before the BCLK, instead of the normal
@@ -84,6 +110,11 @@ void flush()
~~~~~~~~~~~~
Waits until all the I2S buffers have been output.
void getOverUnderflow()
~~~~~~~~~~~~~~~~~~~~~~~
Returns a flag indicating if the I2S system ran our of data to send on output,
or had to throw away data on input.
size_t write(uint8_t/int8_t/int16_t/int32_t)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Writes a single sample of ``bitsPerSample`` to the buffer. It is up to the
@@ -112,7 +143,7 @@ many bytes were actually written.
int availableForWrite()
~~~~~~~~~~~~~~~~~~~~~~~
Returns the number of L/R samples that can be written without
Returns the amount of bytes that can be written without
potentially blocking.
int read()
+3 -7
View File
@@ -1,15 +1,11 @@
IDE Menus
=========
Model
Board
-----
Use the boards menu to select your model of RP2040 board. There will be two
options: `Boardname` and `Boardname (Picoprobe)`. If you want to use a
Picoprobe to upload your sketches and not the default automatic UF2 upload,
use the `(Picoprobe)` option, otherwise use the normal name. No functional
or code changes are done because of this.
Use the boards menu to select your model of RP2040 board.
There is also a `Generic` board which allows you to individually select
There is also a `Generic RP2040` board which allows you to individually select
things such as flash size or boot2 flash type. Use this if your board isn't
yet fully supported and isn't working with the normal `Raspberry Pi Pico`
option.
+6 -1
View File
@@ -30,6 +30,7 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
Analog I/O <analog>
Digital I/O <digital>
BOOTSEL Button <bootsel>
EEPROM <eeprom>
I2S Audio <i2s>
PWM Audio <pwm>
@@ -43,13 +44,17 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p
USB (Arduino and Adafruit_TinyUSB) <usb>
Multicore Processing <multicore>
Bluetooth (Alpha/Beta) <bluetooth>
Bluetooth <bluetooth>
Bluetooth HID Master <hidmaster>
Bluetooth Audio (A2DP) <a2dp>
Single File USB Drive <singlefile>
FatFSUSB - full FS access over USB <fatfsusb>
FreeRTOS SMP (multicore) <freertos>
WiFi (Pico-W Support) <wifi>
Ethernet (Wired) <ethernet>
WiFiClient <wificlient>
WiFiServer <wifiserver>
WiFiUDP <wifiudp>
+21 -11
View File
@@ -26,9 +26,7 @@ Arduino IDE Installation Warning
the actual Arduino application because it has issues detecting attached Pico
boards. Use the "Windows ZIP" or plain "Windows" executable (EXE) download
direct from https://arduino.cc. and allow it to install any device drivers
it suggests. Otherwise the Pico board may not be detected. Also, if trying
out the 2.0 beta Arduino please install the release 1.8 version beforehand
to ensure needed device drivers are present.
it suggests. Otherwise the Pico board may not be detected.
**Note for Linux Users**: If you installed the Arduino IDE using Flatpak, which
is common in Pop!_OS, Fedora, and Mint, among others, you may need to configure
@@ -38,6 +36,22 @@ prevent the Arduino IDE from accessing. For Arduino IDE V2, override the filesys
restriction using ``flatpak override --user --filesystem=host cc.arduino.IDE2`` . For
For Arduino IDE < V2, use ``flatpak override --user --filesystem=host cc.arduino.arduinoide``.
Installing via Arduino CLI
--------------------------
To install using the Arduino command line tool (arduino-cli):
.. code:: bash
arduino-cli config add board_manager.additional_urls https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
arduino-cli core update-index
arduino-cli core install rp2040:rp2040
To list the supported boards:
.. code:: bash
arduino-cli board listall | grep rp2040
Installing via GIT
------------------
To install via GIT (for latest and greatest versions):
@@ -125,11 +139,13 @@ Uploading Filesystem Images
---------------------------
The onboard flash filesystem for the Pico, LittleFS, lets you upload a filesystem image from the sketch directory for your sketch to use. Download the needed plugin from
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/releases
* `IDE 1.x`: https://github.com/earlephilhower/arduino-pico-littlefs-plugin/releases
* `IDE 2.x`: https://github.com/earlephilhower/arduino-littlefs-upload/releases
To install, follow the directions in
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/README.md
* `IDE 1.x`: https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/README.md
* `IDE 2.x`: https://github.com/earlephilhower/arduino-littlefs-upload/blob/main/README.md
For detailed usage information, please check the repo documentation available at
@@ -143,12 +159,6 @@ So for the first sketch you will need to rebuild (with the ``Upload Method->Pico
After the initial upload, as long as the running binary was built using the ``Picotool`` upload method, then the normal upload process should work.
Under MacOS, it may be necessary to install the USB support libraries from a command terminal before the ``Picotool`` upload method can be used:
.. code::
brew install libusb
For Ubuntu and other Linux operating systems you may need to add the following lines to a new `udev` config file(``99-picotool.rules``) to allow normal users to access the special USB device the Pico exports:
.. code::
+1 -1
View File
@@ -10,5 +10,5 @@ In addition, it contains code from additional open source projects:
* 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.
* `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.
+28 -2
View File
@@ -16,11 +16,32 @@ not necessarily simultaneously!).
See the ``Multicore.ino`` example in the ``rp2040`` example directory for a
quick introduction.
Stack Sizes
-----------
When the Pico is running in single core mode, core 0 has the full 8KB of stack
space available to it. When using multicore ``setup1``/``loop1`` the 8KB is split
into two 4K stacks, one per core. It is possible for core 0's stack to overwrite
core 1's stack in this case, if you go beyond the 4K limitation.
To allocate a separate 8K stack for core 1, resulting in 8K stacks being available
for both cores, simply define the following variable in your sketch and set it
to ``true``:
.. code:: cpp
bool core1_separate_stack = true;
Pausing Cores
-------------
Sometimes an application needs to pause the other core on chip (i.e. it is
writing to flash or needs to stop processing while some other event occurs).
In most cases, however, these calls are **SHOULD NOT BE USED**. To synchronize
cross-core operations use normal multiprocessor methods such as circular buffers,
global ``volatile`` flags, mutexes, and the like. Stopping a core has massive
implications and can kill networking and USB communications if done too long or
too frequently.
void rp2040.idleOtherCore()
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -53,7 +74,12 @@ Communicating Between Cores
The RP2040 provides a hardware FIFO for communicating between cores, but it
is used exclusively for the idle/resume calls described above. Instead, please
use the following functions to access a software-managed, multicore safe
FIFO.
FIFO. There are two FIFOs, one written to by core 0 and read by core 1, and
the other written to by core 1 and read by core 0.
You can (and probably should) use shared memory (such as ``volatile`` globals)
or other normal multiprocessor communication algorithms to transfer data or
work between cores, but for simple tasks these FIFO routines can suffice.
void rp2040.fifo.push(uint32_t)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -80,4 +106,4 @@ Reads a value from this core's FIFO and places it in dest. Will return
int rp2040.fifo.available()
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns the number of values available in this core's FIFO.
Returns the number of values available to read in this core's FIFO.
+14 -14
View File
@@ -12,7 +12,7 @@ OTA may be done using:
- `Arduino IDE <#arduino-ide>`__
- `Web Browser <#web-browser>`__
- `HTTP Server <#http-server>`__
- Any other method (ZModen receive over a UART port, etc.) by using the ``Updater`` object in your sketch
- Any other method (ZModem receive over a UART port, etc.) by using the ``Updater`` object in your sketch
The Arduino IDE option is intended primarily for the software development phase. The other two options would be more useful after deployment, to provide the module with application updates either manually with a web browser, or automatically using an HTTP server.
@@ -90,7 +90,7 @@ Signing requires the generation of an RSA-2048 key (other bit lengths are suppor
Automatic Signing
^^^^^^^^^^^^^^^^^
The simplest way of implementing signing is to use the automatic mode, which presently is only possible on Linux and Mac due to some of the tools not being available for Windows. This mode uses the IDE to configure the source code to enable sigining verification with a given public key, and signs binaries as part of the standard build process using a given public key.
The simplest way of implementing signing is to use the automatic mode, which presently is only possible on Linux and Mac due to some of the tools not being available for Windows. This mode uses the IDE to configure the source code to enable signing verification with a given public key, and signs binaries as part of the standard build process using a given public key.
To enable this mode, just include `private.key` and `public.key` in the sketch `.ino` directory. The IDE will call a helper script (`tools/signing.py`) before the build begins to create a header to enable key validation using the given public key, and to actually do the signing after the build process, generating a `sketch.bin.signed` file. When OTA is enabled (ArduinoOTA, Web, or HTTP), the binary will automatically only accept signed updates.
@@ -140,11 +140,11 @@ Compile the sketch normally and, once a `.bin` file is available, sign it using
Compression
-----------
The eboot bootloader incorporates a GZIP decompressor, built for very low code requirements. For applications, this optional decompression is completely transparent. For uploading compressed filesystems, the application must be built with `ATOMIC_FS_UPDATE` defined because, otherwise, eboot will not be involved in writing the filesystem.
The bootloader incorporates a GZIP decompressor, built for very low code requirements. For applications, this optional decompression is completely transparent.
No changes to the application are required. The `Updater` class and `eboot` bootloader (which performs actual application overwriting on update) automatically search for the `gzip` header in the uploaded binary, and if found, handle it.
No changes to the application are required. The `Updater` class and bootloader (which performs actual application overwriting on update) automatically search for the `gzip` header in the uploaded binary, and if found, handle it.
Compress an application `.bin` file or filesystem package using any `gzip` available, at any desired compression level (`gzip -9` is recommended because it provides the maximum compression and uncompresses as fast as any other compressino level). For example:
Compress an application `.bin` file or filesystem package using any `gzip` available, at any desired compression level (`gzip -9` is recommended because it provides the maximum compression and uncompresses as fast as any other compression level). For example:
.. code:: bash
@@ -185,11 +185,11 @@ Uploading modules wirelessly from Arduino IDE is intended for the following typi
- Only if modules are accessible on the same network as the computer with the Arduino IDE.
- For all IDE uploads,m the Pico W and the computer must be connected to the same network.
- For all IDE uploads, the Pico W and the computer must be connected to the same network.
To upload wirelessly from the IDE:
1. Build a sketch starts ``WiFi`` and includes the appropriare calls to ``ArduinoOTA`` (see the examples for reference). These include the ``ArduinoOTA.begin()`` call in ``setup()`` and periodically calling ``ArduinoOTA.handle();`` from the ``loop()``
1. Build a sketch that starts ``WiFi`` and includes the appropriate calls to ``ArduinoOTA`` (see the examples for reference). These include the ``ArduinoOTA.begin()`` call in ``setup()`` and periodically calling ``ArduinoOTA.handle();`` from the ``loop()``
2. Upload using standard USB connection the first time.
@@ -200,7 +200,7 @@ To upload wirelessly from the IDE:
Password Protection
-------------------
Protecting your OTA uploads with password is really straightforward. All you need to do, is to include the following statement in your code:
Protecting your OTA uploads with a password is really straightforward. All you need to do, is to include the following statement in your code:
.. code:: cpp
@@ -208,13 +208,13 @@ Protecting your OTA uploads with password is really straightforward. All you nee
Where ``123`` is a sample password that you should replace with your own.
Before implementing it in your sketch, it is a good idea to check how it works using *BasicOTA.ino* sketch available under *File > Examples > ArduinoOTA*. Go ahead, open *BasicOTA.ino*, uncomment the above statement that is already there, and upload the sketch. To make troubleshooting easier, do not modify example sketch besides what is absolutely required. This is including original simple ``123`` OTA password. Then attempt to upload sketch again (using OTA). After compilation is complete, once upload is about to begin, you should see prompt for password.
Before implementing it in your sketch, it is a good idea to check how it works using *BasicOTA.ino* sketch available under *File > Examples > ArduinoOTA*. Go ahead, open *BasicOTA.ino*, uncomment the above statement that is already there, and upload the sketch. To make troubleshooting easier, do not modify example sketch besides what is absolutely required. This includes the original simple ``123`` OTA password. Then attempt to upload a sketch again (using OTA). After compilation is complete, once upload is about to begin, you should see a prompt for password.
Enter the password and upload should be initiated as usual with the only difference being ``Authenticating...OK`` message visible in upload log.
Enter the password and upload should be initiated as usual with the only difference being ``Authenticating...OK`` message visible in the upload log.
You will not be prompted for a reentering the same password next time. Arduino IDE will remember it for you. You will see prompt for password only after reopening IDE, or if you change it in your sketch, upload the sketch and then try to upload it again.
You will not be prompted for a reentering the same password next time. Arduino IDE will remember it for you. You will see a prompt for password only after reopening the IDE, or if you change it in your sketch, upload the sketch and then try to upload it again.
Please note, it is possible to reveal password entered previously in Arduino IDE, if IDE has not been closed since last upload. This can be done by enabling *Show verbose output during: upload* in *File > Preferences* and attempting to upload the module.
Please note, it is possible to reveal password entered previously in Arduino IDE, if the IDE has not been closed since last upload. This can be done by enabling *Show verbose output during: upload* in *File > Preferences* and attempting to upload the module.
@@ -289,7 +289,7 @@ Simple updater downloads the file every time the function is called.
Advanced updater
^^^^^^^^^^^^^^^^
Its possible to point the update function to a script on the server. If a version string argument is given, it will be sent to the server. The server side script can use this string to check whether an update should be performed.
It's possible to point the update function to a script on the server. If a version string argument is given, it will be sent to the server. The server side script can use this string to check whether an update should be performed.
The server-side script can respond as follows: - response code 200, and send the firmware image, - or response code 304 to notify Pico that no update is required.
@@ -305,7 +305,7 @@ The server-side script can respond as follows: - response code 200, and send the
Serial.println("[update] Update no Update.");
break;
case HTTP_UPDATE_OK:
Serial.println("[update] Update ok."); // may not be called since we reboot the RP2040
Serial.println("[update] Update ok.");
break;
}
+1
View File
@@ -15,6 +15,7 @@ To instantiate only a serial transmit or receive unit, pass in
``SerialPIO::NOPIN`` as the ``txpin`` or ``rxpin``.
For example, to make a transmit-only port on GP16
.. code:: cpp
SerialPIO transmitter( 16, SerialPIO::NOPIN );
+3 -4
View File
@@ -191,7 +191,7 @@ Debug Level
Done again by directly adding the needed `build
flags <https://github.com/earlephilhower/arduino-pico/blob/05356da2c5552413a442f742e209c6fa92823666/boards.txt#L104-L114>`__.
When wanting to define multiple build flags, they must be accumulated in
either a sing line or a newline-separated expression.
either a single line or a newline-separated expression.
.. code:: ini
@@ -363,7 +363,7 @@ For further information on customizing debug options, like the initial breakpoin
You can obtain precompiled binaries from `here <https://github.com/blackmagic-debug/blackmagic/issues/1364#issuecomment-1503372723>`__. A flashing guide is available `here <https://primalcortex.wordpress.com/2017/06/13/building-a-black-magic-debug-probe/>`__. You then have to configure the target serial port ("GDB port") in your project per `documentation <https://docs.platformio.org/en/latest/plus/debug-tools/blackmagic.html#debugging-tool-blackmagic>`__.
.. note::
For the pico-debug (`download <https://github.com/majbthrd/pico-debug/releases>`__) debugging way, *which needs to no additional debug probe*, add this snippet to your ``platformio.ini`` and follow the given procedure:
For the pico-debug (`download <https://github.com/majbthrd/pico-debug/releases>`__) debugging way, *which needs no additional debug probe*, add this snippet to your ``platformio.ini`` and follow the given procedure:
.. code:: ini
@@ -397,5 +397,4 @@ The task "Build Filesystem Image" will take all files in the data directory and
The task "Upload Filesystem Image" will upload the filesystem image to the Pico via the specified ``upload_protocol``.
.. note::
Set the space available for the filesystem in the ``platformio.ini`` using e.g., ``board_build.filesystem_size = 0.5m``, or filesystem
creation will fail!
Set the space available for the filesystem in the ``platformio.ini`` using e.g., ``board_build.filesystem_size = 0.5m``, or filesystem creation will fail!
+6 -2
View File
@@ -81,8 +81,8 @@ overhead).
Hardware Identification
-----------------------
bool isPicoW()
~~~~~~~~~~~~~~
bool rp2040.isPicoW()
~~~~~~~~~~~~~~~~~~~~~
Returns the core's best guess if this code is running on a Raspberry Pi Pico W.
This would let you, possibly, use the same UF2 for Pico and PicoW by simply not
doing any WiFi calls.
@@ -95,3 +95,7 @@ void rp2040.enableDoubleResetBootloader()
Add a call anywhere in the sketch to ``rp2040.enableDoubleResetBootloader()`` and
the core will check for a double-tap on reset, and if found will start the USB
bootloader.
void rp2040.rebootToBootloader()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Will reboot the RP2040 into USB UF2 upload mode.
+20
View File
@@ -45,3 +45,23 @@ For applications where an IRQ driven serial port is not appropriate, use
For detailed information about the Serial ports, see the
Arduino `Serial Reference <https://www.arduino.cc/reference/en/language/functions/communication/serial/>`_ .
RP2040 Specific SerialUSB methods
---------------------------------
void Serial.ignoreFlowControl(bool ignore)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In some cases, the target application will not assert the DTR virtual line, thus preventing writing operations to succeed.
For this reason, the SerialUSB::ignoreFlowControl() method disables the connection's state verification, enabling the program to write on the port, even though the data might be lost.
bool Serial.dtr()
~~~~~~~~~~~~~~~~~
Returns the current state of the DTR virtual line. A USB CDC host (such as the Arduino serial monitor) typically raises the DTR pin when opening the device, and may lower it when closing the device.
bool Serial.rts()
~~~~~~~~~~~~~~~~~
Returns the current state of the RTS virtual line.
+59 -6
View File
@@ -1,5 +1,5 @@
SPI (Serial Peripheral Interface)
=================================
SPI Master (Serial Peripheral Interface)
========================================
The RP2040 has two hardware SPI interfaces, ``spi0 (SPI)`` and ``spi1 (SPI1)``.
These interfaces are supported by the ``SPI`` library in master mode.
@@ -8,10 +8,10 @@ SPI pinouts can be set **before SPI.begin()** using the following calls:
.. code:: cpp
bool setRX(pin_size_t pin);
bool setRX(pin_size_t pin); // or setMISO()
bool setCS(pin_size_t pin);
bool setSCK(pin_size_t pin);
bool setTX(pin_size_t pin);
bool setTX(pin_size_t pin); // or setMOSI()
Note that the ``CS`` pin can be hardware or software controlled by the sketch.
When software controlled, the ``setCS()`` call is ignored.
@@ -20,5 +20,58 @@ The Arduino `SPI documentation <https://www.arduino.cc/en/reference/SPI>`_ gives
a detailed overview of the library, except for the following RP2040-specific
changes:
* ``SPI.begin(bool hwCS)`` can take an options ``hwCS`` parameter. By passing in ``true`` for ``hwCS`` the sketch does not need to worry about asserting and deasserting the ``CS`` pin between transactions. The default is ``false`` and requires the sketch to handle the CS pin itself, as is the standard way in Arduino.
* The interrupt calls (``usingInterrupt``, ``notUsingInterrupt``, ``attachInterrupt``, and ``detachInterrpt``) are not implemented.
* ``SPI.begin(bool hwCS)`` can take an options ``hwCS`` parameter.
By passing in ``true`` for ``hwCS`` the sketch does not need to worry
about asserting and deasserting the ``CS`` pin between transactions.
The default is ``false`` and requires the sketch to handle the CS
pin itself, as is the standard way in Arduino.
* The interrupt calls (``attachInterrupt``, and ``detachInterrpt``) are not implemented.
SPI Slave (SPISlave)
====================
Slave mode operation is also supported on either SPI interface. Two callbacks are
needed in your app, set through ``SPISlave.onDataRecv`` and ``SPISlave.onDataSent``,
in order to consunme the received data and provide data to transmit.
* The callbacks operate at IRQ time and may be called very frequently at high SPI frequencies. So, make then small, fast, and with no memory allocations or locking.
Asynchronous Operation
======================
Applications can use asynchronous SPI calls to allow for processing while long-running SPI transfers are
being performed. For example, a game could send a full screen update out over SPI and immediately start
processing the next frame without waiting for the first one to be sent. DMA is used to handle
the transfer to/from the hardware freeing the CPU from bit-banging or busy waiting.
Note that asynchronous operations can not be intersped with normal, synchronous ones. ``transferAsync``
should still occur after a ``beginTransaction()`` and when ``finishedAsync()`` returns ``true`` then
``endTransaction()`` should also be called.
All buffers need to be valid throughout the entire operation. Read data cannot be accessed until
the transaction is completed and can't be "peeked" at while the operation is ongoing.
bool transferAsync(const void \*send, void \*recv, size_t bytes)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Begins an SPI asynchronous transaction. Either ``send`` or ``recv`` can be ``nullptr`` if data only needs
to be transferred in one direction.
Check ``finishedAsync()`` to determine when the operation completes and conclude the transaction.
This operation needs to allocate a buffer from heap equal to ``bytes`` in size if ``LSBMODE`` is used.
bool finishedAsync()
~~~~~~~~~~~~~~~~~~~~
Call to check if the asynchronous operations is completed and the buffer passed in can be either read or
reused. Frees the allocated memory and completes the asynchronous transaction.
void abortAsync()
~~~~~~~~~~~~~~~~~
Cancels the outstanding asynchronous transaction and frees any allocated memory.
Examples
========
See the SPItoMyself and SPItoMyselfAsync examples for a complete Master and Slave application.
+16 -1
View File
@@ -14,13 +14,28 @@ from the IDE.
The Arduino-Pico core includes ported versions of the basic Arduino
``Keyboard``, ``Mouse`` and ``Joystick`` libraries. These libraries
allow you to emulate a keyboard, a gamepad or mouse (or all together)
with the Pico in your sketches.
with the Pico in your sketches. These libraries only are available
when using the built-in USB, not the Adafruit library.
See the examples and Arduino Reference at
https://www.arduino.cc/reference/en/language/functions/usb/keyboard/
and
https://www.arduino.cc/reference/en/language/functions/usb/mouse
HID Polling Interval
--------------------
By default, HID devices will request to be polled every 10ms (i.e. 100x
per second). If you have a higher performance need, you can override
this value by creating a global variable in your main application, set
to the polling period:
.. code:: cpp
int usb_hid_poll_interval = 1; // Set HID poll interval to 1ms (1kHz)
void setup() {
....
}
Adafruit TinyUSB Arduino Support
--------------------------------
Examples are provided in the Adafruit_TinyUSB_Arduino for the more
+4 -2
View File
@@ -40,9 +40,11 @@ Please note that WiFi on the Pico W is a work-in-progress and there are some imp
* Combined STA/AP mode is not supported
* Multicore is supported, but only one core may run ``WiFi`` code.
* Multicore is supported, but only core 0 may run ``WiFi`` related code.
* FreeRTOS is not yet supported due to the requirement for a very different LWIP implementation. PRs always appreciated!
* FreeRTOS is supported only on core 0 and from within ``setup`` and ``loop``, not tasks, due to the requirement for a very different LWIP implementation. PRs always appreciated!
* LEAmDNS (``MDNS``) is not supported in FreeRTOS due to internal IRQ-time memory allocations.
The WiFi library borrows much work from the `ESP8266 Arduino Core <https://github.com/esp8266/Arduino>`__ , especially the ``WiFiClient`` and ``WiFiServer`` classes.
+1 -1
View File
@@ -5,7 +5,7 @@ NTP allows the Pico to set its internal clock using the internet, and is
required for secure connections because the certificates used have valid
date stamps.
After ``WiFi.begin()`` use ``NTP.begin(s1)`` or ``NTP,begin(s1, s2)`` to
After ``WiFi.begin()`` use ``NTP.begin(s1)`` or ``NTP.begin(s1, s2)`` to
use one or two NTP servers (common ones are ``pool.ntp.org`` and
``time.nist.gov``) .
+39 -1
View File
@@ -20,7 +20,45 @@ diagram for your board, or it won't work.
Other than that, the API is compatible with the Arduino standard.
Both master and slave operation are supported.
Master transmissions are buffered (up to 128 bytes) and only performed
Master transmissions are buffered (up to 256 bytes) and only performed
on ``endTransmission``, as is standard with modern Arduino Wire implementations.
For more detailed information, check the `Arduino Wire documentation <https://www.arduino.cc/en/reference/wire>`_ .
Asynchronous Operation
----------------------
Applications can use asynchronous I2C calls to allow for processing while long-running I2C operations are
being performed. For example, a game could send a full screen update out over I2C and immediately start
processing the next frame without waiting for the first one to be sent over I2C. DMA is used to handle
the transfer to/from the I2C hardware freeing the CPU from bit-banging or busy waiting.
Note that asynchronous operations can not be intersped with normal, synchronous ones. Fully complete an
asynchronous operation before attempting to do a normal ``Wire.beginTransaction()`` or ``Wire.requestFrom``.
Also, all buffers need to be valid throughout the entire operation. Read data cannot be accessed until
the transaction is completed and can't be "peeked" at while the operation is ongoing.
bool writeAsync(uint8_t address, const void \*buffer, size_t bytes, bool sendStop)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Begins an I2C asynchronous write transaction. Writes to ``address`` of ``bytes`` from ``buffer`` and
at the end will send an I2C stop if ``sendStop`` is ``true``.
Check ``finishedAsync()`` to determine when the operation completes and conclude the transaction.
This operation needs to allocate a buffer from heap equal to 2x ``bytes`` in size.
bool readAsync(uint8_t address, void \*buffer, size_t bytes, bool sendStop)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Begins an I2C asynchronous read transaction. Reads from ``address`` for ``bytes`` into ``buffer`` and
at the end will send an I2C stop if ``sendStop`` is ``true``.
Check ``finishedAsync()`` to determine when the operation completes and conclude the transaction.
This operation needs to allocate a buffer from heap equal to 4x ``bytes`` in size.
bool finishedAsync()
~~~~~~~~~~~~~~~~~~~~
Call to check if the asynchronous operations is completed and the buffer passed in can be either read or
reused. Frees the allocated memory and completes the asynchronous transaction.
void abortAsync()
~~~~~~~~~~~~~~~~~
Cancels the outstanding asynchronous transaction and frees any allocated memory.
+1
View File
@@ -2,6 +2,7 @@
// BTstack features that can be enabled
#define ENABLE_LOG_INFO
#define ENABLE_LOG_DEBUG
#define ENABLE_LOG_ERROR
#define ENABLE_PRINTF_HEXDUMP
#define ENABLE_SCO_OVER_HCI
+17 -21
View File
@@ -1,11 +1,9 @@
#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H
#pragma once
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// Critical section protection
extern void noInterrupts();
extern void interrupts();
@@ -13,8 +11,12 @@ extern void interrupts();
#define SYS_ARCH_PROTECT(lev) noInterrupts
#define SYS_ARCH_UNPROTECT(lev) interrupts
extern unsigned long get_rand_32(void);
#define LWIP_RAND() get_rand_32()
extern unsigned long __lwip_rand(void);
#define LWIP_RAND() __lwip_rand()
#ifndef __LWIP_MEMMULT
#define __LWIP_MEMMULT 1
#endif
// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)
@@ -24,10 +26,10 @@ extern unsigned long get_rand_32(void);
#define MEM_LIBC_MALLOC 0
#define MEM_ALIGNMENT 4
#define MEM_SIZE 16384
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define MEM_SIZE (__LWIP_MEMMULT * 16384)
#define MEMP_NUM_TCP_SEG (32)
#define MEMP_NUM_ARP_QUEUE (10)
#define PBUF_POOL_SIZE (__LWIP_MEMMULT > 1 ? 32 : 24)
#define LWIP_ARP 2
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
@@ -40,12 +42,13 @@ extern unsigned long get_rand_32(void);
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define LWIP_STATS 0
#define LWIP_STATS_DISPLAY 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_CHKSUM_ALGORITHM 0
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
@@ -57,7 +60,8 @@ extern unsigned long get_rand_32(void);
#define LWIP_DHCP_DOES_ACD_CHECK 0
// See #1285
#define MEMP_NUM_UDP_PCB 6
#define MEMP_NUM_UDP_PCB (__LWIP_MEMMULT * 6)
#define MEMP_NUM_TCP_PCB (__LWIP_MEMMULT * 5)
#if LWIP_IPV6
#define LWIP_IPV6_DHCP6 1
@@ -70,12 +74,7 @@ extern void __setSystemTime(unsigned long long sec, unsigned long us);
//#define SNTP_SERVER_ADDRESS "pool.ntp.org"
#define SNTP_SERVER_DNS 1
#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif
#define LWIP_DEBUG 0
#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
@@ -108,6 +107,3 @@ extern void __setSystemTime(unsigned long long sec, unsigned long us);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif /* __LWIPOPTS_H__ */
+2 -2
View File
@@ -13,7 +13,7 @@
#define PICO_SDK_VERSION_MAJOR 1
#define PICO_SDK_VERSION_MINOR 5
#define PICO_SDK_VERSION_REVISION 0
#define PICO_SDK_VERSION_STRING "1.5.0"
#define PICO_SDK_VERSION_REVISION 1
#define PICO_SDK_VERSION_STRING "1.5.1"
#endif
+27
View File
@@ -3,15 +3,25 @@
#######################################
Arduino KEYWORD3 RESERVED_WORD
defined KEYWORD3 RESERVED_WORD
#######################################
# Datatypes (KEYWORD1)
#######################################
Dir KEYWORD1
File KEYWORD1
timeval KEYWORD1
time_t KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
openDir KEYWORD2
setConfig KEYWORD2
fileCreationTime KEYWORD2
setup1 KEYWORD2
loop1 KEYWORD2
@@ -61,7 +71,24 @@ digitalReadFast KEYWORD2
enableDoubleResetBootloader KEYWORD2
openDir KEYWORD2
next KEYWORD2
getLastWrite KEYWORD2
getCreationTime KEYWORD2
fileTime KEYWORD2
fileCreationTime KEYWORD2
check KEYWORD2
setTimeCallback KEYWORD2
settimeofday KEYWORD2
sprintf_P KEYWORD2
strcpy_P KEYWORD2
snprintf_P KEYWORD2
strncpy_P KEYWORD2
OUTPUT_2MA LITERAL1
OUTPUT_4MA LITERAL1
OUTPUT_8MA LITERAL1
OUTPUT_12MA LITERAL1
ARDUINO_ARCH_RP2040 LITERAL1
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -1
View File
@@ -94,7 +94,9 @@ SECTIONS
/* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
* FLASH ... we will include any thing excluded here in .data below by default */
*(.init)
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
/* Some of these excludes required for PicoDVI library, won't affect most code */
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a: *interp.c.obj *divider.S.obj *PicoDVI.cpp.o *dvi.c.o) .text*)
*(.fini)
/* Pull all c'tors into .text */
*crtbegin.o(.ctors)
BIN
View File
Binary file not shown.
-2
View File
@@ -1,2 +0,0 @@
source [find interface/picoprobe.cfg]
source [find target/rp2040.cfg]
+5 -4
View File
@@ -152,6 +152,8 @@
-Wl,--wrap=realloc
-Wl,--wrap=free
-Wl,--wrap=lwip_init
-Wl,--wrap=pbuf_header
-Wl,--wrap=pbuf_free
-Wl,--wrap=pbuf_alloc
@@ -201,13 +203,12 @@
-Wl,--wrap=raw_sendto
-Wl,--wrap=raw_remove
-Wl,--wrap=netif_add
-Wl,--wrap=netif_remove
-Wl,--wrap=cyw43_cb_process_ethernet
-Wl,--wrap=cyw43_cb_tcpip_set_link_up
-Wl,--wrap=cyw43_cb_tcpip_set_link_down
-Wl,--wrap=cyw43_tcpip_link_status
-Wl,--wrap=cyw43_cb_tcpip_init
-Wl,--wrap=cyw43_cb_tcpip_deinit
-Wl,--wrap=get_rand_64
-Wl,--wrap=get_rand_32
-Wl,--wrap=sleep_until
+9 -1
View File
@@ -79,6 +79,10 @@ void ADCInput::onReceive(void(*fn)(void)) {
}
bool ADCInput::begin() {
if (_running) {
return false;
}
_running = true;
_isHolding = 0;
@@ -105,7 +109,11 @@ bool ADCInput::begin() {
setFrequency(_freq);
_arb = new AudioBufferManager(_buffers, _bufferWords, 0, INPUT, DMA_SIZE_16);
_arb->begin(DREQ_ADC, (volatile void*)&adc_hw->fifo);
if (!_arb->begin(DREQ_ADC, (volatile void*)&adc_hw->fifo)) {
delete _arb;
_arb = nullptr;
return false;
}
_arb->setCallback(_cb);
adc_fifo_drain();
@@ -1,5 +1,5 @@
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFi.h>
#include <LEAmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
@@ -22,11 +22,11 @@ void setup() {
rp2040.restart();
}
// Port defaults to 8266
// ArduinoOTA.setPort(8266);
// Port defaults to 2040
// ArduinoOTA.setPort(2040);
// Hostname defaults to esp8266-[ChipID]
// ArduinoOTA.setHostname("myesp8266");
// Hostname defaults to pico-[ChipID]
// ArduinoOTA.setHostname("mypico");
// No authentication by default
// ArduinoOTA.setPassword("admin");
@@ -1,5 +1,5 @@
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFi.h>
#include <LEAmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
Submodule libraries/AsyncUDP added at dd32bfa7d9
@@ -20,12 +20,13 @@
*/
#include <Arduino.h>
#include "hardware/dma.h"
#include "hardware/irq.h"
#include <hardware/dma.h>
#include <hardware/irq.h>
#include "AudioBufferManager.h"
static int __channelCount = 0; // # of channels left. When we hit 0, then remove our handler
static AudioBufferManager* __channelMap[12]; // Lets the IRQ handler figure out where to dispatch to
static int __channelCount = 0; // # of channels left. When we hit 0, then remove our handler
static AudioBufferManager* __channelMap[12]; // Lets the IRQ handler figure out where to dispatch to
static bool __irqInstalled = false; // Have we put in our IRQ handler yet?
AudioBufferManager::AudioBufferManager(size_t bufferCount, size_t bufferWords, int32_t silenceSample, PinMode direction, enum dma_channel_transfer_size dmaSize) {
_running = false;
@@ -73,17 +74,10 @@ AudioBufferManager::~AudioBufferManager() {
if (_running) {
_running = false;
for (auto i = 0; i < 2; i++) {
dma_channel_set_irq0_enabled(_channelDMA[i], false);
dma_channel_cleanup(_channelDMA[i]);
__channelMap[_channelDMA[i]] = nullptr;
dma_channel_abort(_channelDMA[i]);
dma_channel_unclaim(_channelDMA[i]);
dma_channel_acknowledge_irq0(_channelDMA[i]);
}
__channelCount--;
if (!__channelCount) {
irq_set_enabled(DMA_IRQ_0, false);
// TODO - how can we know if there are no other parts of the core using DMA0 IRQ??
irq_remove_handler(DMA_IRQ_0, _irq);
__channelCount--;
}
}
interrupts();
@@ -114,7 +108,7 @@ bool AudioBufferManager::begin(int dreq, volatile void *pioFIFOAddr) {
// Get ping and pong DMA channels
for (auto i = 0; i < 2; i++) {
_channelDMA[i] = dma_claim_unused_channel(true);
_channelDMA[i] = dma_claim_unused_channel(false);
if (_channelDMA[i] == -1) {
if (i == 1) {
dma_channel_unclaim(_channelDMA[0]);
@@ -122,7 +116,7 @@ bool AudioBufferManager::begin(int dreq, volatile void *pioFIFOAddr) {
return false;
}
}
bool needSetIRQ = __channelCount == 0;
// Need to know both channels to set up ping-pong, so do in 2 stages
for (auto i = 0; i < 2; i++) {
dma_channel_config c = dma_channel_get_default_config(_channelDMA[i]);
@@ -148,9 +142,10 @@ bool AudioBufferManager::begin(int dreq, volatile void *pioFIFOAddr) {
__channelMap[_channelDMA[i]] = this;
__channelCount++;
}
if (needSetIRQ) {
if (!__irqInstalled) {
irq_add_shared_handler(DMA_IRQ_0, _irq, PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY);
irq_set_enabled(DMA_IRQ_0, true);
__irqInstalled = true;
}
dma_channel_start(_channelDMA[0]);
@@ -257,7 +252,7 @@ void __not_in_flash_func(AudioBufferManager::_dmaIRQ)(int channel) {
_active[1] = _takeFromList(&_filled);
}
_overunderflow = _overunderflow | (_active[1] == _silence);
dma_channel_set_read_addr(channel, _active[0]->buff, false);
dma_channel_set_read_addr(channel, _active[1]->buff, false);
} else {
if (_empty) {
_addToList(&_filled, _active[0]);
@@ -266,7 +261,7 @@ void __not_in_flash_func(AudioBufferManager::_dmaIRQ)(int channel) {
} else {
_overunderflow = true;
}
dma_channel_set_write_addr(channel, _active[0]->buff, false);
dma_channel_set_write_addr(channel, _active[1]->buff, false);
}
dma_channel_set_trans_count(channel, _wordsPerBuffer * (_dmaSize == DMA_SIZE_16 ? 2 : 1), false);
dma_channel_acknowledge_irq0(channel);
@@ -21,7 +21,7 @@
#pragma once
#include <Arduino.h>
#include "hardware/dma.h"
#include <hardware/dma.h>
class AudioBufferManager {
public:
@@ -0,0 +1,68 @@
#include <BTstackLib.h>
#include <SPI.h>
/*
EXAMPLE_START(LEDeviceScanner): LE Device Scanner
@text The LE Device Scanner monitors BLE device advertisements,
keeping track of one or more known devices as they appear.
*/
// Application state
int counter[2] = {0, 0};
BD_ADDR known_devices[2] = {BD_ADDR("DB:88:B6:70:9E:EB"),
BD_ADDR("C9:60:BD:F2:B4:9D")
};
/*
@section Setup
@text After BTstack.setup(), BTstack is configured to call
advertisementCallback whenever an Advertisement was received.
*/
/* LISTING_START(LEDeviceScannerSetup): LE Device Scanner Setup */
void setup(void) {
Serial.begin(9600);
BTstack.setBLEAdvertisementCallback(advertisementCallback);
BTstack.setup();
BTstack.bleStartScanning();
}
/* LISTING_END(LEDeviceScannerSetup): LE Device Scanner Setup */
/*
@section Loop
@text In the standard Arduino loop() function, BTstack's loop() is called.
*/
/* LISTING_START(LEDeviceScannerLoop): Loop */
void loop(void) {
BTstack.loop();
}
/* LISTING_END(LEDeviceScannerLoop): Loop */
/*
@section Advertisement Callback
@text Whenever an Advertisement is received, isIBeacon() checks if
it contains an iBeacon.
If it's not an iBeacon, the BD_ADDR is compared to the address we are
looking for and the counter is incremented.
*/
/* LISTING_START(LEDeviceScannerAdvertisementCallback): Advertisement Callback
*/
void advertisementCallback(BLEAdvertisement *bleAdvertisement) {
if (!(bleAdvertisement->isIBeacon())) {
Serial.print("Device discovered: ");
Serial.println(bleAdvertisement->getBdAddr()->getAddressString());
for (size_t i = 0; i < sizeof(counter) / sizeof(int); i++) {
if (memcmp(bleAdvertisement->getBdAddr()->getAddress(),
known_devices[i].getAddress(), sizeof(known_devices[i])) == 0) {
counter[i]++;
Serial.printf("Known device: %s, has been discovered %d times.\n",
known_devices[i].getAddressString(), counter[i]);
}
}
}
}
/* LISTING_END(LEDeviceScannerAdvertisementCallback): Advertisement Callback */
+14 -7
View File
@@ -396,9 +396,13 @@ BD_ADDR::BD_ADDR(void) {
}
BD_ADDR::BD_ADDR(const char * address_string, BD_ADDR_TYPE address_type) : address_type(address_type) {
(void) address_string;
// TODO: implement
// log_error("BD_ADDR::BD_ADDR(const char *, BD_ADDR_TYPE) not implemented yet!");
int processed = sscanf(address_string, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", address, address + 1,
address + 2, address + 3, address + 4, address + 5);
if (processed != 6) { // Set address to zeroes if we did not get six bytes back.
for (int i = 0; i < 6; i++) {
address[i] = 0;
}
}
}
BD_ADDR::BD_ADDR(const uint8_t address[6], BD_ADDR_TYPE address_type) : address_type(address_type) {
@@ -774,6 +778,10 @@ static hci_transport_config_uart_t config = {
static btstack_packet_callback_registration_t hci_event_callback_registration;
void BTstackManager::setup(void) {
setup("BTstack LE Shield");
}
void BTstackManager::setup(const char * name) {
//#ifdef PIN_LED
// pinMode(PIN_LED, OUTPUT);
@@ -800,9 +808,6 @@ void BTstackManager::setup(void) {
hci_add_event_handler(&hci_event_callback_registration);
l2cap_init();
// setup central device db
le_device_db_init();
sm_init();
att_server_init(att_db_util_get_address(), att_read_callback, att_write_callback);
@@ -822,7 +827,6 @@ void BTstackManager::setup(void) {
const uint8_t flags[] = { 0x02, 0x01, 0x02 };
memcpy(&adv_data[pos], flags, sizeof(flags));
pos += sizeof(flags);
const char * name = "BTstack LE Shield";
adv_data[pos++] = strlen(name) + 1;
adv_data[pos++] = 0x09;
memcpy(&adv_data[pos], name, strlen(name));
@@ -882,6 +886,9 @@ uint16_t BTstackManager::addGATTCharacteristicDynamic(UUID * uuid, uint16_t flag
void BTstackManager::setAdvData(uint16_t adv_data_len, const uint8_t * adv_data) {
gap_advertisements_set_data(adv_data_len, (uint8_t*) adv_data);
}
void BTstackManager::setScanData(uint16_t scan_data_len, const uint8_t * scan_data) {
gap_scan_response_set_data(scan_data_len, (uint8_t*) scan_data);
}
void BTstackManager::startAdvertising() {
gap_advertisements_enable(1);
}

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