Compare commits

...

701 commits

Author SHA1 Message Date
Limor "Ladyada" Fried
775fb76cb8
Merge branch 'earlephilhower:master' into master 2025-06-15 16:20:49 -04:00
ladyada
af1374cb18 fix pins for rev C 2025-06-15 14:05:16 -04:00
Earle F. Philhower, III
f07079bb7d
Remove dead debug code in PIOProgram (#2992) 2025-06-12 11:15:12 -07:00
Earle F. Philhower, III
e7a23550ce
Update to GCC 14.3, Newlib 4.5.0 (#2975)
Moves to just released GCC 14.3

Moves to full-fat printf/scanf because Newlib no longer supports all the
calls libstdc++ requires with the older, smaller, nano-formatted-io option.

Moves to latest SDK develop branch with important float acceleration fixes
for the RP2350, among other updates.

Moves to latest pioasm, picotool develop branches

* SDK was refactored, update the includes
* Rebuild PicoSDK and BearSSL libs
* Update certs in BSSL validation example
* Don't spell check the certs!
* Updated tools with full fat++ newlib printf/scanf
2025-06-12 10:54:37 -07:00
Earle F. Philhower, III
0beb2d4ae8
Add SDIO PIN definitions for Adafruit Metro RP2040 (#2989)
Fixes #2985
2025-06-12 08:16:55 -07:00
ladyada
e5efb8b764 fix missing peripherals, this is for rev C 2025-06-01 15:29:48 -04:00
Maximilian Gerhardt
4de3ea94a9
Cleanly install PlatformIO platform from scratch (#2982)
Prevents weird update errors stemming from an already installed platform
(cached), then updating some files in it manually and then pio pkg updating it.
2025-06-01 08:08:45 -07:00
Maximilian Gerhardt
68f1da5f94
Mark all boards as picosdk compatible in PlatformIO board definition (#2980) 2025-05-31 12:19:21 -07:00
Earle F. Philhower, III
948e9bfd22
Clear any existing IP before sending a DHCP request (#2979)
Fixes #2978
2025-05-31 11:20:14 -07:00
Earle F. Philhower, III
73bd6a0891
Send DHCP request on ::begin even if lease exists (#2977)
When a link comes up, we were only sending a DHCP request if the existing
netif's ipaddress was 0.  When a DHCP lease is acquired at first that IP
is changed to the given address, and if we do another ::begin we wouldn't
dhcp_start to send a new request and use the old one (until its lease
expired).

In the case of network changing (i.e. WiFiMulti on different nets or
moving an Ethernet cable to another router) that old address would not
be valid.

Track if an IP address has been manually set and use that to determine
if DHCP needs to be re-requested instead of looking at the old netif's
ipaddress.

Fixes #2974
2025-05-31 09:19:42 -07:00
ladyada
ecd662640f Merge branch 'master' of github.com:adafruit/arduino-pico 2025-05-24 15:05:34 -04:00
ladyada
0f211d1aa5 fix button names 2025-05-24 15:05:29 -04:00
Earle F. Philhower, III
f3df355663
Fix BSTstackLib service UUID reporting to client (#2968)
Fixes #2967
2025-05-22 12:34:26 -07:00
Earle F. Philhower, III
7dcfe4d483 Update version 2025-05-22 08:19:51 -07:00
Lorandil
3df1392a1b
Added 'TwoWire::setBufferSize()' to Wire library (#2962)
'setBufferSize()' allows to modify the receive buffer size (inspired by the ESP32 code)
2025-05-21 13:57:35 -07:00
Limor "Ladyada" Fried
9043412c5f
Merge branch 'earlephilhower:master' into master 2025-05-18 15:20:50 -04:00
Earle F. Philhower, III
7c51742522
Add PSRAM option for Adafruit Metro RP2350 (#2961)
Fixes #2960
2025-05-16 08:34:01 -07:00
Earle F. Philhower, III
08353deb88 Ignore libpico build dirs for git 2025-05-14 15:00:03 -07:00
Earle F. Philhower, III
d5e844b2bd
Panic on stack protector crash instead of exit (#2955)
Newlib has a stack protector fail handler which write(2)s a
message to STDERR which doesn't work here.  Override with a
call to panic().

Tell GCC to protect all functions for stack protection instead of
ones that it heuristically decides need protection.  Slower but
safer, and only when stack protection is enabled.
2025-05-14 07:38:25 -07:00
Ricardo Marques
de7f1a7e83
Fixed generic PIN_LED and SPI0 Pin assignment on WIZnet W55RP20-EVB-Pico. (#2956)
* Update pins_arduino.h

Changed PIN_LED to match USERLED on PCB. Removed unavailable pins from SPI0 connection.

* Update pins_arduino.h

Uncommented SPI0 pins and reassigned them over GPIO 2,3,4,5.
2025-05-13 17:18:04 -07:00
jeroenzwan
19b14898ea
Add target platform for compiling (#2939)
* add target platform for compiling

* added target specification for riscv

---------

Co-authored-by: jeroen <jeroen.zwanepol@tective.nl>
2025-05-09 07:57:50 -07:00
Jan-Philipp
304e9ce2d1
Make Arduino IDE ask for OTA password (#2938) 2025-05-07 09:03:29 -07:00
Earle F. Philhower, III
2bc00bef57
Fix ADCInput masking (#2937)
Fixes #2935

The PICO_2350A patch flipped the logic of the ADCInput bitmask calcs
causing the 2040 and 2350A to use bitmasks for the 2350B (i.e. wrong
GPIOs) and vice versa.
2025-05-05 09:16:29 -07:00
Earle F. Philhower, III
47c2cd2b0b Update version 2025-05-02 08:59:52 -07:00
Ahmed ARIF
59614a99c8
optimize parity calculations in SerialPIO (#2932) (#2933)
use bit manipulation technique from http://www.graphics.stanford.edu/~seander/bithacks.html#ParityParallel for parity calculation

Co-authored-by: Ahmed ARIF <contact@eotics.com>
2025-05-01 14:06:52 -07:00
Earle F. Philhower, III
227d71ed18
Fix RP2350B SPI RX pin list (#2931)
Fixes #2930
2025-04-29 16:29:45 -07:00
Earle F. Philhower, III
5e74bbbbb2
Rewrite SerialPIO receive path, ensure proper edge (#2929)
The SerialPIO(SoftwareSerial) receive path was convoluted and required
a lot of work on the host to get the actual data out.  It also wasn't
always sampling on the proper edge leading to errors whenever clocks
or hold times shifted slightly.

Rewrite the SerialPIO RX path to explicitily wait for start bit,
pause 1/2 bit time, then idle for a full bit time for all bits.
Takes more PIO instruction memory but works flawlessly even with
mismatched clocks.

Tested with a loopback from HW UART to SW UART with a 5% clock
mismatch @ 19200 baud without reception errors, whereas the
original code would fail with less than a 0.5% variation.

Fixes #2928

````

SoftwareSerial s(15, -1);
void setup() {
  Serial1.setTX(0);
  Serial1.begin(19200 + 1920/2, SERIAL_8N1);
  s.begin(19200, SERIAL_8N1);
}

void loop() {
  Serial.println("---");
  Serial1.write("Had we but world enough and time", 32);
  uint32_t now = millis();
  while (millis() - now < 500) {
    while (s.available()) {
      auto c = s.read();
      Serial.printf("%02x '%c'\n", c, c);
    }
  }
}
````
2025-04-29 13:39:34 -07:00
Earle F. Philhower, III
8d58a9207f
Update LittleFS and Adafruit USB libraries (#2919)
Only very minor changes to the submodules were noted.  Should not have
any effect on this core.
2025-04-18 18:00:56 -07:00
Earle F. Philhower, III
bc5b2c24ff
Fix rp2040.getCycleCount() from core1 (#2915)
Fixes #2914

There are 2 systick units, one per core.  Set up and start core1's
systick unit and track each core's epoch separately.

Document a method of preserving 100% user-only code on core1
and add a core1_disable_systick boolean flag that works like the
separate stack one.
2025-04-18 09:16:36 -07:00
Wai Weng
40b9d5b07e
Add pin definitions for I2C1 on Cytron IRIV (#2916)
Co-authored-by: Kong Wai Weng <waiweng@cytron.io>
2025-04-18 08:59:23 -07:00
Earle F. Philhower, III
07ea22d877
Generate PWMAudio pacer frequencies for 176/276MHz (#2913)
Overclock settings changed, need to update the precalculated pacer
fractions for PWMAudio.
2025-04-17 08:21:14 -07:00
Earle F. Philhower, III
253e946dcb
Update tools README.md 2025-04-17 07:04:26 -07:00
Earle F. Philhower, III
60d28d6c92
Add PIO.h header verification to CI (#2911)
* Add PIO.h header verification to CI

Ensure all PIO .pio.h headers match the .pio sources in the tree

* Install all tools for Style check

* Clean up mismatched PIO headers

No functional changes, but the PDM pdm.pio file did not init a data pin
while the pdm.pio.h (the one actually used in the core) did.  Correct to
match.

* No need for submodules in the style check
2025-04-16 14:56:31 -07:00
Earle F. Philhower, III
e8bd9daa82 Update version 2025-04-16 13:22:14 -07:00
Earle F. Philhower, III
9747990c16
Fix remaining PICO_RP2350B reference (#2910)
Minor fix to #2898
2025-04-16 08:28:53 -07:00
Liz
299f8e28f2
Merge branch 'earlephilhower:master' into master 2025-04-15 13:08:44 -04:00
Liz
6e48cffd62
add adafruit fruit jam and feather rp2350 adalogger (#2907)
* add new RP2350 Metro!

* lol

* fruity!

* Define HSTX pins on Adafruit boards with HSTX or DVI connectors

* fixname

* update rp2350b for fruit jam

* add rp2350 adalogger (#9)

adding rp2350 adalogger

* update psram in makeboards

* Update adafruit_fruitjam.json

---------

Co-authored-by: ladyada <limor@ladyada.net>
Co-authored-by: Jeff Epler <jepler@gmail.com>
2025-04-15 10:03:21 -07:00
Liz
123ae0ff8b Update adafruit_fruitjam.json 2025-04-15 12:44:51 -04:00
Liz
0420446529 update psram in makeboards 2025-04-15 12:22:11 -04:00
Limor "Ladyada" Fried
88c717d420
Merge pull request #10 from adafruit/rp2350_adalogger
adding rp2350 adalogger
2025-04-15 11:27:54 -04:00
Earle F. Philhower, III
9ac7892bd6
Update W55RP20 example for proper CS pin (#2906)
Fixes #2903
2025-04-15 08:17:47 -07:00
Liz
407bdc93f4
add rp2350 adalogger (#9)
adding rp2350 adalogger
2025-04-15 11:08:13 -04:00
Liz
91f8872a63 update rp2350b for fruit jam 2025-04-15 10:54:57 -04:00
Liz
d938633048
Merge branch 'earlephilhower:master' into rp2350_adalogger 2025-04-15 10:49:30 -04:00
Earle F. Philhower, III
073094fe0e
Update adc.rst for RP2350B 2025-04-15 07:39:17 -07:00
Earle F. Philhower, III
2a46bcfc0f
Update contrib.rst
Update the PICO_RP2350A macro usage
2025-04-14 11:41:20 -07:00
Earle F. Philhower, III
e05dd50d62
Convert to SDK RP2350A/B determination (#2898)
* Convert to SDK RP2350A/B determination

Fixes #2878

The SDK uses `defined(PICO_RP2350) && !PICO_RP2350A` to indicate an RP2350B
chip, not the define PICO_RP2350B.

Match the SDK's usage by converting from `defined(PICO_RP2350B)` to
`defined(PICO_RP2350) && !PICO_RP2350A` and update the chip variants
accordingly.

* Need to explicitly override PICO_RP2350A for all

The *SDK*'s board definition file hardcodes a PICO_RP2350A value for
all boards, but we use the same board file for both A and B variants.
Override the SDK board definition in the variant definition file.

* Generic RP2350 needs 2-stage PICO_RP2350A setting

Also ensure SDK board definition included before pins_arduino.h for
clearing up redefinition errors.

* Factor out undef PICO_RP2350A

* Update Arduino.h
2025-04-08 16:02:54 -07:00
Earle F. Philhower, III
54885d79e0
Add explicit using arduino::IPAddress to headers (#2894)
Fix issue with WiFiNINA includes.  Fixes #2887
2025-04-07 10:17:03 -07:00
ladyada
cc96a13bed fixname 2025-03-20 13:19:38 -04:00
Limor "Ladyada" Fried
e24489b69d
Merge branch 'earlephilhower:master' into master 2025-03-20 13:16:16 -04:00
Earle F. Philhower, III
ecf2b2e39f
Add WiFi region for Pico2W (#2872)
Fixes #2871
2025-03-19 08:47:12 -07:00
Earle F. Philhower, III
49397a7f3d Update version 2025-03-18 17:03:18 -07:00
Earle F. Philhower, III
aabbba67ce
Add some Doxygen documentation to core and libraries (#2780) 2025-03-18 17:00:44 -07:00
Earle F. Philhower, III
50b9ea99bd
Add Olimex Pico2XL and Pico2XXL (#2868)
Fixes #2820
2025-03-18 16:40:51 -07:00
Earle F. Philhower, III
beece2ec9d
Add <1MB FS options for multi-size boards (#2867)
Boards with selectable flash sizes only had a 1MB FS as the smallest
option on 2MB boards.  For the normal Pico @ 2MB, though, we supported
filesystems down to 64KB.  Add those same options to the 2MB SKUs
of configurable boards.
2025-03-18 16:29:54 -07:00
Earle F. Philhower, III
1a8735700f
Use flash size menu for Olimex boards (#2866)
Remove duplicated boards with just different flash sizes.  Use the flash
size menu to select 2 or 16 MB units.
2025-03-18 15:26:34 -07:00
Earle F. Philhower, III
cc1af990b4
Add Pimoroni Servo2040 (#2865)
Fixes #2730 .  Untested, based off of schematics
2025-03-18 15:11:25 -07:00
Eris Fairbanks
0ec1dc6724
Bidirectional TDM Support (#2843)
* Initial commit.

* Works with AK4619 in TDM128 I2S compatibility mode set to rising BCLK.

* Works with I2S compat mode with BCLK mode set to 0 on AK4619.
2025-03-14 11:35:37 -07:00
Earle F. Philhower, III
15d1c6813a
Redo UF2 discovery for Windows compatibility (#2853)
Windows Python doesn't seem to kill the worker Thread properly when the IDE
is exited, leading to a) multiple Python3 instances on a PC after many uses
and b) errors updating the core when it tries to re-install Python3 while
still having the older version's EXE loaded and in use.

When an exception happens on the input() call under Windows, it seems like it
can still leave a thread running.  Add one more flag, caught in a global
exception handler.

Works around https://github.com/arduino/arduino-cli/issues/2867
2025-03-14 10:08:37 -07:00
Earle F. Philhower, III
cdf0a65d0f
Fix invalid overclock speeds 175 and 275 MHz (#2855)
Fixes #2854

Change 175->176 and 275->276 in CPU speed menu to avoid panic when
attempting to set a clock that wasn't exactly possible.
2025-03-13 20:18:50 -07:00
Earle F. Philhower, III
e60858c327 Update version 2025-03-11 13:35:52 -07:00
Earle F. Philhower, III
bebd1dff50
Update README.md (#2848) 2025-03-11 13:34:08 -07:00
Earle F. Philhower, III
14145e4469
Update to SDK 2.1.2-develop (#2844)
Supercedes #2815

Move to pico-sdk official develop branch which includes a necessary
IRQ header fix.

200MHz is now default for the Pico, but 133 is still available from
the menus.
2025-03-11 13:30:17 -07:00
Dryw Wade
d9d556bcd0
Add SparkFun XRP Controller (#2847) 2025-03-11 13:00:55 -07:00
InfiniteCoder
5bd1a3a0f6
A2DP: scanAsyncDone & scanAsyncResults; fix write and availableForWrite (#2839) 2025-03-06 10:55:56 -08:00
Earle F. Philhower, III
5bfc35caf5
Enable add'l UART_AUX pinouts for RP2350 (#2837)
Fixes #2835.  Thanks @deltaford!
2025-03-05 07:02:32 -08:00
Alex Brudner
8e1e709ab1
Add SparkFun IoT RedBoard RP2350 (#2836) 2025-03-03 16:30:42 -08:00
46a58fb4b5
Early out of (un)maskInterrupts() if no GPIO interrupts need to be masked (#2831)
My application is designed to generate HSTX data on core0 in interrupts,
but also uses hardware SPI for SD card access.

It turns out that the amount of time spent in maskInterrupts/
unmaskInterrupts, even with an empty _usingIRQs, is too long.

Add a quick check and avoid touching the interrupt disable flag if
there's not actually any GPIO interrupt to (un)mask.
2025-02-28 12:44:47 -08:00
Earle F. Philhower, III
8deb6b9724
Adjust the PSRAM clock when over/underclock F_SYS (#2824)
* Adjust the PSRAM clock when over/underclock F_SYS

Fixes #2818

* Need to increase PSRAM divider before sysclk increase

Per datasheet, when increasing sysclk speed we need to set the qmi
clocks first and do a dummy transfer to ensure no invalid speed
operations happen on the bus.  Handle the logic for this while setting
up the overclock.
2025-02-26 16:38:52 -08:00
6236d1f7c5
Define HSTX pins on Adafruit boards with HSTX or DVI connectors (#2825) 2025-02-25 08:36:58 -08:00
Dryw Wade
91ce323a68
Add SparkFun XRP Controller (Beta) (#2823) 2025-02-24 12:03:55 -08:00
Earle F. Philhower, III
2f82bfd22a
Update README.md 2025-02-23 11:36:36 -08:00
Michael Ring
1689c75ef1
Support Makerbase MKSTHR36 and MKSTHR42 Boards (#2819)
* Support Makerbase MKSTHR36 and MKSTHR42 Boards

* Added missing define for PIN_SERIAL1_* for MKSTHR42 Board
2025-02-23 11:35:53 -08:00
bd5492b6e4
Merge pull request #7 from adafruit/define-hstx-pins
Define HSTX pins on Adafruit boards with HSTX or DVI connectors
2025-02-19 10:35:14 -06:00
eef8dd138c Define HSTX pins on Adafruit boards with HSTX or DVI connectors 2025-02-19 09:45:59 -06:00
brabl2
935eb64a8e
Added WizNet W6100 to the AdvancedWebServer example (#2812) 2025-02-19 07:25:09 -08:00
ladyada
e3ee60f6eb fruity! 2025-02-19 10:12:47 -05:00
Earle F. Philhower, III
31786cdc24 Update version 2025-02-18 12:55:03 -08:00
Earle F. Philhower, III
3d17a56ecf
Fix Wire/Wire1 definitions for Xaio RP2350 (#2811)
Fixes #2808
2025-02-18 10:28:12 -08:00
Earle F. Philhower, III
3cb5c315f3
Correct Seeed XAIO RP2350 config (#2803)
Fixes #2801
2025-02-15 16:15:29 -08:00
Limor "Ladyada" Fried
c65cbded84
Merge branch 'earlephilhower:master' into master 2025-02-10 16:48:47 -05:00
Earle F. Philhower, III
0148b1469c
Update README.md 2025-02-09 09:53:46 -08:00
Stefan Nürnberger
96a4059f09
added I2C TwoWire::busIdle to be checked by writeReadAsync (#2798)
---------
Co-authored-by: Stefan Nuernberger <stefan@elexir.eu>
2025-02-09 09:52:45 -08:00
Limor "Ladyada" Fried
c3d15931a4
Add new RP2350 Metro! (#2795) 2025-02-09 09:16:45 -08:00
Limor "Ladyada" Fried
22dfda2c1c
Merge branch 'master' into master 2025-02-09 11:17:11 -05:00
ladyada
cab65de189 lol 2025-02-09 11:16:40 -05:00
Earle F. Philhower, III
c79e543c41
Move to Arduino API 10501 (#2797)
* Move to Arduino API 10501

Track upstream Arduino API headers

* IPAddress V4/V6 compatiblity restored

* Fix WiFiUDP includes

* String differences in example

* HardwareSerial using exported
2025-02-08 22:45:10 -08:00
Stefan Nürnberger
3c556e6729
fixed: Wire::writeReadAsync not setting _dmaSendBufferLen, therefore allocating the DMA buffer anew on every call (#2796)
Co-authored-by: Stefan Nuernberger <stefan@elexir.eu>
2025-02-08 14:15:18 -08:00
ladyada
9c680bd65f add new RP2350 Metro! 2025-02-08 13:26:37 -05:00
Earle F. Philhower, III
5e2fbf324b Update version 2025-02-04 14:34:53 -08:00
Maximilian Gerhardt
fb82f16704
Document PSRAM and Boot2 better (#2792) 2025-02-04 12:01:54 -08:00
Earle F. Philhower, III
79568a3e63
OTA Updater better error codes on OOS (#2793)
Fixes #2785.  Thanks @donmsmall!
2025-02-04 11:54:12 -08:00
Earle F. Philhower, III
b506c010f7
Fix I2C on Adafruit Feather RP2350 HSTX (#2784)
Fixes #2783
2025-01-30 12:08:24 -08:00
Earle F. Philhower, III
8c3170596f
Deduplicate SPI and SoftwareSPI routines (#2779) 2025-01-28 12:47:13 -08:00
Earle F. Philhower, III
acf81f426c
Add PIO-based SoftwareSPI enabling SPI on any pins (#2778)
* Add PIO-based SoftwareSPI enabling SPI on any pins

The Raspberry Pi team has a working PIO-based SPI interface.  Wrap it
to work like a hardware SPI interface, allowing SPI on any pin
combination.

Tested reading and writing an SD card using unmodified SD library.

* Add W5500 example

Good for testing, shows non-contiguous pin outs.
2025-01-27 13:59:52 -08:00
Cooper Dalrymple
a426fbf51d
Add buffer read to AudioBufferManager and I2S (#2777)
* Added buffer read to `AudioBufferManager` and `I2S`. Example and documentation included.
* Update type of words to unsigned in example.
* Improve buffered loopback example.
* Remove const from read buffer.
2025-01-26 10:03:44 -08:00
Cooper Dalrymple
e133147192
Bi-directional I2S support (#2775)
* Initial bi-directional I2S support.

* Formatting update on pioasm file.

* Added loopback example.

* Updated documentation.

* Fix `getOverUnderflow` naming.

* Revert `getOverUnderflow` naming changes.

* Remove python cache file.

* Remove `availableForRead`.

* Updated naming convention of OverUnderflow methods.

* Update constructor to prevent conflicts with existing code.

* Avoid ambiguous `setDATA` in bi-directional mode.

* Use only input buffer manager in `available`.

* Fix input checks in `read` and `peek`.

* Fix erroneous comment.

* Update pio_i2s.pio to pio v1.

* Change pio_i2s.pio back to pio v0.
2025-01-23 16:30:53 -08:00
Earle F. Philhower, III
84826935a9
Don't set SDFAT_FILE_TYPE, default is OK (#2773)
* Don't set SDFAT_FILE_TYPE, default is OK

Fixes #2772

No need to set SDFAT_FILE_TYPE=3 as that is the defaulr value with upstream
SdFat.  Remove it from platform.txt and platform.io build.

* Codespell got all techy
2025-01-22 10:08:28 -08:00
Earle F. Philhower, III
9480c2a55d Update version 2025-01-21 10:15:08 -08:00
Markus Gyger
b3d0ccc7e3
Change duty cycle of PIO Tone to 50% (#2770) 2025-01-21 10:03:31 -08:00
Dryw Wade
5a34395f46
PIOProgram: Replace __pioHighGPIO with pio_get_gpio_base() (#2769)
Fixes #2768
2025-01-21 09:33:04 -08:00
Earle F. Philhower, III
e20c973bf5
SDIO doesn't take a clock speed parameter (#2766)
It's fixed by the PIO program and GPIO slew rates encoded in the SdFAT
driver.  Remove the parameter from the SD/SDFS begins.
2025-01-18 09:19:39 -08:00
Earle F. Philhower, III
452ef17174
Replace ESP8266SdFat w/SdFat 2.3.0, SDIO, ExFAT (#2764)
* Replace ESP8266SdFat w/SdFat 2.3.0, add SDIO and ExFAT support

Remove ESP8266SdFat fork and replaces with upstream SdFat to simplify
maintenance.

This 2.3.0 version adds SDIO support and enables exFAT support.
Also upgraded FAT filename support to 256 chars, identical to  LittleFS.

* Add SDIO support to SD and SDFS, documentation, and examples

* Update SD examples to all support SPI0, SPI1, or SDIO
2025-01-17 15:22:39 -08:00
Earle F. Philhower, III
4785c16243
Update to LittleFS v2.10.1 (#2762)
Minor behavior changes WRT path handling with trailing slashes, but
should not affect anything on the Arduino side.
2025-01-17 10:18:32 -08:00
Earle F. Philhower, III
2506b8e1d1
Update to Adafruit TinyUSB 3.4.2 (#2761)
Should be no change, just keeping in pace with upstream.
2025-01-17 10:03:22 -08:00
Earle F. Philhower, III
7bfe25b8aa
Remove SDK C++ new/delete, duplicated objects (#2760)
* Remove Pico-SDK C++ exception-override new/delete

We support exceptions on and off, but the cxx_options file in the
SDK implemented a single override to new/delete.

Remove it so we will use GCC's build-in operator new/delete
which will be correct for either option (2 different libstdc++
versions are shipped as part of the toolchain).

* Remove duplicated SDK files

The SDK will link in the same compilation unit in the LWIP builds.
Remove them to shrink the repo size by ~28MB.
2025-01-16 15:02:01 -08:00
SomebodyOdd
2348051026
A2DPSink: Remove stubs, fix volume and connect callbacks (#2757)
* A2DPSink: Remove Stream implementation and onTransmit
* A2DPSink: Fix onConnect and onVolume callbacks
* A2DPSink: Remove transmit callback field
2025-01-16 09:37:22 -08:00
Dryw Wade
b4001bfb0e
Add SparkFun IoT Node LoRaWAN (#2745)
* added files to support the SparkFun IoT Node LoRaWAN board

* added rp2053 to our lorawan board defs

* adding updates/new files generated for the iot node board

* Add SPI swap

* Remove incorrect comment from IoT Node LoRawAN

* Replace missing line in boards.txt

* Re-run makeboards.py for IoT Node LoRaWAN

---------

Co-authored-by: Kirk Benell <kirk.benell@sparkfun.com>
2025-01-15 09:47:55 -08:00
Earle F. Philhower, III
0655b7d5b6
Fix ADCInput clocks for multiple inputs (#2755)
When multiple inputs were active, the frequency was being scaled two
times resulting in incorrect sampling speed.  Correct to only scale
the calculation and not the stored value (which is used in `begin`).

Fixes #2754
2025-01-14 15:58:45 -08:00
Earle F. Philhower, III
83b8d122d7
Restore Bluetooth TLV on Pico2/RPiWiFi boards (#2753) 2025-01-13 17:38:51 -08:00
timw01
8caa590f5c
Correct return from NTP.waitSet() (#2736)
Fixes #2735
2025-01-04 17:06:26 -08:00
Earle F. Philhower, III
ec528d34f8
Remove unneeded SDK files from libpico/etc. (#2733)
Pico-SDK changed the output extension of their compilation from "x.c.obj"
to "x.c.o" meaning the removed Newlib and STDIO SDK wrappers were still
being linked in certain situations.  Update make-libpico Cmakefile to
remove the new names.

Fixes debug `printf` output.
2025-01-03 10:42:47 -08:00
Earle F. Philhower, III
5296241949 Update version 2024-12-31 10:35:02 -08:00
Earle F. Philhower, III
d84ff02f03
Allow setting PWMAudio frequency before begin (#2726)
I2S allows setting freq before ::begin, so allow same for PWMAudio.
2024-12-30 10:57:40 -08:00
Earle F. Philhower, III
cc2581afd6
Properly wrap AudioBufferManager block writes (#2725)
The memcpy-version of the ABM::write updated the destination and count
but neglected to move the source forward.  If a block write crossed a
frame boundary then the 2nd frame would repeat the data from the first
half of the buffer.

Fix by incrementing the source pointer by the same amount as was written.
2024-12-29 16:26:23 -08:00
Earle F. Philhower, III
bb682bbb33
Use the distributed ARM ar in libpico, not system (#2721)
Fixes #508
2024-12-29 10:29:42 -08:00
Earle F. Philhower, III
809beffc8b Add AudioOutputBase keyword 2024-12-27 10:15:05 -08:00
Earle F. Philhower, III
fa22c6c627 RTD has its own key for PDF generation 2024-12-27 08:48:39 -08:00
Earle F. Philhower, III
0788a42477 RTD doesn't do formats:PDF, revert 2024-12-27 08:44:58 -08:00
Earle F. Philhower, III
d732ac82ba
Precalculate common PWMAudio dividers, avoid noise (#2714)
Calculating the DMA clock divider for PWMAudio can take a very long time
because there are 65K floating point divisions required.  But most audio
will be one of a dozen sample rates, so it is possible to precalculate
the rates on the host and use a small lookup table to avoid any math at
all.  Removes occasional scratching in PWMAudio when the BackgroundAudio
library changes sample rates.
2024-12-22 14:05:44 -08:00
Earle F. Philhower, III
5fb5e16be8
Add real block write for AudioRequestBuffer (#2712)
Optimize AudioRequestBuffer writing when large blocks are available (i.e.
I2S writes of full MP3 or AAC frames in BackgroundAudio).  Update I2S to use
the new call.  Reduces 1152 calls to arb::write() to a single call/return
and optimized memcpy in that case.
2024-12-21 14:15:40 -08:00
Earle F. Philhower, III
45c0b3a1b4
Move MacX86 runner up to new minimum spec (#2711)
The MacOS12 runner is dead, so move up to the lowest version still available for CI.
2024-12-21 10:27:44 -08:00
Markus Gyger
7961d2943d
Overclock to 153.6 MHz (instead of 147.6 MHz) for I²S 48 kHz sample rate (#2708) 2024-12-21 07:36:57 -08:00
Kjell Braden
4d03edc7d5
Don't go through runtime initializers when there is no OTA command (#2697)
Leave that to the main app instead, so we don't reset peripherals twice.
* ota: fix copy error for riscv headers
* ota: initialize bootrom bit ops and add explanation
2024-12-19 10:05:46 -08:00
CIncinnatus
d5a6888cac
Fix issue with undefined LED_BUILTIN on Seeed Xiao RP2350 (#2704)
* Modify the pin definitions for XIAO RP2350

* Fix issue with undefined LED_BUILTIN
2024-12-19 09:02:32 -08:00
Earle F. Philhower, III
a13d236afd
Update fs.rst 2024-12-19 07:00:59 -08:00
Earle F. Philhower, III
2f99b0ae2f Update version 2024-12-18 17:51:11 -08:00
Tristan Rowley
681a4c5482
Add Pimoroni Plasma 2350, fix Plasma 2040 I2C (#2698)
* my attempt at adding plasma_2040 support.. cant seem to get it working to test yet though?

* Tracked+replaced files, this now works it seems!

* correct serial count

* Update pins_arduino.h

* Rudimentary Pimoroni Plasma2350 support.

* include correct files + changes needed for proper support.

also!! fixes pin definitions for the i2c on Pimoroni Plasma 2350 (tested, working) and (presumably, untested) on the Plasma RP2040 too by swapping the i2c numbers.  i2c now works!!

* use correct USB PID for Plasma 2350
2024-12-18 17:49:07 -08:00
Earle F. Philhower, III
eecbcdf59a
Derive playback devices from common AudioOutputBase (#2703)
The audio output objects all have the same general necessary configuration
calls.  Abstract them out to a generic AudioOutputBase interface class that
they will inherit from.  Simplifies letting applications use different
output channels.

Should be backwards compatible with existing code.
2024-12-18 12:19:40 -08:00
Earle F. Philhower, III
f1b965f704
Allow I2S constructor to set pins, like PWMAudio (#2702)
Pins are a physical connection, makes sense to define them at construction.
2024-12-18 10:06:54 -08:00
Earle F. Philhower, III
66af359578
Remove unused variable from AudioBufferManager class (#2701) 2024-12-18 07:06:40 -08:00
Earle F. Philhower, III
d65b030644
Add PDF output to readthedocs.yaml (#2700) 2024-12-18 06:48:47 -08:00
Earle F. Philhower, III
33b126836f
Support setting channel for SoftAP (#2695)
Fixes #2694
2024-12-17 08:34:14 -08:00
Earle F. Philhower, III
def00bac66
Fix ordering of boards in menus (#2696)
Been a little cruft in the order of boards, rearrange alphabetically.
2024-12-16 19:45:30 -08:00
mr.chaiwat chainvong
06e3ef9556
Add MyMakers RP2040 board (#2692) 2024-12-16 19:28:03 -08:00
Heng Teng Yi
dc0dc50e36
Modify EVN Alpha board (#2690)
Co-authored-by: HTY2003 <randumbperson@gmail.com>
2024-12-15 16:39:31 -08:00
Earle F. Philhower, III
21a767e7e4
Semihosting part of core, RISC-V support (#2685)
Semihosting is handy for debugging, so allow the core to use `SerialSemi` as the
::printf port.  Add menu item to the IDE to allow selection.

Add RISC-V implementation of semihost call
2024-12-14 09:42:45 -08:00
Earle F. Philhower, III
a02e188fc7
PWMAudio setFrequency optimization (#2683)
If we set the frequency to the same one running, no need to do anything.
2024-12-13 08:04:50 -08:00
Earle F. Philhower, III
e56a295e34
Add MDNS.addServiceTxt() to SimpleMDNS (#2679)
* Add MDNS.addServiceTxt() to SimpleMDNS

Fixes #2678

A simple mapping allows for basic service text addition even when using
SimpleMDNS and ArduinoOTA.

* Protection against duplicate services addition
2024-12-12 11:55:14 -08:00
Earle F. Philhower, III
5b4dff9a77
Add optional callback parameters for I2S/PWMAudio (#2677)
Like GPIO interrupts, allow the user to pass in a callback data pointer.
2024-12-11 14:53:54 -08:00
Kirk D. Benell
abc07ef4e5
Add build.mcu to board definitions (#2673)
* added logic so that the build.mcu value is written to a board defintion in boards.txt. This is needed for Arduino libs that use precompiled/archive libs

* move the setting for the build.mcu as recommended - to manage the different archs available on the rp2340
2024-12-06 10:38:08 -08:00
Earle F. Philhower, III
0061d3f97f
Enable gprof onboard profiling (#2669)
Adds a menu item to enable onboard profiling.  This requires significant
RAM and really only makes sense on devices with PSRAM to store the state.

When the menu item is selected, allocates RAM and tracks function calls and
periodically samples the PC to generate a histogram of application usage.
The onboard gmon.out file can be written over Semihosting or
some other way to transfer to a PC for analysis.

Adds a profiling example with command lines.
2024-12-05 17:30:45 -08:00
Earle F. Philhower, III
48bc91af36
Update semihosting.rst typo 2024-12-04 16:33:46 -08:00
Earle F. Philhower, III
1725e2109f
Add semihosting support (SerialSemi and SemiFS) (#2670)
Enable ARM-only semihosting mode.  This mode allows applications on the
Pico to write to the OpenOCD console and read and write files on the
host system (i.e. debugging dump information, etc.)

It is not very fast because of the way it uses breakpoints on the Pico
to communicate, but it is useful in cases when you want to get a single
file off of the Pico while debugging.

Note that this **requires** a connected OpenOCD and GDB or else the
semihosting will cause a system panic.
2024-12-04 16:07:46 -08:00
Earle F. Philhower, III
f2d30abb1c
Add -O0 optimization mode to menus (#2667)
GCC will still do several optimizations in -Og mode which can make it hard
to see local temporary variables.
2024-12-03 16:11:56 -08:00
Earle F. Philhower, III
f2fc68f55e
GDB + mklittlefs can expand on-device filesystems (#2666) 2024-12-03 16:01:18 -08:00
Earle F. Philhower, III
34e02aaeb5 Update version 2024-12-02 11:39:24 -08:00
Earle F. Philhower, III
6024e9a7e8
Increase LWIP timeouts to avoid MDNS panics (#2653)
Bump up the LWIP_ARP setting to increase the LWIP timeout pool to
avoid a panic when using SimpleMDNS and TCP clients.

Fixes #2650
2024-11-30 10:43:19 -08:00
Earle F. Philhower, III
633faa18ac
Update to Adafruit TinyUSB 3.4.1 (#2647) 2024-11-27 13:04:36 -08:00
Earle F. Philhower, III
90d4841be7
Fix LED pin for Pico 2W (#2646)
Fixes #2644
2024-11-27 12:40:09 -08:00
Linar Yusupov
e16c459598
Fix for cyw43_wrappers.h build with C code (#2639) 2024-11-26 00:48:34 -08:00
Earle F. Philhower, III
33b0fd57a0
Fix pinMode for RP2040 PicoW (#2638)
Enable WL_DYNAMIC on the RP2040 lib builds.

Fixes #2637
2024-11-26 00:31:41 -08:00
Earle F. Philhower, III
7add6250e0 Update version 2024-11-25 10:44:58 -08:00
Earle F. Philhower, III
4068601b01
Update to SDK 2.1.0, add Pico 2W (#2629)
Update to Pico SDK 2.1.0, remove XIP and PSRAM workarounds.

Add Pico2W board.
2024-11-25 10:43:55 -08:00
Earle F. Philhower, III
9cea4708c8
Update README.md 2024-11-21 15:31:40 -08:00
1a41be1eb0
Add Adafruit Floppsy board (#2628)
Co-authored-by: ladyada <limor@ladyada.net>
2024-11-21 15:30:59 -08:00
Earle F. Philhower, III
996c3bfab9
Clean up unused parameter warnings (#2624) 2024-11-19 13:55:00 -08:00
Earle F. Philhower, III
322a1af6da
Avoid memory (de)allocation in GPIO ISR handler (#2623)
Replace std::map, which can `new` and `delete` elements of the tree,
with a statically allocated array and housekeeping.

Fixes #2622
2024-11-19 12:26:47 -08:00
Earle F. Philhower, III
e25d382732
Support WiFi/BT/BLT with RP2350 CYW43 boards (#2616)
Using pico-sdk develop branch, add in support for CYW43-based
WiFi/BT/BLE boards on the RP2350 such as the
SparkFun Thing Plus RP2350 or the Pimoroni Pico Plus 2W.

Fixes #2608

Rolls in dynamic SPI divider #2600

* Support LED digitalWrite on RP2350+CYW

Also move "special GPIO" to 64 since the Pimoroni Pico 2W uses the
RP2350B with 48 GPIOs.

* Enable CYW43_PIN_WL_DYNAMIC in IDE and P.IO

Allows calling `cyw43_set_pins_wl(cyw43_pin_array);` to redefine the
CYW43 hookup in the variant initialization.
2024-11-19 10:28:12 -08:00
Earle F. Philhower, III
bda12cd7e7
WiFiUDP only emit a packet on flush if not ended (#2618)
A flush() on a packet that's already been sent should be a no-op, not
send a 0-byte UDP packet.  Track when an outgoing packet is dirty and
only endPacket()/transmit it when so.

Fixes #2617
2024-11-17 08:58:44 -08:00
Earle F. Philhower, III
ca30518510 Update version 2024-11-15 10:03:00 -08:00
Dryw Wade
17aab7e373
Add SparkFun Thing Plus RP2350 (#2605)
* Add SparkFun Thing Plus RP2350
* Add Thing Plus RP2350 PSRAM definition
* Remove radio from Thing Plus RP2350
Will need to add back once full radio support is added, see #2605
2024-11-14 12:22:31 -08:00
Earle F. Philhower, III
083d86d251
rp2040.enableDoubleResetBootloader only on RP2040 (#2607)
The RP2350 boot ROM seems to randomize memory on a HW reset, including
both CPU stacks where we normally stuff the "reset to bootloader" flag.
Update the docs and source to remove rp2040.enableDoubleResetBootloader()
on RP2350-based boards.

Fixes #2606
2024-11-14 10:46:53 -08:00
Kjell Braden
7a0adfebd1
lwIP_Ethernet: rename copied cyw43 mac function (#2604)
Prevent symbol conflicts when including both Wifi.h and cyw43.h

Fixes #2602
2024-11-13 03:35:26 -08:00
Maximilian Gerhardt
db4b167aaa
Build libpico in CI (#2596)
* Build libpico in CI

* Use our arm-none-eabi-gcc, apply Pico-SDK patch

* Indentation fix, add comment
2024-11-11 12:53:49 -08:00
GUVWAF
5a428647d4
SimpleMDNS: let begin return a bool (#2599)
SimpleMDNS: let `begin` return a bool
To be compatible with LEAmDNS
2024-11-11 12:04:08 -08:00
CIncinnatus
6c8d62fdb8
Correct pin definitions for XIAO RP2350 (#2591) 2024-11-10 14:21:51 -08:00
JimMacA
64156c42b1
Delay LRCK to falling edge of BCK in I2S input (#2592)
In input mode, LRCK needs to change on falling edge of BCK

Fixes #2584.
2024-11-09 12:44:15 -08:00
Earle F. Philhower, III
f5c4136b94
Add SimpleMDNS, IGMP, and .local lookup (#2582)
* Enable LWIP IGMP, MDNS internal server
* Enable MDNS lookup from LWIP DNS
* Add SimpleMDNS responder, small code and no malloc
* Ensure we copy out lwipopts in make-libpico

Adds a small wrapper around the LWIP-provided MDNS responder application.
Drop-in replacement in many basic cases for LEAmDNS.

For FreeRTOS it is important to not allocate memory on an LWIP callback.
LEAmDNS needs to do this to create response objects, leading to crashes.

Increase LWIP timers by bumping the LWIP_ARP number (as done before).

Replace ArduinoOTA LEAmDNS with SimpleMDNS and update a
HTTPUpdateServer example.
2024-11-07 10:09:44 -08:00
Earle F. Philhower, III
c4b6521849
Add wiznet_5100s_evb_pico2, wiznet_5500_evb_pico2 (#2575)
Add 2 new WIZNet Pico2 boards, same pinouts as Pico revs.

Fixes #2574
2024-11-03 09:47:31 -08:00
Maximilian Gerhardt
593b3bece4
Add WIZnet W55RP20-EVB-Pico into README (#2566) 2024-10-29 13:49:10 -07:00
Earle F. Philhower, III
5ef8a5a5cc Update version 2024-10-29 07:08:45 -07:00
wiznet-mason
b0e7ad3de2
Add WIZnet W55RP20-EVB-Pico board (#2555) 2024-10-28 18:10:33 -07:00
Earle F. Philhower, III
0d26c5eded
Update PSRAM cache flush algorithm (#2563)
New info from RPI engineers give a slightly better/safer method.
2024-10-28 16:27:23 -07:00
Earle F. Philhower, III
5b135fabc4
Fix 2.0 SDK BLE devices (#2560)
Remove old pre-release BTStack files from sdkoverrides (were needed for
compound BLE devices, but the latest BTStack now incorporates these
changes).

Fixes #2547
2024-10-27 12:52:43 -07:00
Ikechukwu Ofili
3aa8df5ab7
GPIO interrupt dispatcher, minimize blocking (#2558)
Only need to lock around the std::map check, not the whole IRQ callback

This is important if you have a time sensitive interrupt on one of the cores
2024-10-26 13:37:24 -07:00
ldursw
9c217b13df
FreeRTOS: Add ISR check to critical section (#2559) 2024-10-26 13:08:21 -07:00
Earle F. Philhower, III
d96c0e6818
Update FreeRTOS examples for PicoW (#2557)
The PicoW can't access the LED from core 1, because it is driven by the
CYW43 chip, so make sure any blinking is on core 0.

Fixes #2553
2024-10-23 18:02:29 -07:00
Earle F. Philhower, III
599c226b8c
Workaround PSRAM cache invalid'n by reading flash (#2551)
* Workaround PSRAM cache invalid'n by reading flash

Fixes #2537

While waiting for a working direct cache flush routine, try and force the
cache to evict all PSRAM values by reading a bunch of flash addresses (which
share the XIP cache).  This hurts performance when PSRAM is not used, but
is required for correctness until we have a working XIP flush.

* Invalidate after cleaning the cache line

gmx from the RPI forums came up with this hack and it seems to work!
https://forums.raspberrypi.com/viewtopic.php?p=2262371#p2262371
2024-10-23 16:12:37 -07:00
Earle F. Philhower, III
e7419fbdf9
Add ARM assembly optimized memcpy for RP2350 (#2552)
33% faster for 4K memcpy using DMAMemcyp example

With this assembly:
CPU: 4835 clock cycles for 4K
DMA: 2169 clock cycles for 4K

Using stock Newlib memcpy:
CPU: 7314 clock cycles for 4K
DMA: 2175 clock cycles for 4K
2024-10-23 15:11:19 -07:00
Yveaux
060b15fa27
Remove DEBUGV for lfs_file_close (#2554) 2024-10-22 11:12:12 -07:00
Earle F. Philhower, III
4e9a6de09e
Latest ESPHost, much better performance using DMA (#2545) 2024-10-14 19:34:17 -07:00
Earle F. Philhower, III
4aee8beeea
Update Adafruit TinyUSB to 3.3.4 (#2543) 2024-10-14 17:54:16 -07:00
Earle F. Philhower, III
fdd7557156
Preserve PSRAM QMI interface around flash ops (#2539)
The flash ROM routines seem to overwrite the QMI configuration we set for
PSRAM, rendering it unreadable after any erase or write or ID command.

Wrap the 4 flash control functions to preserve the QMI state on the
RP2350.  On the RP2040, simply pass through the call.

Fixes #2537
2024-10-12 12:32:56 -07:00
CIncinnatus
49f83c4310
Add seeed xiao rp2350 board (#2533) 2024-10-11 02:00:15 -07:00
Earle F. Philhower, III
edba2faa34
Increase default PWMAudio buffer sizes (#2530)
Help ensure click-free playback by default. App overide will still be
obeyed.
2024-10-08 17:48:18 -07:00
Sylwester
c97c61dce5
Add PSRAM Size selection and Frequency Selection for Datanoise PicoADK V2. (#2529) 2024-10-08 11:50:12 -07:00
Maximilian Gerhardt
a314a8c3d7
Document setting the PSRAM size for PlatformIO (#2527) 2024-10-06 09:45:48 -07:00
Maximilian Gerhardt
58c0d95114
Fix getStackPointer() to work in RISC-V and ARM mode (#2526) 2024-10-06 09:44:30 -07:00
Earle F. Philhower, III
2324d52023
Typo fix platform.txt 2024-10-04 17:55:39 -07:00
Earle F. Philhower, III
b9dadbbdc2
Typo fix rp2040.rst 2024-10-04 17:41:53 -07:00
Earle F. Philhower, III
6eead5b0df
Typo fix psram.rst 2024-10-04 17:40:57 -07:00
Earle F. Philhower, III
5f77e12984
Add PSRAM size menu to Adafruit Feather RP2350 HSTX (#2521)
See #2512
2024-10-04 17:39:19 -07:00
Thomas Pfister
2f55223b70
Add getResetReason() by palmerr23 (#2516)
* Add support for RP2350
2024-10-04 17:37:36 -07:00
Earle F. Philhower, III
67bf5a734a
Remove 2 instructions from tone PIO program (#2515)
Manually load the 2 needed registers using pio_execute to save a couple
PIO instruction slots.
2024-10-03 13:27:14 -07:00
Earle F. Philhower, III
ec6bb7e924
Update README.md 2024-10-03 12:39:18 -07:00
Kevin Santo Cappuccio
059bd590d7
Add Jumperless and Jumperless V5 to supported boards (#2514) 2024-10-03 10:02:42 -07:00
Earle F. Philhower, III
9d17f42a35 Update version 2024-10-02 10:26:19 -07:00
Earle F. Philhower, III
1f1fa11216
Allow IDE install to call RISC-V compiler (#2513)
Released packages have a post-processing step to allow them to work with IDE
installed toolchains.  This was not updated for the RISC-V compiler, so R5 compiles
fail under the release IDE package.  Update to call proper compiler path.

Fixes #2510
2024-10-02 10:25:32 -07:00
Earle F. Philhower, III
690293e7e1
RP2350B additional ADC inputs for ADCInput (#2509)
Fix pin offset and maximum count of ADC inputs for the RP2350B variant.
2024-10-01 18:22:11 -07:00
Earle F. Philhower, III
500fcf2513 Update version 2024-10-01 09:25:29 -07:00
Maximilian Gerhardt
a2164a5b10
Update PIO USB docs, fixup used VID/PID macros (#2505) 2024-09-30 09:57:21 -07:00
Maximilian Gerhardt
25501953df
Update PIO platform before compile, add RISC-V PIO build to CI (#2504) 2024-09-30 09:41:16 -07:00
Earle F. Philhower, III
f6973fc64d
Add RISC-V support, GCC 14 move (#2491)
* Adds RISC-V compilation option to the IDE and Platform.IO.
* Build RP2350-RISCV libpico, libbearssl
* Fix RP2350 BearSSL library (was copied from RP2040, now built for M33)
* New GCC 14.2 toolchain is required (12.4 RISC-V support is borked)
* Newlib locking fixed prototypes
* Manually force all runtime init code into RP2350 binaries
* Add RISC-V to CI
* Remove RP2350 BOOT2.S files, binaries (not used)
* Clean up minor GCC 14.x warnings
* Add RP2350-RISCV OTA build, link
* Add RISC-V FreeRTOS files (configuration still not running, but builds)
* Add basic documentation
2024-09-29 15:10:36 -07:00
Earle F. Philhower, III
f49d058477 Update version 2024-09-24 06:59:23 -07:00
Earle F. Philhower, III
777eacdfc3
Wire probe clock stretch up to 500us (#2493)
As reported by @Rasmusfk in #2455, allow for a longer
clock stretch period during probes.
2024-09-24 06:58:41 -07:00
Sylwester
39ad2aeced
Add Datanoise PicoADK v2 (RP2350). (#2413) 2024-09-24 06:46:05 -07:00
Earle F. Philhower, III
a9fd579ce9
Add new Pico SDK AON_Timer module (#2489)
Fixes #2488
2024-09-22 15:16:28 -07:00
Earle F. Philhower, III
a6ab6e1f95
Fix FreeRTOS Flash Freeze, Fastly (#2486)
Fixes #2485
2024-09-20 15:04:56 -07:00
Earle F. Philhower, III
b2ec6ecb09
GCC to 12.4, Newlib to 4.3.0, faster RP2350 libs (#2480)
Newlib built using `-Os` causes things like `memcpy` to be very slow on the
RP2350 because it uses byte-wise operations.  On the RP2040 this doesn't
matter because there is a ROM routine we use instead of the library, but on
the Pico 2 it's almost 10x slower than the optimal method.

Update GCC to 12.4
Update Newlib to 4.4.0
Move to -O2 library compilation

New toolchain looks to add ~10K to RP2350 flash usage (less on the RP2040).
2024-09-19 17:03:23 -07:00
Earle F. Philhower, III
f18fa88565
Update DMAMemcpy.ino (#2481)
Use 64-bit cycle counts to avoid occasional overflows.
2024-09-19 09:25:29 -07:00
Tom Magnier
07b7d9748b
I2C lib : implement "bus recovery" feature on timeout reset (#2479)
* I2C lib : implement "bus recovery" feature on timeout reset
---------
Co-authored-by: Tom Magnier <tom@tmagnier.fr>
2024-09-19 08:58:47 -07:00
Earle F. Philhower, III
66c1f78f7d
Minimize skipped ESPHost CI tests (#2477) 2024-09-18 08:28:05 -07:00
Pontus Oldberg
f6940cc04e
Adds support for ESP Hosted to WiFi/BLE boards and adds a menu item for ESP WiFi selection (#2468)
* Adds a menu item for selecting type of ESP wifi type.

* Updated pin definitions to work with ESP hosted.

* Fixed residual debug modification.

* Added ESPHost support library.

* Removed local cloning of ESPHost and added to excluded from CI

* Updated boards.txt

---------

Co-authored-by: Pontus Oldberg <pontus.oldberg@non.se.com>
2024-09-18 07:16:23 -07:00
Earle F. Philhower, III
5830cd8e7d
Clean up libpico Cmakefile, 1 entry per line (#2474)
Split the 1300+ char define-setting line into a multi-line value.
Makes it more maintainable and easier to see when changes needed.
No settings should have been modified.
2024-09-17 18:26:16 -07:00
Earle F. Philhower, III
2063a2d23d
Enable OTA support for RP2350 (#2472)
The RP2350 has a different blob header requirement to identify a working
image.  Ensure that header is present in the OTA loader.

Update the PicoOTA examples for the 2350
2024-09-17 15:05:42 -07:00
Earle F. Philhower, III
4504d72972
Don't realloc(nullptr) from PSRAM by default (#2473)
Several Arduino APIs realloc(NULL) which is legal and equivalent to
"malloc()", but the PSRAM logic was placing those malloc calls in PSRAM
and not RAM because "0" < RAM_START.

Ensure the realloc address is non-null and before RAM_START before
using PSRAM.
2024-09-17 14:46:41 -07:00
Yveaux
5db8063756
Also remove CFG_TUSB_DEBUG from platformio-build.py for rp2350 (#2471) 2024-09-17 11:52:30 -07:00
Yveaux
5fbda35282
Remove CFG_TUSB_DEBUG for rp2350 (#2469) 2024-09-17 11:21:16 -07:00
Liz
163b209d6c
Add Adafruit Feather RP2350 with HSTX (#2459)
* Add xosc delay for RP2350

* init feather rp2350 addition

* Update Feather RP2350 JSON

---------

Co-authored-by: Scott Shawcroft <scott@tannewt.org>
Co-authored-by: ladyada <support@adafruit.com>
2024-09-17 09:45:45 -07:00
Earle F. Philhower, III
ccdc76c279
Update freertos.rst - FreeRTOS RP2350 support added 2024-09-16 16:59:19 -07:00
Earle F. Philhower, III
e88d2d0469
Update rp2350.rst - FreeRTOS support added 2024-09-16 16:57:32 -07:00
Earle F. Philhower, III
a0b3876de4
Add FreeRTOS support for RP2350 (#2406)
Pull in Raspberry Pi's custom RP2350 ARM and RISC-V ports for FreeRTOS.

Basic tests run, but stress mutex test is failing in unique and interesting
ways.

* Add simplified switching test catching task swap problem

* Freertosrp2350: use FreeRTOS macros in noInterrupts/interrupts when applicable. (#2456)
* Use FreeRTOS macros in noInterrupts/interrupts when applicable.
* Fixed calling taskEXIT_CRITICAL and taskENTER_CRITICAL
---------

Co-authored-by: fietser28 <fietser28@users.noreply.github.com>
2024-09-16 16:56:22 -07:00
Earle F. Philhower, III
5f6e4aff5c
Allow LWIP Ethernet HW IRQs > 32 (#2464)
Allow RP2350B boards to use GPIOs 31+ for the Ethernet HW IRQ line.
Also update SPI debug output with the new registers.
2024-09-16 12:35:46 -07:00
Earle F. Philhower, III
4d1d1d2304
Fix PICO_RP2350B define check for other peripherals (#2463)
Fixes #2461
2024-09-16 11:16:08 -07:00
Earle F. Philhower, III
1f291482cd Fix SerialUART RP2350B define checks
Fixes #2460
2024-09-16 09:27:08 -07:00
Tom Magnier
d26a358055
I2C lib: Handle timeout in write() (#2458)
Co-authored-by: Tom Magnier <tom@tmagnier.fr>
2024-09-16 08:08:21 -07:00
Earle F. Philhower, III
aaaa99d969
Support PIO2 for SoftwareSerial/SerialPIO (#2451)
New IRQs and PIO pointers required for the 3rd PIO on the 2350.

Fixes #2447
2024-09-13 12:25:55 -07:00
SamHalvoe
12130eb767
Add "#define PICO_RP2350B 1" since this board is based on RP2350B (#2445) 2024-09-12 12:50:04 -07:00
arturo182
f5c85fa958
Solderparty_rp2350_stamp_xl: Properly mark as using RP2350B (#2446) 2024-09-12 11:52:30 -07:00
Earle F. Philhower, III
ee9649a032 Update version 2024-09-12 10:16:13 -07:00
Earle F. Philhower, III
4098ba29af
Document E9 non-workaround (#2444)
Fixes #2380
2024-09-12 09:51:24 -07:00
Earle F. Philhower, III
76811d3c66
Add RP2350B generic/Pimoroni PGA2350 support (#2433)
* Add support for the extra 16 GPIO pins in the menus and core.
* Clean up Generic RP2350 PSRAM ("none" is valid) and flash (other than 16MB) options.
* Add extra GPIO<->peripheral connections
* Add Pimoroni PGA2350 RP2350B-based board
* Pins 32-47 can be used for PIOPrograms
* Avoid hang when PSRAM fails to initialize
* Move libpico to an RP2350B board for SDK (otherwise the SDK drops all GPIOHI support)
2024-09-11 18:55:28 -07:00
Earle F. Philhower, III
20c69bdfbd
Warn when using PSRAM on non-PSRAM boards (#2441)
Avoid link errors with a warning message and always-failing calls to
pmalloc/pcalloc.  Addresses #2439
2024-09-10 09:50:51 -07:00
Earle F. Philhower, III
a9b390296f
Fix F_CPU 125MHz setting on RP2350 (#2436)
Fixes #2434
2024-09-09 11:57:47 -07:00
Earle F. Philhower, III
8f7ddb6dc3
Ensure sample aligment on PWMAudio example (#2437) 2024-09-09 11:22:00 -07:00
Dan Ellis
3e24400beb
libraries/PDM/src/rp2040/pdm.pio.h: pio_gpio_init data in pin. (#2432) 2024-09-08 19:12:33 -07:00
Earle F. Philhower, III
be2174bdb6
Fix SoftwareSerial/SerialPIO inversion and build (#2423)
SWSerial wasn't even building due to a typo in the header, and SerialPIO
needs to set the OE-invert flag after PIO initialization for transmit.

Fixes #2419
2024-09-06 19:54:31 -07:00
Earle F. Philhower, III
70b273544e
Add board Pimornoi Tiny2350 (#2426)
Similar to Pimoroni Tiny2040
2024-09-06 19:44:21 -07:00
Earle F. Philhower, III
e0ff046f37
Remove even more pico-debug stragglers (#2425) 2024-09-06 19:21:56 -07:00
Earle F. Philhower, III
5e07682d11
Remove straggler pico-debug references (#2422) 2024-09-06 12:06:43 -07:00
SamHalvoe
902f709f6f
Add board Pimoroni Pico Plus 2 (#2415) 2024-09-05 10:55:58 -07:00
qqqlab
bf33170691
Add TwoWire::writeReadAsync (#2388) 2024-09-04 08:42:14 -07:00
Earle F. Philhower, III
50cb17497b
Fix RP2040 FP calls in ROM (#2411)
A typo in the CMakefile resulted in ROM FPU calls not being added in
the Pico library.  Fix the file and rebuild libraries.

Fixes #2410
2024-09-03 19:39:41 -07:00
Yveaux
48c4c20251
Allow reconfiguring individual FreeRTOS config items - fixes #2398 (#2407) 2024-09-03 12:58:46 -07:00
Jean-Luc Béchennec
6a5f98c7ef
FS doc update (#2404)
FSInfo64 removed and FSInfo updated. File name length limitation of LittleFS changed to 255 characters
2024-09-01 10:18:23 -07:00
Yveaux
bc7adf42c2
Allow configuring maxIRQs (#2401) 2024-09-01 08:44:51 -07:00
AIWintermuteAI
94c9932417
Expand documentation to clarify pin notation and Servo usage (#2326) 2024-08-31 13:11:42 -07:00
Earle F. Philhower, III
cde5fe3de5
Mac BASH update for CI scripts (#2400) 2024-08-31 12:53:00 -07:00
Earle F. Philhower, III
226a318897
Add serial inversion for UART and SerialPIO (#2395)
Use real GPIO pad inversion to allow inverted RX, TX, and controls for
the hardware UART and software PIO-emulated serial ports.

Adds ``setInvertTX(bool)`` and ``setInvertRX(bool)`` calls to both ports,
with ``setInvertControl(bool)`` for the HW UARTS.
2024-08-31 07:46:11 -07:00
Earle F. Philhower, III
729163d0cc
Remove pico-debug because it's archived (#2392)
Pico-Debug is no longer supported and was removed from OpenOCD, so remove
the references and upload menu items for it.

Fixes https://github.com/earlephilhower/pico-quick-toolchain/issues/61
2024-08-30 14:16:50 -07:00
Maximilian Gerhardt
42a0c88174
Update PIO board definition for PSRAM (#2387) 2024-08-30 06:38:44 -07:00
Earle F. Philhower, III
7a9c4271d1
Add P.IO package.JSON to Mac/Win OpenOCD, Picotool (#2376) 2024-08-27 13:30:25 -07:00
Earle F. Philhower, III
ca623a9643
Update README.md 2024-08-27 07:09:39 -07:00
Salam
057896899c
Add motion 2350 pro (#2372)
* Added motion 2350 pro.

* generated boards.txt

* adjusted the f_cpu

* Added Cytron Motion 2350 Pro to README.md

* Update pins_arduino.h
2024-08-27 07:08:48 -07:00
Wai Weng
9f65f25992
Update README.md (#2374) 2024-08-27 06:54:04 -07:00
Wai Weng
0c78fbd6c1
Add new board: IRIV IO Controller. (#2370)
Co-authored-by: Kong Wai Weng <waiweng@cytron.io>
2024-08-26 21:30:25 -07:00
Earle F. Philhower, III
2cac51ee4b
Update PIOASM to 2.0.0 SDK version (#2369)
Not actually used in the core, but useful for folks trying to build custom
PIO apps.
2024-08-26 18:58:21 -07:00
Earle F. Philhower, III
404f188e25
Don't construct P.IO JSON from string, use JSON (#2368)
I shall not generate a JSON file using string replacement!
2024-08-26 18:03:21 -07:00
Earle F. Philhower, III
84828f0461
Fix Pio MHZ for RP2350, fix RP2350 generic menus (#2366)
* Fix Pio MHZ for RP2350, fix RP2350 generic menus

* Clean up platform.txt IPV4 default

Was never used, but should at least exist for sanity's sake

Fixes #2365
2024-08-26 13:11:28 -07:00
Earle F. Philhower, III
b2428763d6
Add SHA256 SDK libs/inclues for RP2350 (#2364) 2024-08-26 11:48:07 -07:00
Earle F. Philhower, III
99a907b0d7
Windows Picotool add support for upload (#2363) 2024-08-26 11:17:44 -07:00
Earle F. Philhower, III
9cb9226744
Fix Platform.IO ARDUINO_ARCH_xxx define (#2361)
The core will be identified (now for historical reasons) as ARDUINO_ARCH_RP2040.
2024-08-26 09:06:56 -07:00
Earle F. Philhower, III
f4bffc6ec6 More RTD edits 2024-08-26 06:34:04 -07:00
Earle F. Philhower, III
94af6f8aca Add readthedocs.yaml file
Seems RTD isn't building w/o it anymore.
2024-08-26 06:29:24 -07:00
Earle F. Philhower, III
45e5ca16da Update version 2024-08-25 22:09:00 -07:00
Earle F. Philhower, III
b8408961b3
Attempt to make IDE really downloade SDK 2.0.0 tools (#2356)
Fixes #2355
2024-08-25 22:08:33 -07:00
Earle F. Philhower, III
ba1face5f1 Update version 2024-08-25 12:17:25 -07:00
Earle F. Philhower, III
33694a1fcc
Add RP2350 support, new boards (#2337)
* Migrate RP2040-specific bits to separate dirs
* Add chip to boards.txt, isolate RP2040-specifics
* Add RP2350 boot2, bearssl, and libraries
* Platform.IO adjust to new paths
* Add RPIPICO2 JSON for P.IO
* Add RP2350 to Platform.io
* Update Picotool and OpenOCD for all hosts
* Use picotool to generate UF2s
* Build separate libpico blobs serially
Thanks for the review, @aarturo182 !
* Add RP2350 to CI
* Allow Ethernet/WiFi building for RP2350
* Update Adafruit TinyUSB to latest
* Test skip fix
* Make RP2350 Picotool work. update USB ID
* Fix EEPROM/FS flash locations
RP2350 adds a 4K header sector to the UF2, meaning we have 4K less total
flash to work with.  Adjust all constants appropriately on the RP2350.
* Adds ilabs board and PSRAM support. (#2342)
* Adds iLabs boards and basic PSRAM support.
* Make PSRAM come up as part of chip init
Uses SparkFun psram.cpp to set timings on clocks which are defined in the
variant file.  Prefix things with RP2350_PSRAM_xxx for sanity.
Users don't need to call anything, PSRAM "just appears".  Still need to
add in malloc-type allocation.
* Add board SparkFun ProMicro RP2350
Same pinout as the SparkFun ProMicro RP2040 with 8MB PSRAM and RP2350
* Add TLSF library for use w/PSRAM
Fork of upstream to include add'l C++ warning fixes.
* Add pmalloc/pcalloc to use PSRAM memory
free() and realloc() all look at the pointer passed in and jump to the
appropriate handler.  Also takes care of stopping IRQs and taking the
malloc mutex to support multicore and FreeRTOS (when that workd)
* Fix BOOTSEL for RP2350
* Add simple rp2040.idleOtherCore test
* Add Generic RP2350 and clean up PSRAM menus
Commercial boards now only have 1 size PSRAM, no need to have menu for them.
* Add Solder Party RP2350 Stamp boards (#2352)
* Add PSRAM heap info helpers, mutex lock mallinfo
* Add RP2350 docs
* FreeRTOS and OTA unsupported warnings for RP2350
2024-08-25 11:21:46 -07:00
Earle F. Philhower, III
815e17b35a
Add WiFiClient example for w6100 for CI (#2348) 2024-08-22 10:03:47 -07:00
Stefan Nürnberger
32f031112f
W6100 implementation based on W5500 driver (#2346)
Added new RawDevice (W6100) for lwIP Ethernet
---------
Co-authored-by: Stefan Nuernberger <stefan@elexir.eu>
2024-08-22 09:02:43 -07:00
Earle F. Philhower, III
f45db86cc2
Migrate to 2.0.0 SDK (#2336)
* Update to 2.0.0 SDK
* Board type needs to be set before earliest SDK setup
* Platform includes update
* Boot2 files
* Simple compilation issues
* Build and link
* PIO rebuild with version
* Newlib wrapper update
* Force inclusion of runtime_init_* fcns
The linker was dropping all references to the library's included
runtime_init_xxx functions and hence things like the IRQ vector
table and mutexes and alarms weren't properly set up leading to
instant crashes on start up..

Explicitly call out one function from the object file stored in
the .A to force the inclusion of all the functions.  May be a better
way, heppy to hear any ideas.
* Fix SPI GPIO calls
* Fix Ethernet GPIO
* Remove SDK warnings
Remove the skipped error messages once the following PR merged:
https://github.com/raspberrypi/pico-sdk/pull/1786
* BTStack moved SBC encode/decode paths
* Platform.IO fixes
* BT No longer has special absolute mouse
* Rebuild and update OTA
* Rebuild BearSSL, too
* Update liker file to latest SDK
* Clean up libpicocmake
* Clean up LWIP/BT library names
2024-08-17 10:39:13 -07:00
Earle F. Philhower, III
16d9609ac9
Add VFS to enable POSIX file I/O operations (#2333)
* Add VFS to enable POSIX file I/O operations

Enables use of FILE * operations on internal and external storage.  fopen,
fclose, fseek, fprintf, fscanf, etc. supported.

* Add FS/File::stat and support POSIX stat/fstat
2024-08-16 13:37:23 -07:00
Earle F. Philhower, III
2a73651a8c
BREAKING: Remove FS::info64, make FS::info 64-bit (#2335)
Removed FS::info64, and updates FS::info with the 64-bit version since in
2024 it's almost impossible to get a SD card smaller than 4GB.

Most code can simply replace info64 with info and continue operation, if they
were updated to be 64-bit in the first place.
2024-08-16 12:03:12 -07:00
Earle F. Philhower, III
bd64b97a20 Update version 2024-08-08 11:00:00 -07:00
Earle F. Philhower, III
525408e181
Add RP2040.memcpyDMA for DMA-managed memory copies (#2324)
RP2040::memcpyDMA implements a DMA-controlled memory copy call identical in
function to standard memcpy, but using an onboard DMA engine.  For large
memory transfers this can be significantly faster than using the CPU-based
memcpy.  Only 4-byte aligned source, destination, and counts are allowed.
If any inputs are not 4-byte aligned, then standard memcpy will occur so
it will behave correctly for any inputs.
2024-08-08 10:49:33 -07:00
Earle F. Philhower, III
e022d47e80
Minor BearSSL changes for 8266/upstream (#2323)
No functionality differences expected.
2024-08-08 08:44:17 -07:00
Earle F. Philhower, III
28b0edac21
Add checks for Adafruit TinyUSB to USB libs (#2319)
The included USB libraries are not compatible with Adafruit TinyUSB, so
add a #error message when they're built with the define set.
2024-08-04 10:10:08 -07:00
Dominic Pearman
4bd7d99c96
Documentation: moved 'ESP32 Compatibility' to subsection (#2311)
Lowered level of segment 'ESP32 Compatibility' in documentation of 'WiFiClientSecure Class' to be a subsection thereof.
2024-08-03 07:32:39 -07:00
Earle F. Philhower, III
06572e365b
Fix minor LWIP wrapper errors (#2310)
Somehow returning the results of a `void` function from another `void`
wrapper didn't trigger any warnings.  Also missed tcp_bind actual
GCC wrapping.
2024-08-02 16:24:54 -07:00
Earle F. Philhower, III
e86f8f5002
Really remove dup'd TUSB GAMEPAD16 HID descriptor (#2306) 2024-07-30 09:54:12 -07:00
Earle F. Philhower, III
4f4e638aee
Replace most remaining ESP_ debug macros (#2305)
In ported libraries there were still some remaining DEBUG_ESP_PORT
references.  Moved to their RP2040 equivalents.
2024-07-28 09:36:10 -07:00
Earle F. Philhower, III
34f386a21b
LwIpIntfDev.end() check _started to prevent crash (#2304)
From @JAndrassy https://github.com/esp8266/Arduino/pull/9173
2024-07-27 11:46:39 -07:00
Earle F. Philhower, III
dd1c9095e8
Factor out cut-n-pasted GAMEPAD16 HID structures (#2302)
Create a single spot with the gamepad16's HID report descriptor and
report structure.  Avoids cut-n-pasted code.
2024-07-26 09:11:41 -07:00
Earle F. Philhower, III
8140c354c7
Fix HTTPClient debug output (#2300)
Found via #2296, the HTTPClient was looking for old ESP8266 defines and
not the RP2040 core ones to enable it.  Now dump on `Core` level.
2024-07-25 22:21:38 -07:00
Earle F. Philhower, III
5c4eb022c1
Rename Picoprobe upload to DebugProbe new name (#2298)
Picoprobe was rechristened Debugprobe earlier this year, add a note
in the menus to be specific about it.

See https://github.com/raspberrypi/debugprobe
2024-07-25 10:10:33 -07:00
Earle F. Philhower, III
6e5b3897b7
Fix BT/BLE Joystick reports (#2293)
Underlying HID_Joystick now always using 16-bit format axes, need to update
BT and BLE descriptors sent to the BT master or it will misinterpret the
reports and the reported joystick state will be read as garbage.

Fixes bug introduced in #2276, oops!
2024-07-23 21:11:08 -07:00
Earle F. Philhower, III
f3b8c58157
Remove obsolete TRAVIS CI variables (#2292)
Use GH native ones instead.
2024-07-23 09:48:33 -07:00
Earle F. Philhower, III
6d115cdcec Update version 2024-07-22 12:51:07 -07:00
Earle F. Philhower, III
9f66e834d4
Split variant build, combine spell + style checks (#2291)
Variant builds were taking longer than the actual individual CI jobs, so
split it up.

Combine the spelling and style checks, they ran very fast and spent more
time in checking out than in running.
2024-07-22 12:46:47 -07:00
Earle F. Philhower, III
096990123d
Fix timeout in WebServer::_uploadReadByte and handleClient() (#2290)
Upstream patch https://github.com/espressif/arduino-esp32/pull/9991
2024-07-22 12:21:42 -07:00
Earle F. Philhower, III
ea2de469a2
FreeRTOS/Arduino header include fix (#2288)
Fixes #2287
2024-07-21 05:13:43 -07:00
deltaford
80196d570b
Add Pintronix PinMax board (#2286) 2024-07-20 13:08:05 -07:00
Amken USA
1f71135a2b
Add 4 Amken boards (#2283)
Added 4 new boards from Amken LLC.
* Amken Bunny
* Amken Revelop
* Amken Revelop Plus
* Amken Revelop eS

Co-authored-by: H.Keni <151807089+hrken1@users.noreply.github.com>
2024-07-19 14:17:53 -07:00
Earle F. Philhower, III
c4e713247e
Make CI use current JSON, not upstream (#2277) 2024-07-18 16:33:23 -07:00
Earle F. Philhower, III
bd902a93f5
Add true 10- and 16-bit joystick modes (#2276)
Fixes #2275

Adds `Joystick.use10bit` and `Joystick.use16bit` methods.  10-bit is
unsigned from 0...1023 while 16-bit is signed -32767..32767.
Defines a new HID descriptor to support the increased resolution.
2024-07-18 16:07:29 -07:00
Heng Teng Yi
372fef06e1
Add board EVN Alpha (#2263)
Co-authored-by: HTY2003 <randumbperson@gmail.com>
2024-07-13 11:21:04 -07:00
Earle F. Philhower, III
41ce4b2f8b
Ensure makeboards.py writes UNIX newlines (#2264)
The repo and development use only '\n' (UNIX) EOLs.  When a user runs
makeboards on a Windows system they end up changing every line in boards.txt
and the JSON files to Windows '\r\n' format.

Explicitly set the newline character when opening the output files to
avoid this.
2024-07-12 17:53:34 -07:00
Earle F. Philhower, III
e8a2654296
Add a build of all variants to CI (#2262)
* Add a build of all variants to CI using P.IO
* Split out into separate job, use BOOTSEL sketch
* Fix Breadstick variant
* Fix Bridgetech boards with illegal define names
  Dash(-) to underscore(_) in define and variant for the -7 and -43.
* Bridgetech JSON updates
* Temporarily remove Bridgetech boards from CI
  Needs an update to the P.IO external repo to work since the names
  of the boards have changed.
2024-07-12 15:50:03 -07:00
AcThPaU
a584d10321
Fix D pin mapping on Adafruit IB/Feather RP2040 (#2259)
* Fix D pins on Adafruit IB RP2040
* Fix Adafruit Feather D pins mapping as well
* Change common.h to accept D pin def per board
2024-07-12 14:41:06 -07:00
Earle F. Philhower, III
5cdd58dfb8
Add FreeRTOS functionality tests (#2257)
FreeRTOS often seems to have interesting corner cases.  Add two simple
tests that have been useful while debugging issues found from users or
from FreeRTOS updates.
2024-07-08 18:07:28 -07:00
Earle F. Philhower, III
96a2e925cf
Fix leak in HTTPSClient (#2256)
Fixes #2254

The faked certificate was allocated but not deleted in certain cases.  Make sure
to clean up in the destructor.
2024-07-08 09:21:46 -07:00
Maximilian Gerhardt
8cb8807573
Fix assembler flags (#2255)
An oversight in the order of updating the ASFLAGS with a copy of the CCFLAGS (see line 110) and then updating the CCFLAGS (without resyncing the ASFLAGS) leads to a fatal compilation error in the Adafruit PicoDVI library, in which `tmds_encode.S` fails to find the `pico/config.h` include file. This fix updates the ASFLAGS manually after changing the CCFLAGS so that they're equal again, and the library can be compiled.
2024-07-08 09:02:15 -07:00
Earle F. Philhower, III
2cde8bd789
Avoid deadlock BT/LE HID send when disconnected (#2252)
Fixes #2251

The 2-phase send could get out of whack if transmission was attempted when
no device was connected. Clear things up so if things aren't connected,
then no data gets set as pending.
2024-07-04 13:58:33 -07:00
Earle F. Philhower, III
99b32b8436
Update to latest FreeRTOS main, not SMP branch (#2250)
FreeRTOS has merged the SMP branch into its main, so move to that and
adjust the core accordingly.  V11.1.0 + several minor edits.
2024-07-03 17:31:22 -07:00
Pontus Oldberg
91240567ce
Fixed incorrect AVR compatibility macros. (#2249)
* Fixed incorrect AVR compatibility macros.

---------

Co-authored-by: Pontus Oldberg <pontus.oldberg@non.se.com>
2024-07-03 08:01:20 -07:00
chungsoftvn-tuannguyen
247e48fa85
Add board BridgeTek IDM2040-43A (#2246)
- Board information brtchip.com/product/idm2040-43a

Signed-off-by: Tuan Nguyen <tuan.nguyen@brtchip.com>
Co-authored-by: Tuan Nguyen <tuan.nguyen@brtchip.com>
2024-06-27 11:30:53 -07:00
Earle F. Philhower, III
268d0aa1c5
On Timer::once execution, delete the alarm_id (#2245)
A Timer is not active after the alarm fires once, so clear the
alarm ID so we know we're not running.
2024-06-24 16:07:19 -07:00
Earle F. Philhower, III
553f7604ea
Add ESP32-compatible Ticker library (#2244)
Uses the Pico SDK alarms and repeated-timers to provide for IRQ-level
periodic tasks to be scheduled.
2024-06-24 14:47:46 -07:00
Earle F. Philhower, III
1357e4a37b
Receive GATT characteristic updates in BTStackLib (#2241)
Fixes #2231
2024-06-24 08:48:07 -07:00
Earle F. Philhower, III
fdc361aff9
Remove old ESP8266 files from AsyncUDP (#2238) 2024-06-19 15:51:34 -07:00
Earle F. Philhower, III
7df8c35e81
Use built-in LWIP call to determine NetBIOS IP (#2235)
Instead of manually iterating over netifs to find the one a packet came
in over for NetBIOS name lookup, use a built-in LWIP macro that's
available for udp_recv callbacks.  Shrinks and simplifies NetBIOS code.
2024-06-18 13:42:23 -07:00
Earle F. Philhower, III
2297d61d92 Update version 2024-06-18 09:44:58 -07:00
Limor "Ladyada" Fried
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 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 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 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💿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 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, 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 158aabbdf2. 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 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
Mykle
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
Earle F. Philhower, III
3dee0a276b Update version 2023-05-05 09:00:07 -07:00
Maximilian Gerhardt
e95248a787
Support and Document pico-debug in PlatformIO (#1427) 2023-05-05 07:32:41 -07:00
Earle F. Philhower, III
414ff23141
Remove circular dependency on WiFi/LWIP_Ethernet (#1415)
Fixes #1408

The wl_* types are required in multiple libraries which in turn seem
to have a circular dependency that Platform.IO has issues with in certain
modes.

Avoid the issue by moving the common headers into the core directories
so they will be accessible by all libs.

Move StackThunk to core directory, too
2023-05-04 19:54:24 -07:00
Paint Your Dragon
2c0ce6f416
Add Feathers: CAN and Prop-Maker (#1421) 2023-05-02 15:41:05 -07:00
Earle F. Philhower, III
89fe754a9f
Fix USB Mouse/Joystick HID report ID (#1418)
Fixes #1410

The USB Keyboard now has 2 reports (keyboard + consumer control), so when both
Keyboard and Mouse libraries are included, the Mouse must be report 3, not 2.

Update the Mouse and Joystick report IDs appropriately.
2023-05-01 21:14:11 -07:00
Earle F. Philhower, III
01ee673dc2
Protect the HW random generation from FreeRTOS (#1395)
Fixes #1394

The Pico_Rand SDK calls gather bits from the HW ROSC at precise intervals.
If there is jitter in the sleep_until() call then the ROSC bit collection
will always think it's failed to acquire the right bit and retry infintitely.

Avoid by wrapping the HW random number calls and the sleep_until() routine.
Only when in FreeRTOS set a flag to silently make sleep_until() into a
busy wait loop while in a random number generation step.  When not in the
random code, do the normal sleep_until call.
2023-05-01 19:42:21 -07:00
Earle F. Philhower, III
5a949443a5
Fix USB crashes in FreeRTOS (#1419)
Fixes #1402

The global USB mutex is auto-shadowed with a FreeRTOS semaphore while in
FreeRTOS mode.  Unfortunately, while the core was using the proper
FreeRTOS semaphore to lock access to the USB port, the actual FreeRTOS
USB task was using the naked Pico SDK mutex, leading to cases where it
could acquire the mutex even though some other FreeRTOS task actually
owned the shadowed mutex.

Properly lock the shadowed Semaphore, not mutex_t, in the FreeRTOS
USB periodic task.
2023-05-01 19:34:46 -07:00
Maximilian Gerhardt
a916695155
Add PICO_FLASH_SIZE_BYTES to PIO (#1416) 2023-05-01 11:48:28 -07:00
Earle F. Philhower, III
611547ee97
Add PICO_FLASH_SIZE_BYTES define (#1414)
Matches the flash size defined in the menus.

Fixes #1399
2023-05-01 11:02:01 -07:00
Earle F. Philhower, III
ff9f228e1b
FreeRTOS compilation fix when no LED present (#1413)
Fixes #1412
2023-05-01 10:46:23 -07:00
Earle F. Philhower, III
f33dfd2313
Don't delete first cert, taken from ESP8266 repo (#1392)
See https://github.com/esp8266/Arduino/pull/8907
2023-04-22 15:34:59 -07:00
Earle F. Philhower, III
7ef00c8761
Update to Adafruit_TinyUSB 2.1.0 (#1387)
Fixes #1382
2023-04-21 10:20:14 -07:00
Maximilian Gerhardt
437d03583a
Sync macros used in PlatformIO and platform.txt (#1386) 2023-04-21 09:57:50 -07:00
Wvirgil123
0322a6871c
Add board Seeed Indicator RP2040 (#1375) 2023-04-21 09:48:38 -07:00
Maximilian Gerhardt
4f643d27d9
Enable BlackMagicProbe for PlatformIO (#1378) 2023-04-15 12:35:45 -07:00
Earle F. Philhower, III
3dcb4bbf8b
Clear compile errors if BT needed but not on (#1371)
Fixes #1370

Adds a simple helper assertion to tell the user how to enable BT if it's
not enabled, instead of some odd compilation warnings about undefined
functions.
2023-04-12 08:21:24 -07:00
Paint Your Dragon
59981aed7f
Rename USB HOST pins (#1367)
Change “N” to “M” and add “HOST” in the USB pins. Only two pins are actually affected; diff appears large to maintain the pleasant aligned-columns format.
2023-04-10 10:53:28 -07:00
Earle F. Philhower, III
07781e9cf5
Rename BTstack lib to BTstackLib (#1360)
Fixes #1356

Mac and Windows have case-insensitive filesystems, so the will find
the internal (all-lowercase) "btstack.h" and not the library's "BTstack.h",
causing compilation errors.

Rename the library and header to avoid the issue.
2023-04-06 17:09:07 -07:00
Earle F. Philhower, III
c276a36c9b Update version 2023-04-05 13:38:25 -07:00
Earle F. Philhower, III
ff0d794c50
Add MacOS Picotool upload help (#1355)
Fixes #1344
2023-04-04 14:24:15 -07:00
Maximilian Gerhardt
369c878711
Add BTC and BLE docs to PlatformIO (#1354) 2023-04-04 14:20:39 -07:00
Pontus Oldberg
5bf570c27d
Add support for Challenger UWB board, fix some defines (#1351) 2023-04-03 08:58:26 -07:00
Earle F. Philhower, III
0963611fc7
Add absolute mouse support (#1342)
Fixes #1338

To be revisited when TinyUSB native support is added and picked up in the SDK
2023-03-30 16:09:04 -07:00
Earle F. Philhower, III
00644db9b1
Update to fixed HID_Mouse submodule (#1340) 2023-03-30 12:24:13 -07:00
Paint Your Dragon
f8ba72aa15
Add Feather ThinkINK and USB Host (#1334) 2023-03-29 11:18:45 -07:00
Paint Your Dragon
371b2c87b1
Add Feather RP2040 RFM, fix pins in SCORPIO, DVI board defs (#1333) 2023-03-28 12:58:49 -07:00
Earle F. Philhower, III
387655606e
Update README.md 2023-03-21 07:17:40 -07:00
Earle F. Philhower, III
e1b881a688
Add Win32 Long Path info to P.IO docs (#1321) 2023-03-20 15:31:39 -07:00
Mark Hildreth
869ea4c16b
Add flatpak-specific IDE installation instructions (#1317) 2023-03-19 11:43:47 -07:00
Earle F. Philhower, III
71238ccd74
Clean up CoreMutex and __isFreeRTOS definition (#1312)
See #1311 for more info.  __isFreeRTOS is C++ linkage and only used
in the core proper (all C++).
2023-03-16 14:42:28 -07:00
Earle F. Philhower, III
1dfd9ebac7
Add HID consumer (aka media) keys for USB, BT (#1309)
Allow sending thigns like KEY_MUTE or KEY_SCAN_NEXT from the USB and
Bluetooth Classic keyboard libraries.

BLE requires some add'l magic, not yet discovered.

Pull in latest upstream Keyboard library changes
2023-03-15 19:10:31 -07:00
Earle F. Philhower, III
3dbe5cf930
Add I2S::swapClocks() for boards w/reversed pins (#1298)
Allow users of boards like the Pico-Audiom where the LRCLK comes
before the BCLK pin, to swap the BCLK/LRCLK of the I2S interface.

Fixes #1287
2023-03-15 15:23:56 -07:00
Earle F. Philhower, III
8e8fea4b7d
Add (unsupported) BTstack Arduino library (#1305)
The BTstack driver includes a basic Arduino library as part of the ports
directory.
2023-03-15 13:02:24 -07:00
Earle F. Philhower, III
ebe5bfbc07
Increase UDP PCBs to avoid DNS OOM error (#1304)
Fixes #1285 (or at least works well enough for now)
2023-03-14 07:28:24 -07:00
Limor "Ladyada" Fried
d67930eeef
Feather DVI peripheral fix (#1301)
* make the main SPI SPI (even tho its on SPI1)

* fix Wire to default pins
2023-03-13 17:07:55 -07:00
Earle F. Philhower, III
084d5b0b87
Add 4 and 8 MB VCC_GND boards via Flash Size menu (#1297)
Thanks to @e-tinkers for the initial PR!
2023-03-11 09:52:33 -08:00
Earle F. Philhower, III
8dc44b5e0d
Astyle format variants format (#1295) 2023-03-10 13:00:04 -08:00
Earle F. Philhower, III
7851dc8cb7 Update version 2023-03-10 09:08:28 -08:00
Philipp Molitor
75c553c391
Fix pin assigment for Waveshare RP2040 1.28 LCD PIN_BAT_ADC (#1292) 2023-03-10 04:31:33 -08:00
Earle F. Philhower, III
6bff270402
Manually add MDNS multicast Ethernet MACs to CYW43 (#1290)
SDK 1.5 changed the behavior of the underlying CYW43 blob, and it seems
to block MDNS multicast by default.  Manually add back the Ethernet MACs
used for MDNS multicast in IPV4 and IPV6.

Fixes #1267
2023-03-09 14:15:14 -08:00
nanoparticle
72f1e53106
Add board definition for Neko Systems BL2040 Mini (#1258) 2023-03-09 10:30:54 -08:00
Earle F. Philhower, III
e6c7b97b5e
Adjust LWIP intf to avoid hangs/crashes under load (#1286)
It seems possible now for TCP connection _pcbs to disappear while being
processed, due to the new async context configuration.  This would cause
LWIP to panic when a NULL pcb was passed in.

Check for and avoid passing in null PCBs in the ClientContext.

Undo special-casing of sys_check_timeouts wrapper

AdvancedWebServer with heavy F5-refresh and #1274 test both pass.

Fixes #1274
2023-03-08 11:48:23 -08:00
whimsee
54f9d3c414
Reassign I2C pins to correct buses (#1255) 2023-03-05 14:56:53 -08:00
Tim Boldt
9e272733cf
Add instructions for making I2S input work with Adafruit microphone (#1272)
Co-authored-by: timboldt <tim.boldt@gmail.com>
2023-03-05 14:24:31 -08:00
Earle F. Philhower, III
51afd3440f
Add Bluetooth to the PIO CI (#1269) 2023-03-05 08:48:24 -08:00
Sanjay Govind
f67bc43584
Add Bluetooth support to Platform.io (#1259) 2023-03-05 08:23:22 -08:00
Earle F. Philhower, III
79e1af7bde
Add Keyboard LED callback for USB and BT (not BLE) (#1265)
BLE seems to require some kind of characteristic callback that is not yeet
implemented here.  USB and BT tested and examples updated.
2023-03-04 14:18:40 -08:00
Earle F. Philhower, III
173c44417c
Allow setting names for BT/BLE HID devices (#1260) 2023-03-04 12:38:34 -08:00
Earle F. Philhower, III
7aa1c08d17
Use generic HID classes to minimize code duplic'n (#1254)
Move the Joystick, Keyboard, and Mouse into a base class which handles
the operation/input, and a subclass which will implement the reporting
as a HID device via USB, Bluetooth Classic, or Bluetooth Low Energy (BLE).

Reduce copies of library code and makes maintainability much better.
2023-03-03 11:12:09 -08:00
Rei Vilo
0be1d9c3ea
Fix picow default libname in platform.txt (#1250) 2023-03-03 07:40:02 -08:00
Earle F. Philhower, III
305e194993
Add setBattery to BLE HID devices (#1246) 2023-03-02 15:55:18 -08:00
Paint Your Dragon
719ab019a4
Add Adafruit Feather RP2040 DVI (#1245)
Includes option for QSPI/4 flash access on specific Adafruit boards for use when overclocking.
2023-03-02 15:54:19 -08:00
Earle F. Philhower, III
e9df18f910
Update PicoBluetoothBLEHID.cpp 2023-03-02 08:18:02 -08:00
Earle F. Philhower, III
06a1fdac50 Update version 2023-03-01 16:59:38 -08:00
Earle F. Philhower, III
7308ef4117
Update bluetooth.rst 2023-03-01 16:44:35 -08:00
Earle F. Philhower, III
67c1db9957
JoystickBLE actually implements a gamepad, update appearance 2023-03-01 16:30:51 -08:00
Earle F. Philhower, III
f5a621935d
Add BLE HID libraries and examples (#1240) 2023-03-01 16:29:25 -08:00
Earle F. Philhower, III
354edb30d3
Move pico-sdk to RPI's original version (#1239)
No need to use my own fork, we're using the default upstream code.
2023-03-01 10:24:45 -08:00
Earle F. Philhower, III
96113fe848
Fix BLE enable definition (#1238)
BLE tested working with BTStack BLE hog-keyboard-demo.
2023-03-01 10:08:03 -08:00
Earle F. Philhower, III
fd1596b6c9
Update keywords.txt 2023-02-28 12:41:22 -08:00
Earle F. Philhower, III
9760efbca3
Clean up the BT HID libraries a bit (#1236) 2023-02-28 10:10:39 -08:00
Earle F. Philhower, III
d92c1025ba
Update to SDK 1.5, add alpha-level BT support, use Pico-SDK CYW43 infrastructure (#1167)
* Update to Pico-SDK v1.5
* Hook in pico_rand, use ioctl to set ipv6 allmulti
* Move into PicoSDK LWIP mutex, hack timer sizes
* Utilize much of the PicoSDK infrastructure for WiFi
* Add WiFi::begin(ssid, pass, bssid)
* WiFiMulti to use BSSID, make more robust

WiFiMulti will now be more aggressive and try all matching SSIDs, in order
of RSSI, using the BSSID to identify individual APs in a mesh.

Before, if the highest RSSI AP didn't connect, it would fail immediately.
Now, it will go down the list, ordered by RSSI, to attempt to get a link.

* Add Bluetooth support from Pico-SDK
Able to build and run the HID Keyboard Demo from the Arduino IDE, almost
as-is.

Will probably need to make BT configurable.  Enabling BT on a plain WiFi
sketch uses 50KB of flash and 16KB of RAM even if no BT is used.

* Separate picow libs, BT through menus, example

Build normal Pico.a and 4 different options for PicoW IP/BT configuration.
Use IP=>IP/Bluetooth menu to select between options.

* CMakefile rationalization

* Move BT TLV(pairing) out of last 2 flash sectors

The pairing keys for BT are stored at the end of flash by default, but
we use the last sector of flash for EPROM and the penultimate one for
the filesystem.  Overwriting those in BT could cause some real exciting
crashes down the line.

Move the store to an app-build specific address using a dummy const
array to allocate space in the application image itself.

* PicoBluetoothHID with BT Mouse, Joystick, Keyboard

Add simple Bluetooth Classic HID helper function and port the existing
USB HID devices to it.  Port their examples.

* Protect BT key storage from multicore

* Add short-n-sweet Bluetooth documents

* Add Bluetooth Serial port library

* Turn off BT when the BT libraries exit
2023-02-27 20:09:02 -08:00
Earle F. Philhower, III
de55db12f1
Update rp2040.rst 2023-02-26 18:54:32 -08:00
Earle F. Philhower, III
264b9efb36
Return custom USB product and manufacturer (#1223)
Return the pre-existing USB_PRODUCT/MANUFACTURER to the USB host in
the ID stage, allowing for reports like:

[1412958.589070] usb 1-6.3.4.1: New USB device found, idVendor=2e8a, idProduct=f00a, bcdDevice= 1.00
[1412958.589076] usb 1-6.3.4.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[1412958.589079] usb 1-6.3.4.1: Product: Pico W
[1412958.589080] usb 1-6.3.4.1: Manufacturer: Raspberry Pi
[1412958.589081] usb 1-6.3.4.1: SerialNumber: E6614C775B6C7F31

or

[1413190.272233] usb 1-6.3.4.1: New USB device found, idVendor=2e8a, idProduct=1037, bcdDevice= 1.00
[1413190.272239] usb 1-6.3.4.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[1413190.272242] usb 1-6.3.4.1: Product: HunterCat NFC RP2040
[1413190.272243] usb 1-6.3.4.1: Manufacturer: ElectronicCats
[1413190.272244] usb 1-6.3.4.1: SerialNumber: E6614C775B6C7F31
2023-02-23 17:13:12 -08:00
Earle F. Philhower, III
9fd5cdf1ba
Move PicoW auto-reassignment of LED pin to code (#1208)
Many examples require that LED_BUILTIN be defined as a constant, so we
can't use a ternary operator to swap between Pico and PicoW LED pins.

Instead, do the check in the digitalWrite/digitalRead/pinMode calls
to cover most of the uses.
2023-02-22 16:13:24 -08:00
Earle F. Philhower, III
1b33cbe591
Always apply 5M speed to CMSIS_DAP TCL script (#1218)
Still need it on the command line in platform.txt for upload/etc., but make the
debug script in lib/picoprobe_cmsis_dap.tcl include the adapter speed setting.
2023-02-21 12:30:05 -08:00
MisterSilvereagle
a97d5eab22
Fix spelling mistake (#1211)
Co-authored-by: Earle F. Philhower, III <earlephilhower@yahoo.com>
2023-02-20 09:58:50 -08:00
crp500
83e790851f
Update PlayStereo.ino (#1210)
The PWMAudio lib is expecting an int16_t value but the example passes a sample cast to uint16_t 
So any values from the lookup table that are negative are recast to 0 i think.
So half the sine wave in the case of the example is lost.
2023-02-20 09:58:14 -08:00
Earle F. Philhower, III
11ac5ed33e Update version 2023-02-18 13:04:53 -08:00
Earle F. Philhower, III
b7912f182b
Add isPicoW call to RP2040 object (#1204)
Use the RPi code to get a best-guess as to whether the board is a Pico or
PicoW.

Fixes #849
2023-02-18 13:00:02 -08:00
Earle F. Philhower, III
6db0ac8471
Add release package fixups for picoprobe-cmsis-dap (#1205) 2023-02-18 12:14:23 -08:00
Ha Thach
060aa52c89
Add picoprobe CMSIS-DAP support (#1198) 2023-02-18 12:09:02 -08:00
Carter Nelson
ba413bb7ad
Remove extra SPI byte flip (#1202)
Fixes #1201
2023-02-17 12:42:31 -08:00
Earle F. Philhower, III
97e787e48a
Reduce unintialized_ram overhead to 0 in most cases (#1200)
Use GNU LD MAX() to ensure the uninitialized RAM portions are after the
OTA region.  For most apps this already happens, so there will be no
overhead added.
2023-02-16 18:23:15 -08:00
Earle F. Philhower, III
b473139758
Enable use of uninitialized_ram() macro (#1199)
The uninitted RAM macro would fail because the OTA code would clear out the
first 50KB or so of RAM to copy its code and global values.

Move all global values to the end of RAM in OTA, and then align any uninitted
vars to a 16KB unit to ensure it won't appear in the 1st part of RAM that is
still needed to copy the OTA executable.

In the normal case, without any uninit_ram vars, no additional space is used.
When uninit_ram is used, up to 16KB of space may be lost to get that alignment,
but it will work properly.

Fixes #1188
2023-02-16 17:59:15 -08:00
Earle F. Philhower, III
7afcec8edc
Update picotool refs in JSON (#1197) 2023-02-15 18:49:40 -08:00
Earle F. Philhower, III
d1a3009447
Upgrade to toolchain 1.5.0-b (#1196)
Includes fixes for ::printf/etc. using stdout/stderr
Fixes #1181
2023-02-15 18:20:18 -08:00
Earle F. Philhower, III
651d596246
Allow FreeRTOS to ::printf (#1195)
The stdin/stdout FILEs have an internal mutex which needs to be initted
to a FreeRTOS one, or any sketch with ::printf will hang.  Automatically
create and acquire/release the shadowed mutex.

Requires new build of pico-quick-toolchain to function properly.  Tested
on preliminary local build.
2023-02-15 15:58:45 -08:00
Earle F. Philhower, III
75bab41e39
Make uf2conf.py flush STDOUT for real-time updates (#1194)
Without flushing STDOUT, the upload script's output aften are buffered
and not displayed until it completes.  Add in flush commands to allow
the IDE to display status as it changes.
2023-02-15 12:13:55 -08:00
Earle F. Philhower, III
36e0b4a908
Unbreak FreeRTOS (#1193)
USB changes caused FreeRTOS to not be able to swap tasks when the Serial port
was connected.  Clear the "stop PendSV" flag after checking for reset signal.
2023-02-15 12:10:52 -08:00
Earle F. Philhower, III
974301eaaf
Add rp2040.cpuid() call to get running core (#1190)
Per question received via email.
2023-02-14 16:22:04 -08:00
Earle F. Philhower, III
2acc161ad2
Update contrib.rst 2023-02-14 13:24:02 -08:00
Earle F. Philhower, III
7322bad830 Add docs on adding a new board to the core, too 2023-02-14 08:46:24 -08:00
Earle F. Philhower, III
6afd3260ef
Update README.md 2023-02-13 14:56:46 -08:00
Earle F. Philhower, III
76e7cca821
Add contributing docs (#1183) 2023-02-13 14:54:52 -08:00
962 changed files with 217531 additions and 9425 deletions

42
.github/workflows/build-libpico.yml vendored Normal file
View file

@ -0,0 +1,42 @@
# Run whenever it is manually triggered, a pull request or a push is done that modifes the libpico configuration
name: libpico Builder
on:
pull_request:
paths:
- tools/libpico/**
workflow_dispatch:
push:
paths:
- tools/libpico/**
jobs:
build-libpico:
name: Build libpico precompiled libraries
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: false
- name: Get submodules for pico-sdk
run: cd pico-sdk && git submodule update --init --recursive
- name: Install dependencies
run: |
sudo apt update
sudo apt install cmake make build-essential wget
# Automatically get correct toolchain
cd tools && python3 get.py && cd ..
# add to PATH
echo "$GITHUB_WORKSPACE/system/riscv32-unknown-elf/bin" >> "$GITHUB_PATH"
echo "$GITHUB_WORKSPACE/system/arm-none-eabi/bin" >> "$GITHUB_PATH"
- name: Build libpico
run: |
cd tools/libpico
./make-libpico.sh
- uses: actions/upload-artifact@v4
with:
name: libpico
path: |
tools/libpico/build-rp2040/*.a
tools/libpico/build-rp2350/*.a
tools/libpico/build-rp2350-riscv/*.a

View file

@ -6,38 +6,21 @@ name: Arduino-Pico CI
on:
pull_request:
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
TRAVIS_TAG: ${{ github.ref }}
jobs:
# Me no spell so good
code-spell:
name: Check spelling
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
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
# Consistent style
# Consistent style, spelling
astyle:
name: Style, Boards, Package
name: Spelling, Style, Boards, Package, PIO
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: false
- name: Check package references
run: |
./tests/ci/pkgrefs_test.sh
- name: Run codespell
uses: codespell-project/actions-codespell@v2
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,./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,./libraries/WiFi/examples/BearSSL_Validation/certs.h
ignore_words_list: ser,dout,shiftIn,acount,froms
- name: Check boards.txt was not edited after makeboards.py
run: |
./tools/makeboards.py
@ -50,6 +33,15 @@ jobs:
./tests/restyle.sh
# If anything changed, GIT should return an error and fail the test
git diff --exit-code
- name: Check compiled PIO files
run: |
(cd ./tools && ./get.py)
./tools/makepio.py
# If anything changed, GIT should return an error and fail the test
git diff -w --exit-code
- name: Check package references
run: |
./tests/ci/pkgrefs_test.sh
# Build all examples on linux (core and Arduino IDE)
build-linux:
@ -59,15 +51,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') }}
@ -82,20 +74,82 @@ jobs:
cd ..
bash ./tests/build.sh
# Build all rp2350 examples on linux (core and Arduino IDE)
build-rp2350-linux:
name: Build RP2350 ${{ matrix.chunk }}
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v4
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketches
env:
BUILD_PARITY: custom
mod: 6
rem: ${{ matrix.chunk }}
run: |
cd pico-sdk
git submodule update --init
cd ..
bash ./tests/build-rp2350.sh
# Build all rp2350-riscv examples on linux (core and Arduino IDE)
build-rp2350-riscv-linux:
name: Build RP2350-RISCV ${{ matrix.chunk }}
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1, 2, 3, 4, 5]
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Cache Linux toolchain
id: cache-linux
uses: actions/cache@v4
with:
path: ./tools/dist
key: ${{ runner.os }}-${{ hashFiles('package/package_pico_index.template.json', 'tests/common.sh') }}
- name: Build Sketches
env:
BUILD_PARITY: custom
mod: 6
rem: ${{ matrix.chunk }}
run: |
cd pico-sdk
git submodule update --init
cd ..
bash ./tests/build-rp2350-riscv.sh
# Build TinyUSB examples, requires custom build command line
build-tinyusb:
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 +167,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 +198,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-13, 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,17 +222,23 @@ jobs:
mod: 500
rem: 1
run: |
brew update
brew install bash
/usr/bin/env bash --version
uname -a
cd pico-sdk
git submodule update --init
cd ..
bash ./tests/build.sh
/usr/bin/env bash ./tests/build.sh
./system/picotool/picotool version
otool -L ./system/picotool/picotool
# Build a few examples with PlatformIO to test if integration works
build-platformio:
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,29 +249,33 @@ 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
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio
rm -rf ~/.platformio/platforms/raspberrypi*
pio pkg install --global --platform https://github.com/maxgerhardt/platform-raspberrypi.git
pio pkg install --global --tool symlink://.
cp -f /home/runner/work/arduino-pico/arduino-pico/tools/json/*.json /home/runner/.platformio/platforms/raspberrypi/boards/.
- name: Build Multicore Example
run: pio ci --board=rpipico --board=adafruit_feather -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Multicore/Multicore.ino
run: pio ci -v --board=rpipico --board=rpipico2 --board=adafruit_feather -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Multicore/Multicore.ino
- name: Build Multicore Example (RISC-V)
run: pio ci -v --board=rpipico2 -O "board_build.mcu = rp2350-riscv" -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Multicore/Multicore.ino
- name: Build Fade Example
run: pio ci --board=rpipico --board=adafruit_feather -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Fade/Fade.ino
- name: Build TinyUSB Example
@ -217,3 +284,58 @@ jobs:
run: pio ci --board=rpipicow -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/WiFi/examples/ScanNetworks/ScanNetworks.ino
- name: Build Signed OTA Example
run: pio ci --board=rpipicow -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/ArduinoOTA/examples/SignedOTA/SignedOTA.ino
- name: Build Bluetooth Example
run: pio ci --board=rpipicow -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" -O "build_flags=-DPIO_FRAMEWORK_ARDUINO_ENABLE_BLUETOOTH" libraries/MouseBLE/examples/BLECircle/BLECircle.ino
# Build every variant using PIO for simplicity
build-variants:
name: Build Every Variant ${{ matrix.chunk }}
runs-on: ubuntu-latest
strategy:
matrix:
chunk: [0, 1]
steps:
- uses: actions/checkout@v4
with:
submodules: 'true'
- name: Initialize needed submodules
run: |
cd pico-sdk
git submodule update --init
cd ../libraries/Adafruit_TinyUSB_Arduino
git submodule update --init
cd ../..
- name: Cache pip
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@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install PlatformIO
run: |
python -m pip install --upgrade pip
pip install --upgrade platformio
rm -rf ~/.platformio/platforms/raspberrypi*
pio pkg install --global --platform https://github.com/maxgerhardt/platform-raspberrypi.git
pio pkg install --global --tool symlink://.
cp -f /home/runner/work/arduino-pico/arduino-pico/tools/json/*.json /home/runner/.platformio/platforms/raspberrypi/boards/.
- name: Build Every Variant
run: |
cnt=0
for b in $(cut -f1 -d. /home/runner/work/arduino-pico/arduino-pico/boards.txt | sed 's/#.*//' | sed 's/^menu$//' | sort -u); do
cnt=$((cnt + 1))
rem=$((cnt % 2))
if [ $rem == ${{ matrix.chunk }} ]; then
pio ci --board=$b -O "platform_packages=framework-arduinopico@symlink:///home/runner/work/arduino-pico/arduino-pico" libraries/rp2040/examples/Bootsel/Bootsel.ino
fi
done

View file

@ -9,31 +9,30 @@ 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 }}
BUILD_TYPE: package
CI_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }}
@ -43,5 +42,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

View file

@ -15,16 +15,15 @@ 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
env:
TRAVIS_BUILD_DIR: ${{ github.workspace }}
BUILD_TYPE: package
CI_GITHUB_API_KEY: ${{ secrets.GITHUB_TOKEN }}
run: |

7
.gitignore vendored
View file

@ -3,5 +3,10 @@ system
tools/dist
docs/_build
ota/build
tools/libpico/build
ota/build-rp2350
ota/build-rp2350-riscv
tools/libpico/boot
tools/libpico/build-rp2040
tools/libpico/build-rp2350
tools/libpico/build-rp2350-riscv
platform.local.txt

32
.gitmodules vendored
View file

@ -3,25 +3,22 @@
url = https://github.com/earlephilhower/ArduinoCore-API.git
[submodule "pico-sdk"]
path = pico-sdk
url = https://github.com/earlephilhower/pico-sdk.git
url = https://github.com/raspberrypi/pico-sdk.git
[submodule "system/pyserial"]
path = tools/pyserial
url = https://github.com/pyserial/pyserial.git
[submodule "libraries/LittleFS/lib/littlefs"]
path = libraries/LittleFS/lib/littlefs
url = https://github.com/littlefs-project/littlefs.git
[submodule "libraries/SdFat"]
path = libraries/ESP8266SdFat
url = https://github.com/earlephilhower/ESP8266SdFat.git
[submodule "libraries/Keyboard"]
path = libraries/Keyboard
url = https://github.com/earlephilhower/Keyboard
path = libraries/HID_Keyboard
url = https://github.com/earlephilhower/Keyboard.git
[submodule "libraries/Mouse"]
path = libraries/Mouse
url = https://github.com/earlephilhower/Mouse
path = libraries/HID_Mouse
url = https://github.com/earlephilhower/Mouse.git
[submodule "libraries/Joystick"]
path = libraries/Joystick
url = https://github.com/benjaminaigner/Joystick
path = libraries/HID_Joystick
url = https://github.com/earlephilhower/Joystick.git
[submodule "libraries/Adafruit_TinyUSB_Arduino"]
path = libraries/Adafruit_TinyUSB_Arduino
url = https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
@ -37,3 +34,18 @@
[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
[submodule "cores/rp2040/tlsf"]
path = lib/tlsf
url = https://github.com/earlephilhower/tlsf.git
[submodule "libraries/ESPHost"]
path = libraries/ESPHost
url = https://github.com/Networking-for-Arduino/ESPHost.git
[submodule "libraries/SdFat"]
path = libraries/SdFat
url = https://github.com/greiman/SdFat.git

41
.readthedocs.yaml Normal file
View file

@ -0,0 +1,41 @@
# Read the Docs configuration file for Sphinx projects
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.12"
jobs:
post_create_environment:
- python -m pip install sphinx_rtd_theme
# You can also specify other tool versions:
# nodejs: "20"
# rust: "1.70"
# golang: "1.20"
# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/conf.py
# You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs
# builder: "dirhtml"
# Fail on all warnings to avoid broken references
# fail_on_warning: true
# Optionally build your docs in additional formats such as PDF and ePub
formats:
- pdf
# - epub
# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
# python:
# install:
# - requirements: docs/requirements.txt

@ -1 +1 @@
Subproject commit e37df85425e0ac020bfad226d927f9b00d2e0fb7
Subproject commit 82928635c893189343cf8eb78569f0c4136fded0

223
README.md
View file

@ -2,50 +2,109 @@
[![Release](https://img.shields.io/github/v/release/earlephilhower/arduino-pico?style=plastic)](https://github.com/earlephilhower/arduino-pico/releases)
[![Gitter](https://img.shields.io/gitter/room/earlephilhower/arduino-pico?style=plastic)](https://gitter.im/arduino-pico/community)
Raspberry Pi Pico Arduino core, for all RP2040 boards
Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 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 Arduino to the RP2040 (Raspberry Pi Pico processor) and RP2350 (Raspberry Pi Pico 2 processor). It uses the bare Raspberry Pi Pico SDK and a custom GCC 14.2/Newlib 4.3 toolchain and supports ARM and RISC-V cores.
# Documentation
See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for more detailed usage information.
# Contributing
Read the [Contributing Guide](https://github.com/earlephilhower/arduino-pico/blob/master/docs/contrib.rst) for more information on submitting pull requests and porting libraries or sketches to this core.
# Supported Boards
* Raspberry Pi Pico
* Raspberry Pi Pico W
* Raspberry Pi Pico 2
* Raspberry Pi Pico 2W
* 0xCB Helios
* Adafruit Feather RP2040
* Adafruit Feather RP2040 SCORPIO
* Adafruit Floppsy RP2040
* Adafruit ItsyBitsy RP2040
* Adafruit KB2040
* Adafruit Macropad RP2040
* Adafruit Metro RP2040
* Adafruit Metro RP2350
* Adafruit QTPy RP2040
* Adafruit STEMMA Friend RP2040
* Adafruit Trinkey RP2040 QT
* Amken Bunny
* Amken Revelop
* Amken Revelop Plus
* Amken Revelop eS
* Architeuthis Flux Jumperless
* Architeuthis Flux Jumperless V5
* Arduino Nano RP2040 Connect
* ArtronShop RP2 Nano
* Breadstick Raspberry
* BridgeTek IDM2040-7A
* BridgeTek IDM2040-43A
* Cytron IRIV IO Controller
* Cytron Maker Pi RP2040
* Cytron Maker Nano RP2040
* DatanoiseTV PicoADK+
* Cytron Maker Uno RP2040
* Cytron Motion 2350 Pro
* Datanoise PicoADK v1
* Datanoise PicoADK v2 (RP2350)
* Degz Suibo RP2040
* DeRuiLab FlyBoard2040 Core
* DFRobot Beetle RP2040
* ElectronicCats Hunter Cat NFC
* EVN Alpha
* 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
* Invector Labs Challenger RP2040 SubGHz
* Invector Labs Challenger RP2040 SD/RTC
* Invector Labs Challenger RP2040 UWB
* Invector Labs Challenger RP2350 BConnect
* Invector Labs Challenger RP2350 WiFi/BLE
* Invector Labs RPICO32
* Melopero Cookie RP2040
* Melopero Shake RP2040
* METE HOCA Akana R1
* Makerbase MKSTHR36
* Makerbase MKSTHR42
* MyMakers RP2040
* Neko Systems BL2040 Mini
* Newsan Archi
* nullbits Bit-C PRO
* Olimex Pico2XL
* Olimex Pico2XXL
* Olimex RP2040-Pico30
* Pimoroni PGA2040
* Pimoroni Pico Plus 2
* Pimoroni Pico Plus 2W
* Pimoroni Plasma2040
* Pimoroni Plasma2350
* Pimoroni Servo2040
* Pimoroni Tiny2040
* Pimoroni Tiny2350
* Pintronix PinMax
* RAKwireless RAK11300
* Redscorp RP2040-Eins
* Redscorp RP2040-ProMini
* Sea-Picro
* Seeed Indicator RP2040
* Seeed XIAO RP2040
* Seeed XIAO RP2350
* Silicognition RP2040-Shim
* Solder Party RP2040 Stamp
* Solder Party RP2350 Stamp
* Solder Party RP2350 Stamp XL
* SparkFun IoT RedBoard RP2350
* SparkFun MicroMod RP2040
* SparkFun ProMicro RP2040
* SparkFun ProMicro RP2350
* SparkFun Thing Plus RP2040
* SparkFun Thing Plus RP2350
* SparkFun XRP Controller
* uPesy RP2040 DevKit
* VCC-GND YD-RP2040
* Viyalab Mizu RP2040
@ -54,19 +113,79 @@ See https://arduino-pico.readthedocs.io/en/latest/ along with the examples for m
* Waveshare RP2040 Plus
* Waveshare RP2040 LCD 0.96
* Waveshare RP2040 LCD 1.28
* Waveshare RP2040 Matrix
* Waveshare RP2040 PiZero
* WIZnet W5100S-EVB-Pico
* WIZnet W5100S-EVB-Pico2
* WIZnet W5500-EVB-Pico
* WIZnet W5500-EVB-Pico2
* WIZnet W55RP20-EVB-Pico
* WIZnet WizFi360-EVB-Pico
* Generic (configurable flash, I/O pins)
* Generic RP2040 (configurable flash, I/O pins)
* Generic RP2350 (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 WizNet W6100, WizNet W5500, WizNet 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
* Transparent use of PSRAM globals and heap (RP2350 only)
* ARM or RISC-V (Hazard3) support for the RP2350
* Semihosted serial and file system access
* GPROF profiling support
The RP2040 PIO state machines (SMs) are used to generate jitter-free:
* Servos
* Tones
* I2S Input
* I2S Output
* Software UARTs (Serial ports)
* Software SPIs
# Installing via Arduino Boards Manager
**Windows Users**: Please do not use the Windows Store version of the actual Arduino application
## Windows-specific Notes
Please do not use the Windows Store version of 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. (See #20 for more details.)
## Linux-specific Notes
Installing Arduino using flatpak (often used by "App Stores" in various Linux
distributions) will mean it has restricted access to the host. This might cause uploads to fail
with error messages such as the following:
```
Scanning for RP2040 devices
...
No drive to deploy.
```
If you encounter this, you will need to either install Arduino in a different manner, or override
the flatpak sandboxing feature using the following command, then restarting Arduino.
```
flatpak override --user --filesystem=host:ro cc.arduino.IDE2
```
## Installation
Open up the Arduino IDE and go to File->Preferences.
In the dialog that pops up, enter the following URL in the "Additional Boards Manager URLs" field:
@ -84,6 +203,12 @@ Type "pico" in the search box and select "Add":
![image](https://user-images.githubusercontent.com/11875/111917223-12063680-8a3c-11eb-8884-4f32b8f0feb1.png)
# Installing via GIT
**Windows Users:** Before installing via `git` on Windows, please read and follow the directions in
[this link](https://arduino-pico.readthedocs.io/en/latest/platformio.html#important-steps-for-windows-users-before-installing).
If Win32 long paths are not enabled, and `git` not configured to use them then there
may be errors when attempting to clone the submodules.
To install via GIT (for latest and greatest versions):
````
mkdir -p ~/Arduino/hardware/pico
@ -96,11 +221,6 @@ cd ../tools
python3 ./get.py
`````
# Installing both Arduino and CMake
Tom's Hardware presented a very nice writeup on installing `arduino-pico` on both Windows and Linux, available at https://www.tomshardware.com/how-to/program-raspberry-pi-pico-with-arduino-ide
If you follow Les' step-by-step you will also have a fully functional `CMake`-based environment to build Pico apps on if you outgrow the Arduino ecosystem.
# Uploading Sketches
To upload your first sketch, you will need to hold the BOOTSEL button down while plugging in the Pico to your computer.
Then hit the upload button and the sketch should be transferred and start to run.
@ -121,82 +241,30 @@ To install, follow the directions in
* https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/README.md
For detailed usage information, please check the ESP8266 repo documentation (ignore SPIFFS related notes) available at
* https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html
* https://arduino-pico.readthedocs.io/en/latest/fs.html
# Uploading Sketches with Picoprobe
# Uploading Sketches with Picoprobe/Debugprobe
If you have built a Raspberry Pi Picoprobe, you can use OpenOCD to handle your sketch uploads and for debugging with GDB.
Under Windows a local admin user should be able to access the Picoprobe port automatically, but under Linux `udev` must be told about the device and to allow normal users access.
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 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="0004", MODE="660", GROUP-"plugdev"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", MODE="660", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-PicoProbe.rules
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000f", MODE="660", GROUP="plugdev"' | 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.
# Uploading Sketches with pico-debug
[pico-debug](https://github.com/majbthrd/pico-debug/) differs from Picoprobe in that pico-debug is a virtual debug pod that runs side-by-side on the same RP2040 that you run your code on; so, you only need one RP2040 board instead of two. pico-debug also differs from Picoprobe in that pico-debug is standards-based; it uses the CMSIS-DAP protocol, which means even software not specially written for the Raspberry Pi Pico can support it. pico-debug uses OpenOCD to handle your sketch uploads, and debugging can be accomplished with CMSIS-DAP capable debuggers including GDB.
Under Windows and macOS, any user should be able to access pico-debug automatically, but under Linux `udev` must be told about the device and to allow normal users access.
To set up user-level access to all CMSIS-DAP adapters on Ubuntu (and other OSes which use `udev`):
````
echo 'ATTRS{product}=="*CMSIS-DAP*", MODE="664", GROUP="plugdev"' | sudo tee -a /etc/udev/rules.d/98-CMSIS-DAP.rules
sudo udevadm control --reload
````
The first line creates a file that recognizes all CMSIS-DAP adapters and tells UDEV to give users full access to it. The second causes `udev` to load this new rule. Note that you will need to unplug and re-plug in your device the first time you create this file, to allow udev to make the device node properly.
Once CMSIS-DAP permissions are set up properly, then select the board "Raspberry Pi Pico (pico-debug)" in the Tools menu.
When first connecting the USB port to your PC, you must copy [pico-debug-gimmecache.uf2](https://github.com/majbthrd/pico-debug/releases/) to the Pi Pico to load pico-debug into RAM; after this, upload as normal.
# Debugging with Picoprobe/pico-debug, OpenOCD, and GDB
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation. For [pico-debug](https://github.com/majbthrd/pico-debug/), replace the raspberrypi-swd and picoprobe example OpenOCD arguments of "-f interface/raspberrypi-swd.cfg -f target/rp2040.cfg" or "-f interface/picoprobe.cfg -f target/rp2040.cfg" respectively in the Pico Getting Started manual with "-f board/pico-debug.cfg".
# Features
* Adafruit TinyUSB Arduino (USB mouse, keyboard, flash drive, generic HID, CDC Serial, MIDI, WebUSB, others)
* Generic Arduino USB Serial, Keyboard, and Mouse emulation
* 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.
# Debugging with Picoprobe, OpenOCD, and GDB
The installed tools include a version of OpenOCD (in the pqt-openocd directory) and GDB (in the pqt-gcc directory). These may be used to run GDB in an interactive window as documented in the Pico Getting Started manuals from the Raspberry Pi Foundation. Use the command line `./system/openocd/bin/openocd -f ./lib/rp2040/picoprobe_cmsis_dap.tcl` or `./system/openocd/bin/openocd -f ./lib/rp2350/picoprobe_cmsis_dap.tcl` from the `git` installation directory.
# 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.
@ -207,14 +275,17 @@ 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.
* [TLSF memory manager for PSRAM from Espressif fork](https://github.com/espressif/tlsf) of [original](https://github.com/mattconte/tlsf) by Matthew Conte is copyright Matthew Conte and licensed under the MIT license.
* [ESPHost library](https://github.com/Networking-for-Arduino/ESPHost) is LGPL licensed by its maintainers.
-Earle F. Philhower, III
earlephilhower@yahoo.com

30498
boards.txt

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,23 @@
// Padded and checksummed version of: generated\Winbond\W25Q32JVxQ\boot2.bin
.cpu cortex-m0plus
.thumb
.section .boot2, "ax"
.byte 0xf7, 0xb5, 0x73, 0x46, 0x21, 0x22, 0x02, 0x25, 0x01, 0x93, 0x29, 0x4b, 0xc0, 0x24, 0x5a, 0x60
.byte 0x9a, 0x68, 0x01, 0x26, 0xaa, 0x43, 0xda, 0x60, 0x9a, 0x60, 0x1a, 0x61, 0x5a, 0x61, 0x00, 0x23
.byte 0x64, 0x05, 0xa3, 0x60, 0x04, 0x33, 0x63, 0x61, 0x22, 0x4b, 0x28, 0x00, 0x1e, 0x60, 0xe0, 0x23
.byte 0xdb, 0x02, 0x23, 0x60, 0x35, 0x23, 0xa6, 0x60, 0x23, 0x66, 0x23, 0x66, 0x00, 0xf0, 0x4a, 0xf8
.byte 0xc0, 0xb2, 0xa8, 0x42, 0x12, 0xd0, 0x06, 0x23, 0x30, 0x00, 0x23, 0x66, 0x00, 0xf0, 0x42, 0xf8
.byte 0x31, 0x23, 0x28, 0x00, 0x23, 0x66, 0x25, 0x66, 0x00, 0xf0, 0x3c, 0xf8, 0x03, 0x35, 0x25, 0x66
.byte 0x02, 0x20, 0x25, 0x66, 0x00, 0xf0, 0x36, 0xf8, 0x30, 0x42, 0xf8, 0xd1, 0x00, 0x25, 0x12, 0x4b
.byte 0xa5, 0x60, 0x12, 0x4f, 0x23, 0x60, 0x12, 0x4b, 0x65, 0x60, 0x01, 0x26, 0x3b, 0x60, 0xeb, 0x23
.byte 0xa6, 0x60, 0x23, 0x66, 0x4b, 0x3b, 0x23, 0x66, 0x02, 0x20, 0x00, 0xf0, 0x23, 0xf8, 0x0d, 0x4b
.byte 0xa5, 0x60, 0x3b, 0x60, 0xa6, 0x60, 0x01, 0x9b, 0xab, 0x42, 0x08, 0xd1, 0x0a, 0x4b, 0x0b, 0x4a
.byte 0x13, 0x60, 0x1b, 0x68, 0x83, 0xf3, 0x08, 0x88, 0x09, 0x4b, 0x1b, 0x68, 0x18, 0x47, 0xf7, 0xbd
.byte 0x00, 0x00, 0x02, 0x40, 0xf0, 0x00, 0x00, 0x18, 0x00, 0x03, 0x5f, 0x00, 0xf4, 0x00, 0x00, 0x18
.byte 0x21, 0x22, 0x00, 0x00, 0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0
.byte 0x04, 0x01, 0x00, 0x10, 0xc0, 0x23, 0x02, 0x00, 0x04, 0x21, 0x5b, 0x05, 0x98, 0x6a, 0x08, 0x42
.byte 0xfc, 0xd0, 0x01, 0x21, 0x98, 0x6a, 0x08, 0x42, 0xfc, 0xd1, 0x18, 0x6e, 0x01, 0x2a, 0x00, 0xd0
.byte 0x18, 0x6e, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x2d, 0x68, 0xca

View file

@ -0,0 +1,4 @@
.section .boot2, "ax"
.global __boot2_entry_point
__boot2_entry_point:

4
boot2/rp2350/none.S Normal file
View file

@ -0,0 +1,4 @@
.section .boot2, "ax"
.global __boot2_entry_point
__boot2_entry_point:

View file

@ -27,10 +27,22 @@
#include "RP2040Version.h"
#include "api/ArduinoAPI.h"
#include "api/itoa.h" // ARM toolchain doesn't provide itoa etc, provide them
#include <pico.h>
#undef PICO_RP2350A // Set in the RP2350 SDK boards file, overridden in the variant pins_arduino.h
#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
// Chip sanity checking. SDK uses interesting way of separating 2350A from 2350B, see https://github.com/raspberrypi/pico-sdk/issues/2364
#if (!defined(PICO_RP2040) && !defined(PICO_RP2350)) || defined(PICO_RP2040) && defined(PICO_RP2350)
#error Invalid core definition. Either PICO_RP2040 or PICO_RP2350 must be defined.
#endif
#if defined(PICO_RP2350) && !defined(PICO_RP2350A)
#error Invalid RP2350 definition. Need to set PICO_RP2350A=0/1 for A/B variant
#endif
#if defined(PICO_RP2350B)
#error Do not define PICO_RP2350B. Use PICO_RP2350A=0 to indicate RP2350B. See the SDK for more details
#endif
// Try and make the best of the old Arduino abs() macro. When in C++, use
// the sane std::abs() call, but for C code use their macro since stdlib abs()
@ -38,7 +50,7 @@
#ifdef abs
#undef abs
#endif // abs
#ifdef __cplusplus
#if defined(__cplusplus) && !defined(__riscv)
using std::abs;
using std::round;
#else
@ -59,15 +71,24 @@ extern "C" {
void interrupts();
void noInterrupts();
// Only implemented on some RP2350 boards, not the OG Pico 2
#ifdef RP2350_PSRAM_CS
void *pmalloc(size_t size);
void *pcalloc(size_t count, size_t size);
#else
[[deprecated("This chip does not have PSRAM, pmalloc will always fail")]] void *pmalloc(size_t size);
[[deprecated("This chip does not have PSRAM, pcalloc will always fail")]] void *pcalloc(size_t count, size_t size);
#endif
// AVR compatibility macros...naughty and accesses the HW directly
#define digitalPinToPort(pin) (0)
#define digitalPinToBitMask(pin) (1UL << (pin))
#define digitalPinToTimer(pin) (0)
#define digitalPinToInterrupt(pin) (pin)
#define NOT_AN_INTERRUPT (-1)
#define portOutputRegister(port) ((volatile uint32_t*) sio_hw->gpio_out)
#define portInputRegister(port) ((volatile uint32_t*) sio_hw->gpio_in)
#define portModeRegister(port) ((volatile uint32_t*) sio_hw->gpio_oe)
#define portOutputRegister(port) ((volatile uint32_t *)&(sio_hw->gpio_out))
#define portInputRegister(port) ((volatile uint32_t *)&(sio_hw->gpio_in))
#define portModeRegister(port) ((volatile uint32_t *)&(sio_hw->gpio_oe))
#define digitalWriteFast(pin, val) (val ? sio_hw->gpio_set = (1 << pin) : sio_hw->gpio_clr = (1 << pin))
#define digitalReadFast(pin) ((1 << pin) & sio_hw->gpio_in)
#define sei() interrupts()
@ -84,13 +105,13 @@ void analogWriteFreq(uint32_t freq);
void analogWriteRange(uint32_t range);
void analogWriteResolution(int res);
// FreeRTOS potential calls
extern bool __isFreeRTOS;
#ifdef __cplusplus
} // extern "C"
#endif
// FreeRTOS potential calls
extern bool __isFreeRTOS;
// Ancient AVR defines
#define HAVE_HWSERIAL0
#define HAVE_HWSERIAL1
@ -102,7 +123,7 @@ extern bool __isFreeRTOS;
#endif
#ifndef PGM_VOID_P
#define PGM_VOID_P void *
#define PGM_VOID_P const void *
#endif
#ifdef __cplusplus
@ -118,6 +139,7 @@ extern const String emptyString;
#endif
#include "SerialUART.h"
#include "SerialSemi.h"
#include "RP2040Support.h"
#include "SerialPIO.h"
#include "Bootsel.h"
@ -125,7 +147,32 @@ extern const String emptyString;
// Template which will evaluate at *compile time* to a single 32b number
// with the specified bits set.
template <size_t N>
constexpr uint32_t __bitset(const int (&a)[N], size_t i = 0U) {
return i < N ? (1L << a[i]) | __bitset(a, i + 1) : 0;
constexpr uint64_t __bitset(const int (&a)[N], size_t i = 0U) {
return i < N ? (1LL << 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")
// PSRAM decorator
#define PSRAM __attribute__((section("\".psram\"")))
// General GPIO/ADC layout info
#if defined(PICO_RP2350) && !PICO_RP2350A
#define __GPIOCNT 48
#define __FIRSTANALOGGPIO 40
#else
#define __GPIOCNT 30
#define __FIRSTANALOGGPIO 26
#endif
#ifdef __cplusplus
using namespace arduino;
#endif

View file

@ -0,0 +1,21 @@
// Abstract class for audio output devices to allow easy swapping between output devices
#pragma once
#include <Print.h>
class AudioOutputBase : public Print {
public:
virtual ~AudioOutputBase() { }
virtual bool setBuffers(size_t buffers, size_t bufferWords, int32_t silenceSample = 0) = 0;
virtual bool setBitsPerSample(int bps) = 0;
virtual bool setFrequency(int freq) = 0;
virtual bool setStereo(bool stereo = true) = 0;
virtual bool begin() = 0;
virtual bool end() = 0;
virtual bool getUnderflow() = 0;
virtual void onTransmit(void(*)(void *), void *) = 0;
// From Print
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
virtual int availableForWrite() = 0;
};

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

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.
//
@ -26,7 +26,9 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
// Must disable interrupts, as interrupt handlers may be in flash, and we
// are about to temporarily disable flash access!
noInterrupts();
if (!__isFreeRTOS) {
noInterrupts();
}
rp2040.idleOtherCore();
// Set chip select to Hi-Z
@ -39,7 +41,12 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
// The HI GPIO registers in SIO can observe and control the 6 QSPI pins.
// Note the button pulls the pin *low* when pressed.
bool button_state = !(sio_hw->gpio_hi_in & (1u << CS_PIN_INDEX));
#if PICO_RP2040
#define CS_BIT (1u << 1)
#else
#define CS_BIT SIO_GPIO_HI_IN_QSPI_CSN_BITS
#endif
bool button_state = !(sio_hw->gpio_hi_in & CS_BIT);
// Need to restore the state of chip select, else we are going to have a
// bad time when we return to code in flash!
@ -48,7 +55,9 @@ static bool __no_inline_not_in_flash_func(get_bootsel_button)() {
IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS);
rp2040.resumeOtherCore();
interrupts();
if (!__isFreeRTOS) {
interrupts();
}
return button_state;
}

View file

@ -20,10 +20,21 @@
#pragma once
/**
@brief Wrapper class for polling the BOOTSEL button
*/
class __Bootsel {
public:
__Bootsel() { }
/**
@brief Get state of the BOOTSEL pin
@returns True if BOOTSEL pushed
*/
operator bool();
};
/**
@brief BOOTSEL accessor instance
*/
extern __Bootsel BOOTSEL;

View file

@ -28,11 +28,17 @@ 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);
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 {
@ -54,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);
}

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 {
@ -43,5 +42,6 @@ public:
private:
mutex_t *_mutex;
bool _acquired;
u_int8_t _option;
uint8_t _option;
BaseType_t _pxHigherPriorityTaskWoken;
};

View file

@ -225,6 +225,21 @@ void File::setTimeCallback(time_t (*cb)(void)) {
_timeCallback = cb;
}
bool File::stat(FSStat *st) {
if (!_p) {
return false;
}
size_t pos = position();
seek(0, SeekEnd);
st->size = position() - pos;
seek(pos, SeekSet);
st->blocksize = 0; // Not set here
st->ctime = getCreationTime();
st->atime = getLastWrite();
st->isDir = isDirectory();
return true;
}
File Dir::openFile(const char* mode) {
if (!_impl) {
return File();
@ -366,13 +381,6 @@ bool FS::info(FSInfo& info) {
return _impl->info(info);
}
bool FS::info64(FSInfo64& info) {
if (!_impl) {
return false;
}
return _impl->info64(info);
}
File FS::open(const String& path, const char* mode) {
return open(path.c_str(), mode);
}
@ -462,6 +470,17 @@ bool FS::rename(const String& pathFrom, const String& pathTo) {
return rename(pathFrom.c_str(), pathTo.c_str());
}
bool FS::stat(const char *path, FSStat *st) {
if (!_impl) {
return false;
}
return _impl->stat(path, st);
}
bool FS::stat(const String& path, FSStat *st) {
return stat(path.c_str(), st);
}
time_t FS::getCreationTime() {
if (!_impl) {
return 0;

View file

@ -48,6 +48,14 @@ enum SeekMode {
SeekEnd = 2
};
struct FSStat {
size_t size;
size_t blocksize;
time_t ctime;
time_t atime;
bool isDir;
};
class File : public Stream {
public:
File(FileImplPtr p = FileImplPtr(), FS *baseFS = nullptr) : _p(p), _fakeDir(nullptr), _baseFS(baseFS) {
@ -119,6 +127,8 @@ public:
time_t getCreationTime();
void setTimeCallback(time_t (*cb)(void));
bool stat(FSStat *st);
protected:
FileImplPtr _p;
time_t (*_timeCallback)(void) = nullptr;
@ -152,18 +162,8 @@ protected:
time_t (*_timeCallback)(void) = nullptr;
};
// Backwards compatible, <4GB filesystem usage
struct FSInfo {
size_t totalBytes;
size_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};
// Support > 4GB filesystems (SD, etc.)
struct FSInfo64 {
struct FSInfo {
uint64_t totalBytes;
uint64_t usedBytes;
size_t blockSize;
@ -172,7 +172,6 @@ struct FSInfo64 {
size_t maxPathLength;
};
class FSConfig {
public:
static constexpr uint32_t FSId = 0x00000000;
@ -201,7 +200,6 @@ public:
bool format();
bool info(FSInfo& info);
bool info64(FSInfo64& info);
File open(const char* path, const char* mode);
File open(const String& path, const char* mode);
@ -224,6 +222,9 @@ public:
bool rmdir(const char* path);
bool rmdir(const String& path);
bool stat(const char *path, FSStat *st);
bool stat(const String& path, FSStat *st);
// Low-level FS routines, not needed by most applications
bool gc();
bool check();

View file

@ -119,7 +119,6 @@ public:
virtual void end() = 0;
virtual bool format() = 0;
virtual bool info(FSInfo& info) = 0;
virtual bool info64(FSInfo64& info) = 0;
virtual FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) = 0;
virtual bool exists(const char* path) = 0;
virtual DirImplPtr openDir(const char* path) = 0;
@ -127,6 +126,7 @@ public:
virtual bool remove(const char* path) = 0;
virtual bool mkdir(const char* path) = 0;
virtual bool rmdir(const char* path) = 0;
virtual bool stat(const char *path, FSStat *st) = 0;
virtual bool gc() {
return true; // May not be implemented in all file systems.
}

View file

@ -1 +1,2 @@
#include "api/IPAddress.h"
using arduino::IPAddress;

127
cores/rp2040/PIOProgram.cpp Normal file
View file

@ -0,0 +1,127 @@
/*
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>
#include <hardware/claim.h>
#if defined(PICO_RP2350)
#define PIOS pio0, pio1, pio2
#define PIOCNT 3
#elif defined(PICO_RP2040)
#define PIOS pio0, pio1
#define PIOCNT 2
#endif
static std::map<const pio_program_t *, int> __pioMap[PIOCNT];
static bool __pioAllocated[PIOCNT];
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, int start, int cnt) {
CoreMutex m(&_pioMutex);
PIO pi[PIOCNT] = { PIOS };
uint gpioBaseNeeded = ((start + cnt) >= 32) ? 16 : 0;
DEBUGV("PIOProgram %p: Searching for base=%d, pins %d-%d\n", _pgm, gpioBaseNeeded, start, start + cnt - 1);
// If it's already loaded into PIO IRAM, try and allocate in that specific PIO
for (int o = 0; o < PIOCNT; o++) {
auto p = __pioMap[o].find(_pgm);
if ((p != __pioMap[o].end()) && (pio_get_gpio_base(pio_get_instance(o)) == gpioBaseNeeded)) {
int idx = pio_claim_unused_sm(pi[o], false);
if (idx >= 0) {
DEBUGV("PIOProgram %p: Reusing IMEM ON PIO %p(base=%d) for pins %d-%d\n", _pgm, pi[o], pio_get_gpio_base(pio_get_instance(o)), start, start + cnt - 1);
_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 < PIOCNT; o++) {
if (__pioAllocated[o] && (pio_get_gpio_base(pio_get_instance(o)) == gpioBaseNeeded)) {
DEBUGV("PIOProgram: Checking PIO %p\n", pi[o]);
if (pio_can_add_program(pi[o], _pgm)) {
int idx = pio_claim_unused_sm(pi[o], false);
if (idx >= 0) {
DEBUGV("PIOProgram %p: Adding IMEM ON PIO %p(base=%d) for pins %d-%d\n", _pgm, pi[o], pio_get_gpio_base(pio_get_instance(o)), start, start + cnt - 1);
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;
} else {
DEBUGV("PIOProgram: can't claim unused SM\n");
}
} else {
DEBUGV("PIOProgram: can't add program\n");
}
} else {
DEBUGV("PIOProgram: Skipping PIO %p, wrong allocated/needhi\n", pi[o]);
}
}
// No existing PIOs can meet, is there an unallocated one we can allocate?
PIO p;
uint idx;
uint off;
auto rc = pio_claim_free_sm_and_add_program_for_gpio_range(_pgm, &p, &idx, &off, start, cnt, true);
if (rc) {
int o = 0;
while (p != pi[o]) {
o++;
}
assert(!__pioAllocated[o]);
__pioAllocated[o] = true;
DEBUGV("PIOProgram %p: Allocating new PIO %p(base=%d) for pins %d-%d\n", _pgm, pi[o], pio_get_gpio_base(pio_get_instance(o)), start, start + cnt - 1);
__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
cores/rp2040/PIOProgram.h Normal file
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, int gpio_start = 0, int gpio_cnt = 1);
private:
const pio_program_t *_pgm;
PIO _pio;
int _sm;
};

View file

@ -19,6 +19,10 @@
*/
#include <Arduino.h>
#include <pico/runtime.h>
#ifdef PICO_RP2040
#include <hardware/structs/psm.h>
extern "C" void boot_double_tap_check();
@ -31,3 +35,19 @@ void RP2040::enableDoubleResetBootloader() {
boot_double_tap_check();
}
}
#endif
#ifdef __PROFILE
Stream *__profileFile;
int __writeProfileCB(const void *data, int len) {
return __profileFile->write((const char *)data, len);
}
#ifdef __PROFILE
extern "C" void runtime_init_setup_profiling();
#define PICO_RUNTIME_INIT_PROFILING "11011" // Towards the end, after PSRAM
PICO_RUNTIME_INIT_FUNC_RUNTIME(runtime_init_setup_profiling, PICO_RUNTIME_INIT_PROFILING);
#endif
#endif

View file

@ -18,17 +18,28 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <hardware/clocks.h>
#include <hardware/irq.h>
#include <hardware/pio.h>
#include <pico/unique_id.h>
#ifdef PICO_RP2350
#include <hardware/regs/powman.h>
#else
#include <hardware/regs/vreg_and_chip_reset.h>
#endif
#include <hardware/exception.h>
#include <hardware/watchdog.h>
#include <hardware/structs/rosc.h>
#include <hardware/structs/systick.h>
#include <pico/multicore.h>
#include <hardware/dma.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>
@ -36,6 +47,13 @@
extern "C" volatile bool __otherCoreIdled;
extern "C" {
#ifdef __PROFILE
typedef int (*profileWriteCB)(const void *data, int len);
extern void _writeProfile(profileWriteCB writeCB);
#endif
}
class _MFIFO {
public:
_MFIFO() { /* noop */ };
@ -56,8 +74,13 @@ public:
void registerCore() {
if (!__isFreeRTOS) {
multicore_fifo_clear_irq();
#ifdef PICO_RP2350
irq_set_exclusive_handler(SIO_IRQ_FIFO, _irq);
irq_set_enabled(SIO_IRQ_FIFO, true);
#else
irq_set_exclusive_handler(SIO_IRQ_PROC0 + get_core_num(), _irq);
irq_set_enabled(SIO_IRQ_PROC0 + get_core_num(), true);
#endif
}
// FreeRTOS port.c will handle the IRQ hooking
}
@ -90,15 +113,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() {
@ -108,10 +130,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.
@ -155,154 +175,288 @@ private:
class RP2040;
extern RP2040 rp2040;
extern "C" void main1();
class PIOProgram;
extern "C" char __StackLimit;
extern "C" char __bss_end__;
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;
// 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;
};
/**
@brief RP2040/RP2350 helper function for HW-specific features
*/
class RP2040 {
public:
RP2040() { /* noop */ }
~RP2040() { /* noop */ }
void begin() {
_epoch = 0;
void begin(int cpuid) {
_epoch[cpuid] = 0;
#if !defined(__riscv) && !defined(__PROFILE)
if (!__isFreeRTOS) {
// Enable SYSTICK exception
exception_set_exclusive_handler(SYSTICK_EXCEPTION, _SystickHandler);
systick_hw->csr = 0x7;
systick_hw->rvr = 0x00FFFFFF;
} else {
int off = 0;
_ccountPgm = new PIOProgram(&ccount_program);
_ccountPgm->prepare(&_pio, &_sm, &off);
ccount_program_init(_pio, _sm, off);
pio_sm_set_enabled(_pio, _sm, true);
#endif
// Only start 1 instance of the PIO SM
if (cpuid == 0) {
int off = 0;
_ccountPgm = new PIOProgram(&ccount_program);
_ccountPgm->prepare(&_pio, &_sm, &off);
ccount_program_init(_pio, _sm, off);
pio_sm_set_enabled(_pio, _sm, true);
}
#if !defined(__riscv) && !defined(__PROFILE)
}
#endif
}
// Convert from microseconds to PIO clock cycles
/**
@brief Convert from microseconds to PIO clock cycles
@returns the PIO cycles for a given microsecond delay
*/
static int usToPIOCycles(int us) {
// Parenthesis needed to guarantee order of operations to avoid 32bit overflow
return (us * (clock_get_hz(clk_sys) / 1'000'000));
}
// Get current clock frequency
/**
@brief Gets the active CPU speed (may differ from F_CPU
@returns CPU frequency in Hz
*/
static int f_cpu() {
return clock_get_hz(clk_sys);
}
// Get CPU cycle count. Needs to do magic to extens 24b HW to something longer
volatile uint64_t _epoch = 0;
/**
@brief Get the core ID that is currently executing this code
@returns 0 for Core 0, 1 for Core 1
*/
static int cpuid() {
return sio_hw->cpuid;
}
/**
@brief CPU cycle counter epoch (24-bit cycle). For internal use
*/
volatile uint64_t _epoch[2] = {};
/**
@brief Get the count of CPU clock cycles since power on.
@details
The 32-bit count will overflow every 4 billion cycles, so consider using ``getCycleCount64`` for
longer measurements
@returns CPU clock cycles since power up
*/
inline uint32_t getCycleCount() {
#if !defined(__riscv) && !defined(__PROFILE)
// Get CPU cycle count. Needs to do magic to extend 24b HW to something longer
if (!__isFreeRTOS) {
uint32_t epoch;
uint32_t ctr;
do {
epoch = (uint32_t)_epoch;
epoch = (uint32_t)_epoch[sio_hw->cpuid];
ctr = systick_hw->cvr;
} while (epoch != (uint32_t)_epoch);
} while (epoch != (uint32_t)_epoch[sio_hw->cpuid]);
return epoch + (1 << 24) - ctr; /* CTR counts down from 1<<24-1 */
} else {
#endif
return ccount_read(_pio, _sm);
#if !defined(__riscv) && !defined(__PROFILE)
}
#endif
}
/**
@brief Get the count of CPU clock cycles since power on as a 64-bit quantrity
@returns CPU clock cycles since power up
*/
inline uint64_t getCycleCount64() {
#if !defined(__riscv) && !defined(__PROFILE)
if (!__isFreeRTOS) {
uint64_t epoch;
uint64_t ctr;
do {
epoch = _epoch;
epoch = _epoch[sio_hw->cpuid];
ctr = systick_hw->cvr;
} while (epoch != _epoch);
} while (epoch != _epoch[sio_hw->cpuid]);
return epoch + (1LL << 24) - ctr;
} else {
#endif
return ccount_read(_pio, _sm);
#if !defined(__riscv) && !defined(__PROFILE)
}
#endif
}
/**
@brief Gets total unused heap (dynamic memory)
@details
Note that the allocations of the size of the total free heap may fail due to fragmentation.
For example, ``getFreeHeap`` can report 100KB available, but an allocation of 90KB may fail
because there may not be a contiguous 90KB space available
@returns Free heap in bytes
*/
inline int getFreeHeap() {
return getTotalHeap() - getUsedHeap();
}
/**
@brief Gets total used heap (dynamic memory)
@returns Used heap in bytes
*/
inline int getUsedHeap() {
struct mallinfo m = mallinfo();
return m.uordblks;
}
/**
@brief Gets total heap (dynamic memory) compiled into the program
@returns Total heap size in bytes
*/
inline int getTotalHeap() {
return &__StackLimit - &__bss_end__;
}
/**
@brief On the RP2350, returns the amount of heap (dynamic memory) available in PSRAM
@returns Total free heap in PSRAM, or 0 if no PSRAM present
*/
inline int getFreePSRAMHeap() {
return getTotalPSRAMHeap() - getUsedPSRAMHeap();
}
/**
@brief On the RP2350, returns the total amount of PSRAM heap (dynamic memory) used
@returns Bytes used in PSRAM, or 0 if no PSRAM present
*/
inline int getUsedPSRAMHeap() {
#if defined(RP2350_PSRAM_CS)
extern size_t __psram_total_used();
return __psram_total_used();
#else
return 0;
#endif
}
/**
@brief On the RP2350, gets total heap (dynamic memory) compiled into the program
@returns Total PSRAM heap size in bytes, or 0 if no PSRAM present
*/
inline int getTotalPSRAMHeap() {
#if defined(RP2350_PSRAM_CS)
extern size_t __psram_total_space();
return __psram_total_space();
#else
return 0;
#endif
}
/**
@brief Gets the current stack pointer in a ARM/RISC-V safe manner
@returns Current SP
*/
inline uint32_t getStackPointer() {
uint32_t *sp;
#if defined(__riscv)
asm volatile("mv %0, sp" : "=r"(sp));
#else
asm volatile("mov %0, sp" : "=r"(sp));
#endif
return (uint32_t)sp;
}
/**
@brief Calculates approximately how much stack space is still available for the running core. Handles multiprocessing and separate stacks.
@details
Not valid in FreeRTOS. Use the FreeRTOS internal functions to access this information.
@returns Approximation of the amount of stack available for use on the specific core
*/
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;
}
/**
@brief On the RP2350, gets the size of attached PSRAM
@returns PSRAM size in bytes, or 0 if no PSRAM present
*/
inline size_t getPSRAMSize() {
#if defined(RP2350_PSRAM_CS)
extern size_t __psram_size;
return __psram_size;
#else
return 0;
#endif
}
/**
@brief Freezes the other core in a flash-write-safe state. Not generally needed by applications
@details
When the external flash chip is erasing or writing, the Pico cannot fetch instructions from it.
In this case both the core doing the writing and the other core (if active) need to run from a
routine that's contained in RAM. This call forces the other core into a tight, RAM-based loop
safe for this operation. When flash erase/write is completed, ``resumeOtherCore`` to return
it to operation.
Be sure to disable any interrupts or task switches before calling to avoid deadlocks.
If the second core is not started, this is a no-op.
*/
void idleOtherCore() {
fifo.idleOtherCore();
}
/**
@brief Resumes normal operation of the other core
*/
void resumeOtherCore() {
fifo.resumeOtherCore();
}
/**
@brief Hard resets the 2nd core (CORE1).
@details
Because core1 will restart with the heap and global variables not in the same state as
power-on, this call may not work as desired and a full CPU reset may be necessary in
certain cases.
*/
void restartCore1() {
multicore_reset_core1();
fifo.clear();
multicore_launch_core1(main1);
}
/**
@brief Warm-reboots the chip in normal mode
*/
void reboot() {
watchdog_reboot(0, 0, 10);
while (1) {
@ -310,20 +464,110 @@ public:
}
}
/**
@brief Warm-reboots the chip in normal mode
*/
inline void restart() {
reboot();
}
static void enableDoubleResetBootloader();
/**
@brief Warm-reboots the chip into the USB bootloader mode
*/
inline void rebootToBootloader() {
reset_usb_boot(0, 0);
while (1) {
continue;
}
}
#ifdef PICO_RP2040
static void enableDoubleResetBootloader();
#endif
/**
@brief Starts the hardware watchdog timer. The CPU will reset if the watchdog is not fed every delay_ms
@param [in] delay_ms Milliseconds without a wdt_reset before rebooting
*/
void wdt_begin(uint32_t delay_ms) {
watchdog_enable(delay_ms, 1);
}
/**
@brief Feeds the watchdog timer, resetting it for another delay_ms countdown
*/
void wdt_reset() {
watchdog_update();
}
/**
@brief Best-effort reasons for chip reset
*/
enum resetReason_t {UNKNOWN_RESET, PWRON_RESET, RUN_PIN_RESET, SOFT_RESET, WDT_RESET, DEBUG_RESET, GLITCH_RESET, BROWNOUT_RESET};
/**
@brief Attempts to determine the reason for the last chip reset. May not always be able to determine accurately
@returns Reason for reset
*/
resetReason_t getResetReason(void) {
io_rw_32 *WD_reason_reg = (io_rw_32 *)(WATCHDOG_BASE + WATCHDOG_REASON_OFFSET);
if (watchdog_caused_reboot() && watchdog_enable_caused_reboot()) { // watchdog timer
return WDT_RESET;
}
if (*WD_reason_reg & WATCHDOG_REASON_TIMER_BITS) { // soft reset() or reboot()
return SOFT_RESET;
}
#ifdef PICO_RP2350
// **** RP2350 is untested ****
io_rw_32 *rrp = (io_rw_32 *)(POWMAN_BASE + POWMAN_CHIP_RESET_OFFSET);
if (*rrp & POWMAN_CHIP_RESET_HAD_POR_BITS) { // POR: power-on reset (brownout is separately detected on RP2350)
return PWRON_RESET;
}
if (*rrp & POWMAN_CHIP_RESET_HAD_RUN_LOW_BITS) { // RUN pin
return RUN_PIN_RESET;
}
if ((*rrp & POWMAN_CHIP_RESET_HAD_DP_RESET_REQ_BITS) || (*rrp & POWMAN_CHIP_RESET_HAD_RESCUE_BITS) || (*rrp & POWMAN_CHIP_RESET_HAD_HZD_SYS_RESET_REQ_BITS)) { // DEBUG port
return DEBUG_RESET;
}
if (*rrp & POWMAN_CHIP_RESET_HAD_GLITCH_DETECT_BITS) { // power supply glitch
return GLITCH_RESET;
}
if (*rrp & POWMAN_CHIP_RESET_HAD_BOR_BITS) { // power supply brownout reset
return BROWNOUT_RESET;
}
#else
io_rw_32 *rrp = (io_rw_32 *)(VREG_AND_CHIP_RESET_BASE + VREG_AND_CHIP_RESET_CHIP_RESET_OFFSET);
if (*rrp & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_POR_BITS) { // POR: power-on reset or brown-out detection
return PWRON_RESET;
}
if (*rrp & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_RUN_BITS) { // RUN pin
return RUN_PIN_RESET;
}
if (*rrp & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_PSM_RESTART_BITS) { // DEBUG port
return DEBUG_RESET; // **** untested **** debug reset may just cause a rebootToBootloader()
}
#endif
return UNKNOWN_RESET;
}
/**
@brief Get unique ID string for the running board
@returns String with the unique board ID as determined by the SDK
*/
const char *getChipID() {
static char id[2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1] = { 0 };
if (!id[0]) {
@ -332,37 +576,104 @@ public:
return id;
}
// Multicore comms FIFO
#pragma GCC push_options
#pragma GCC optimize ("Os")
/**
@brief Perform a memcpy using a DMA engine for speed
@details
Uses the DMA to copy to and from RAM. Only works on 4-byte aligned, 4-byte multiple length
sources and destination (i.e. word-aligned, word-length). Falls back to normal memcpy otherwise.
@param [out] dest Memcpy destination, 4-byte aligned
@param [in] src Memcpy source, 4-byte aligned
@param [in] n Count in bytes to transfer (should be a multiple of 4 bytes)
*/
void *memcpyDMA(void *dest, const void *src, size_t n) {
// Allocate a DMA channel on 1st call, reuse it every call after
if (memcpyDMAChannel < 1) {
memcpyDMAChannel = dma_claim_unused_channel(true);
dma_channel_config c = dma_channel_get_default_config(memcpyDMAChannel);
channel_config_set_transfer_data_size(&c, DMA_SIZE_32);
channel_config_set_read_increment(&c, true);
channel_config_set_write_increment(&c, true);
channel_config_set_irq_quiet(&c, true);
dma_channel_set_config(memcpyDMAChannel, &c, false);
}
// If there's any misalignment or too small, use regular memcpy which can handle it
if ((n < 64) || (((uint32_t)dest) | ((uint32_t)src) | n) & 3) {
return memcpy(dest, src, n);
}
int words = n / 4;
dma_channel_set_read_addr(memcpyDMAChannel, src, false);
dma_channel_set_write_addr(memcpyDMAChannel, dest, false);
dma_channel_set_trans_count(memcpyDMAChannel, words, false);
dma_channel_start(memcpyDMAChannel);
while (dma_channel_is_busy(memcpyDMAChannel)) {
/* busy wait dma */
}
return dest;
}
#pragma GCC pop_options
/**
@brief Multicore communications FIFO
*/
_MFIFO fifo;
// TODO - Not so great HW random generator. 32-bits wide. Cryptographers somewhere are crying
uint32_t hwrand32() {
// Try and whiten the HW ROSC bit
uint32_t r = 0;
for (int k = 0; k < 32; k++) {
unsigned long int b;
do {
b = rosc_hw->randombit & 1;
if (b != (rosc_hw->randombit & 1)) {
break;
}
} while (true);
r <<= 1;
r |= b;
}
// Stir using the cycle count LSBs. In any WiFi use case this will be a random # since the connection time is not cycle-accurate
uint64_t rr = (((uint64_t)~r) << 32LL) | r;
rr >>= rp2040.getCycleCount() & 32LL;
/**
@brief Return a 32-bit from the hardware random number generator
return (uint32_t)rr;
@returns Random value using appropriate hardware (RP2350 has true RNG, RP2040 has a less true RNG method)
*/
uint32_t hwrand32() {
return get_rand_32();
}
/**
@brief Determines if code is running on a Pico or a PicoW
@details
Code compiled for the RP2040 PicoW can run on the RP2040 Pico. This call lets an application
identify if the current device is really a Pico or PicoW and handle appropriately. For
the RP2350, this runtime detection is not available and the call returns whether it was
compiled for the CYW43 WiFi driver
@returns True if running on a PicoW board with CYW43 WiFi chip.
*/
bool isPicoW() {
#if !defined(PICO_CYW43_SUPPORTED)
return false;
#else
extern bool __isPicoW;
return __isPicoW;
#endif
}
#ifdef __PROFILE
void writeProfiling(Stream *f) {
extern Stream *__profileFile;
extern int __writeProfileCB(const void *data, int len);
__profileFile = f;
_writeProfile(__writeProfileCB);
}
size_t getProfileMemoryUsage() {
extern int __profileMemSize;
return (size_t) __profileMemSize;
}
#endif
private:
static void _SystickHandler() {
rp2040._epoch += 1LL << 24;
static void __no_inline_not_in_flash_func(_SystickHandler)() {
rp2040._epoch[sio_hw->cpuid] += 1LL << 24;
}
PIO _pio;
int _sm;
PIOProgram *_ccountPgm;
int memcpyDMAChannel = -1;
};

View file

@ -25,17 +25,17 @@
#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_gamepad16.h"
#include <device/usbd_pvt.h>
// Big, global USB mutex, shared with all USB devices to make sure we don't
@ -83,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),
@ -100,7 +102,7 @@ const uint8_t *tud_descriptor_device_cb(void) {
.iSerialNumber = USBD_STR_SERIAL,
.bNumConfigurations = 1
};
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallJoystick && !__USBInstallMassStorage) {
if (__USBInstallSerial && !__USBInstallKeyboard && !__USBInstallMouse && !__USBInstallAbsoluteMouse && !__USBInstallJoystick && !__USBInstallMassStorage) {
// Can use as-is, this is the default USB case
return (const uint8_t *)&usbd_desc_device;
}
@ -108,7 +110,7 @@ const uint8_t *tud_descriptor_device_cb(void) {
if (__USBInstallKeyboard) {
usbd_desc_device.idProduct |= 0x8000;
}
if (__USBInstallMouse) {
if (__USBInstallMouse || __USBInstallAbsoluteMouse) {
usbd_desc_device.idProduct |= 0x4000;
}
if (__USBInstallJoystick) {
@ -129,15 +131,15 @@ int __USBGetKeyboardReportID() {
}
int __USBGetMouseReportID() {
return __USBInstallKeyboard ? 2 : 1;
return __USBInstallKeyboard ? 3 : 1;
}
int __USBGetJoystickReportID() {
int i = 1;
if (__USBInstallKeyboard) {
i++;
i += 2;
}
if (__USBInstallMouse) {
if (__USBInstallMouse || __USBInstallAbsoluteMouse) {
i++;
}
return i;
@ -156,8 +158,9 @@ static uint8_t *GetDescHIDReport(int *len) {
void __SetupDescHIDReport() {
//allocate memory for the HID report descriptors. We don't use them, but need the size here.
uint8_t desc_hid_report_mouse[] = { TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(1)) };
uint8_t desc_hid_report_joystick[] = { TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(1)) };
uint8_t desc_hid_report_keyboard[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)) };
uint8_t desc_hid_report_absmouse[] = { TUD_HID_REPORT_DESC_ABSMOUSE(HID_REPORT_ID(1)) };
uint8_t desc_hid_report_joystick[] = { TUD_HID_REPORT_DESC_GAMEPAD16(HID_REPORT_ID(1)) };
uint8_t desc_hid_report_keyboard[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(1)), TUD_HID_REPORT_DESC_CONSUMER(HID_REPORT_ID(2)) };
int size = 0;
//accumulate the size of all used HID report descriptors
@ -166,6 +169,8 @@ void __SetupDescHIDReport() {
}
if (__USBInstallMouse) {
size += sizeof(desc_hid_report_mouse);
} else if (__USBInstallAbsoluteMouse) {
size += sizeof(desc_hid_report_absmouse);
}
if (__USBInstallJoystick) {
size += sizeof(desc_hid_report_joystick);
@ -194,11 +199,19 @@ void __SetupDescHIDReport() {
if (__USBInstallMouse) {
//determine if we need an offset (USB keyboard is installed)
if (__USBInstallKeyboard) {
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(2)) };
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(3)) };
memcpy(__hid_report + sizeof(desc_hid_report_keyboard), desc_local, sizeof(desc_local));
} else {
memcpy(__hid_report, desc_hid_report_mouse, sizeof(desc_hid_report_mouse));
}
} else if (__USBInstallAbsoluteMouse) {
//determine if we need an offset (USB keyboard is installed)
if (__USBInstallKeyboard) {
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_ABSMOUSE(HID_REPORT_ID(3)) };
memcpy(__hid_report + sizeof(desc_hid_report_keyboard), desc_local, sizeof(desc_local));
} else {
memcpy(__hid_report, desc_hid_report_absmouse, sizeof(desc_hid_report_absmouse));
}
}
//3.) joystick descriptor. 2 additional checks are necessary for mouse and/or keyboard
@ -206,14 +219,17 @@ void __SetupDescHIDReport() {
uint8_t reportid = 1;
int offset = 0;
if (__USBInstallKeyboard) {
reportid++;
reportid += 2;
offset += sizeof(desc_hid_report_keyboard);
}
if (__USBInstallMouse) {
reportid++;
offset += sizeof(desc_hid_report_mouse);
} else if (__USBInstallAbsoluteMouse) {
reportid++;
offset += sizeof(desc_hid_report_absmouse);
}
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_GAMEPAD(HID_REPORT_ID(reportid)) };
uint8_t desc_local[] = { TUD_HID_REPORT_DESC_GAMEPAD16(HID_REPORT_ID(reportid)) };
memcpy(__hid_report + offset, desc_local, sizeof(desc_local));
}
}
@ -235,7 +251,7 @@ const uint8_t *tud_descriptor_configuration_cb(uint8_t index) {
void __SetupUSBDescriptor() {
if (!usbd_desc_cfg) {
bool hasHID = __USBInstallKeyboard || __USBInstallMouse || __USBInstallJoystick;
bool hasHID = __USBInstallKeyboard || __USBInstallMouse || __USBInstallAbsoluteMouse || __USBInstallJoystick;
uint8_t interface_count = (__USBInstallSerial ? 2 : 0) + (hasHID ? 1 : 0) + (__USBInstallMassStorage ? 1 : 0);
@ -249,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;
@ -301,15 +317,15 @@ void __SetupUSBDescriptor() {
const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
(void) langid;
#define DESC_STR_MAX (20)
#define DESC_STR_MAX (32)
static uint16_t desc_str[DESC_STR_MAX];
static char idString[PICO_UNIQUE_BOARD_ID_SIZE_BYTES * 2 + 1];
static const char *const usbd_desc_str[] = {
[USBD_STR_0] = "",
[USBD_STR_MANUF] = "Raspberry Pi",
[USBD_STR_PRODUCT] = "PicoArduino",
[USBD_STR_MANUF] = USB_MANUFACTURER,
[USBD_STR_PRODUCT] = USB_PRODUCT,
[USBD_STR_SERIAL] = idString,
[USBD_STR_CDC] = "Board CDC",
#ifdef ENABLE_PICOTOOL_USB
@ -380,9 +396,22 @@ 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
extern "C" uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) __attribute__((weak));
extern "C" uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
// TODO not implemented
(void) instance;
@ -396,6 +425,7 @@ extern "C" uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, h
// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
extern "C" void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) __attribute__((weak));
extern "C" void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
// TODO set LED based on CAPLOCK, NUMLOCK etc...
(void) instance;
@ -533,6 +563,57 @@ usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
*driver_count = 1;
return &_resetd_driver;
}
#elif defined NO_USB
#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

View file

@ -19,13 +19,19 @@
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));
extern void __USBInstallKeyboard() __attribute__((weak));
extern void __USBInstallJoystick() __attribute__((weak));
// One or the other allowed, not both
extern void __USBInstallMouse() __attribute__((weak));
extern void __USBInstallAbsoluteMouse() __attribute__((weak));
extern void __USBInstallMassStorage() __attribute__((weak));
// Big, global USB mutex, shared with all USB devices to make sure we don't
@ -39,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();

View file

@ -1,5 +1,5 @@
#pragma once
#define ARDUINO_PICO_MAJOR 2
#define ARDUINO_PICO_MINOR 7
#define ARDUINO_PICO_REVISION 2
#define ARDUINO_PICO_VERSION_STR "2.7.2"
#define ARDUINO_PICO_MAJOR 4
#define ARDUINO_PICO_MINOR 5
#define ARDUINO_PICO_REVISION 4
#define ARDUINO_PICO_VERSION_STR "4.5.4"

297
cores/rp2040/SemiFS.h Normal file
View file

@ -0,0 +1,297 @@
/*
SemiFS.h - File system wrapper for Semihosting ARM
Copyright (c) 2024 Earle F. Philhower, III. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "Semihosting.h"
#include "FS.h"
#include "FSImpl.h"
using namespace fs;
namespace semifs {
class SemiFSFileImpl;
class SemiFSConfig : public FSConfig {
public:
static constexpr uint32_t FSId = 0x53454d49;
SemiFSConfig() : FSConfig(FSId, false) { }
};
class SemiFSFileImpl : public FileImpl {
public:
SemiFSFileImpl(int fd, const char *name, bool writable)
: _fd(fd), _opened(true), _writable(writable) {
_name = std::shared_ptr<char>(new char[strlen(name) + 1], std::default_delete<char[]>());
strcpy(_name.get(), name);
}
~SemiFSFileImpl() override {
flush();
close();
}
int availableForWrite() override {
return 1; // TODO - not implemented? _opened ? _fd->availableSpaceForWrite() : 0;
}
size_t write(const uint8_t *buf, size_t size) override {
if (_opened) {
uint32_t a[3];
a[0] = _fd;
a[1] = (uint32_t)buf;
a[2] = size;
return 0 == Semihost(SEMIHOST_SYS_WRITE, a) ? size : -1;
}
return -1; // some kind of error
}
int read(uint8_t* buf, size_t size) override {
if (_opened) {
uint32_t a[3];
a[0] = _fd;
a[1] = (uint32_t)buf;
a[2] = size;
int ret = Semihost(SEMIHOST_SYS_READ, a);
if (ret == 0) {
return size;
} else if (ret == (int)size) {
return -1;
} else {
return ret;
}
}
return -1;
}
void flush() override {
/* noop */
}
bool seek(uint32_t pos, SeekMode mode) override {
if (!_opened || (mode != SeekSet)) {
// No seek cur/end in semihost
return false;
}
uint32_t a[2];
a[0] = _fd;
a[1] = pos;
return !Semihost(SEMIHOST_SYS_SEEK, a);
}
size_t position() const override {
return 0; // Not available semihost
}
size_t size() const override {
if (!_opened) {
return 0;
}
uint32_t a;
a = _fd;
int ret = Semihost(SEMIHOST_SYS_FLEN, &a);
if (ret < 0) {
return 0;
}
return ret;
}
bool truncate(uint32_t size) override {
return false; // Not allowed
}
void close() override {
if (_opened) {
uint32_t a = _fd;
Semihost(SEMIHOST_SYS_CLOSE, &a);
_opened = false;
}
}
const char* name() const override {
if (!_opened) {
DEBUGV("SemiFSFileImpl::name: file not opened\n");
return nullptr;
} else {
const char *p = _name.get();
const char *slash = strrchr(p, '/');
// For names w/o any path elements, return directly
// If there are slashes, return name after the last slash
// (note that strrchr will return the address of the slash,
// so need to increment to ckip it)
return (slash && slash[1]) ? slash + 1 : p;
}
}
const char* fullName() const override {
return _opened ? _name.get() : nullptr;
}
bool isFile() const override {
return _opened; // Could look at ISTTY but that's not the sense here. Just differentiating between dirs and files
}
bool isDirectory() const override {
return false;
}
time_t getLastWrite() override {
return getCreationTime(); // TODO - FatFS doesn't seem to report both filetimes
}
time_t getCreationTime() override {
time_t ftime = 0;
return ftime;
}
protected:
int _fd;
std::shared_ptr<char> _name;
bool _opened;
bool _writable;
};
class SemiFSImpl : public FSImpl {
public:
SemiFSImpl() {
/* noop */
}
FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) override {
if (!path || !path[0]) {
DEBUGV("SemiFSImpl::open() called with invalid filename\n");
return FileImplPtr();
}
// Mode conversion https://developer.arm.com/documentation/dui0471/m/what-is-semihosting-/sys-open--0x01-?lang=en
int mode = 1; // "rb"
if (accessMode == AM_READ) {
mode = 1; // "rb"
} else if (accessMode == AM_WRITE) {
if (openMode & OM_APPEND) {
mode = 9; // "ab";
} else {
mode = 5; // "wb";
}
} else {
if (openMode & OM_TRUNCATE) {
mode = 7; // "w+b";
} else if (openMode & OM_APPEND) {
mode = 3; // "r+b"
} else {
mode = 11; // "a+b";
}
}
uint32_t a[3];
a[0] = (uint32_t)path;
a[1] = mode;
a[2] = strlen(path);
int handle = Semihost(SEMIHOST_SYS_OPEN, a);
if (handle < 0) {
return FileImplPtr();
}
return std::make_shared<SemiFSFileImpl>(handle, path, (accessMode & AM_WRITE) ? true : false);
}
bool exists(const char* path) override {
File f = open(path, OM_DEFAULT, AM_READ);
return f ? true : false;
}
DirImplPtr openDir(const char* path) override {
// No directories
return DirImplPtr();
}
bool rename(const char* pathFrom, const char* pathTo) override {
uint32_t a[4];
a[0] = (uint32_t)pathFrom;
a[1] = strlen(pathFrom);
a[2] = (uint32_t)pathTo;
a[3] = strlen(pathTo);
return !Semihost(SEMIHOST_SYS_RENAME, a);
}
bool info(FSInfo& info) override {
// Not available
return false;
}
bool remove(const char* path) override {
uint32_t a[2];
a[0] = (uint32_t)path;
a[1] = strlen(path);
return !Semihost(SEMIHOST_SYS_REMOVE, a);
}
bool mkdir(const char* path) override {
// No mkdir
return false;
}
bool rmdir(const char* path) override {
// No rmdir
return false;
}
bool stat(const char *path, FSStat *st) override {
if (!path || !path[0]) {
return false;
}
uint32_t a[3];
a[0] = (uint32_t)path;
a[1] = 0; // READ
a[2] = strlen(path);
int fn = Semihost(SEMIHOST_SYS_OPEN, a);
if (fn < 0) {
return false;
}
bzero(st, sizeof(*st));
a[0] = fn;
st->size = Semihost(SEMIHOST_SYS_FLEN, a);
a[0] = fn;
Semihost(SEMIHOST_SYS_CLOSE, a);
return true;
}
bool setConfig(const FSConfig &cfg) override {
return true;
}
bool begin() override {
/* noop */
return true;
}
void end() override {
/* noop */
}
bool format() override {
return false;
}
};
}; // namespace sdfs
#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SEMIFS)
extern FS SemiFS;
using semifs::SemiFSConfig;
#endif

View file

@ -0,0 +1,6 @@
#include "Semihosting.h"
#include "SerialSemi.h"
#include "SemiFS.h"
SerialSemiClass SerialSemi;
FS SemiFS = FS(FSImplPtr(new semifs::SemiFSImpl()));

113
cores/rp2040/Semihosting.h Normal file
View file

@ -0,0 +1,113 @@
/*
Semihosting.h - Semihosting for Serial and FS access via GDB
Copyright (c) 2024 Earle F. Philhower, III. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
// Be sure to only use this library with GDB and to enable the ARM semihosting support
// (gdb) monitor arm semihosting enable
// Input/output will be handled by OpenOCD
/**
@brief Semihosting host API opcodes, from https://developer.arm.com/documentation/dui0471/g/Semihosting/Semihosting-operations?lang=en
*/
typedef enum {
SEMIHOST_SYS_CLOSE = 0x02,
SEMIHOST_SYS_CLOCK = 0x10,
SEMIHOST_SYS_ELAPSED = 0x30,
SEMIHOST_SYS_ERRNO = 0x13,
SEMIHOST_SYS_FLEN = 0x0C,
SEMIHOST_SYS_GET_CMDLINE = 0x15,
SEMIHOST_SYS_HEAPINFO = 0x16,
SEMIHOST_SYS_ISERROR = 0x08,
SEMIHOST_SYS_ISTTY = 0x09,
SEMIHOST_SYS_OPEN = 0x01,
SEMIHOST_SYS_READ = 0x06,
SEMIHOST_SYS_READC = 0x07,
SEMIHOST_SYS_REMOVE = 0x0E,
SEMIHOST_SYS_RENAME = 0x0F,
SEMIHOST_SYS_SEEK = 0x0A,
SEMIHOST_SYS_SYSTEM = 0x12,
SEMIHOST_SYS_TICKFREQ = 0x31,
SEMIHOST_SYS_TIME = 0x11,
SEMIHOST_SYS_TMPNAM = 0x0D,
SEMIHOST_SYS_WRITE = 0x05,
SEMIHOST_SYS_WRITEC = 0x03,
SEMIHOST_SYS_WRITE0 = 0x04
} SEMIHOST_OPCODES;
#ifdef __arm__
/**
@brief Execute a semihosted request, from https://github.com/ErichStyger/mcuoneclipse/blob/master/Examples/MCUXpresso/FRDM-K22F/FRDM-K22F_Semihosting/source/McuSemihost.c
@param [in] reason Opcode to execute
@param [in] arg Any arguments for the opcode
@returns Result of operation
*/
static inline int __attribute__((always_inline)) Semihost(int reason, void *arg) {
int value;
__asm volatile(
"mov r0, %[rsn] \n" /* place semihost operation code into R0 */
"mov r1, %[arg] \n" /* R1 points to the argument array */
"bkpt 0xAB \n" /* call debugger */
"mov %[val], r0 \n" /* debugger has stored result code in R0 */
: [val] "=r"(value) /* outputs */
: [rsn] "r"(reason), [arg] "r"(arg) /* inputs */
: "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" /* clobber */
);
return value; /* return result code, stored in R0 */
}
#else
/**
@brief Execute a semihosted request, from https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/n-5VQ9PHZ4w/m/KbzH5t9MBgAJ
@param [in] reason Opcode to execute
@param [in] argPack Any arguments for the opcode
@returns Result of operation
*/
static inline int __attribute__((always_inline)) Semihost(int reason, void *argPack) {
register int value asm("a0") = reason;
register void *ptr asm("a1") = argPack;
asm volatile(
// Force 16-byte alignment to make sure that the 3 instructions fall
// within the same virtual page.
" .balign 16 \n"
" .option push \n"
// Force non-compressed RISC-V instructions
" .option norvc \n"
// semihosting e-break sequence
" slli x0, x0, 0x1f \n" // # Entry NOP
" ebreak \n" // # Break to debugger
" srai x0, x0, 0x7 \n" // # NOP encoding the semihosting call number 7
" .option pop \n"
/*mark (value) as an output operand*/
: "=r"(value) /* Outputs */
// The semihosting call number is passed in a0, and the argument in a1.
: "0"(value), "r"(ptr) /* Inputs */
// The "memory" clobber makes GCC assume that any memory may be arbitrarily read or written by the asm block,
// so will prevent the compiler from reordering loads or stores across it, or from caching memory values in registers across it.
// The "memory" clobber also prevents the compiler from removing the asm block as dead code.
: "memory" /* Clobbers */
);
return value;
}
#endif

View file

@ -33,6 +33,7 @@ static std::map<int, PIOProgram*> _rxMap;
// Duplicate a program and replace the first insn with a "set x, repl"
static pio_program_t *pio_make_uart_prog(int repl, const pio_program_t *pg) {
pio_program_t *p = new pio_program_t;
memcpy(p, pg, sizeof(*p));
p->length = pg->length;
p->origin = pg->origin;
uint16_t *insn = (uint16_t *)malloc(p->length * 2);
@ -67,20 +68,17 @@ static PIOProgram *_getRxProgram(int bits) {
}
// ------------------------------------------------------------------------
// TODO - this works, but there must be a faster/better way...
static int _parity(int bits, int data) {
int p = 0;
for (int b = 0; b < bits; b++) {
p ^= (data & (1 << b)) ? 1 : 0;
}
return p;
static int __not_in_flash_func(_parity)(int data) {
data ^= data >> 4;
data &= 0xf;
return (0x6996 >> data) & 1;
}
// We need to cache generated SerialPIOs so we can add data to them from
// the shared handler
static SerialPIO *_pioSP[2][4];
static SerialPIO *_pioSP[3][4];
static void __not_in_flash_func(_fifoIRQ)() {
for (int p = 0; p < 2; p++) {
for (int p = 0; p < 3; p++) {
for (int sm = 0; sm < 4; sm++) {
SerialPIO *s = _pioSP[p][sm];
if (s) {
@ -97,20 +95,16 @@ void __not_in_flash_func(SerialPIO::_handleIRQ)() {
}
while (!pio_sm_is_rx_fifo_empty(_rxPIO, _rxSM)) {
uint32_t decode = _rxPIO->rxf[_rxSM];
decode >>= 33 - _rxBits;
uint32_t val = 0;
for (int b = 0; b < _bits + 1; b++) {
val |= (decode & (1 << (b * 2))) ? 1 << b : 0;
}
uint32_t val = decode >> (32 - _rxBits - 1);
if (_parity == UART_PARITY_EVEN) {
int p = ::_parity(_bits, val);
int p = ::_parity(val);
int r = (val & (1 << _bits)) ? 1 : 0;
if (p != r) {
// TODO - parity error
continue;
}
} else if (_parity == UART_PARITY_ODD) {
int p = ::_parity(_bits, val);
int p = ::_parity(val);
int r = (val & (1 << _bits)) ? 1 : 0;
if (p == r) {
// TODO - parity error
@ -138,6 +132,8 @@ SerialPIO::SerialPIO(pin_size_t tx, pin_size_t rx, size_t fifoSize) {
_fifoSize = fifoSize + 1; // Always one unused entry
_queue = new uint8_t[_fifoSize];
mutex_init(&_mutex);
_invertTX = false;
_invertRX = false;
}
SerialPIO::~SerialPIO() {
@ -145,6 +141,21 @@ SerialPIO::~SerialPIO() {
delete[] _queue;
}
static int pio_irq_0(PIO p) {
switch (pio_get_index(p)) {
case 0:
return PIO0_IRQ_0;
case 1:
return PIO1_IRQ_0;
#if defined(PICO_RP2350)
case 2:
return PIO2_IRQ_0;
#endif
default:
return -1;
}
}
void SerialPIO::begin(unsigned long baud, uint16_t config) {
_overflow = false;
_baud = baud;
@ -191,7 +202,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
_txBits = _bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1/*start bit*/;
_txPgm = _getTxProgram(_txBits);
int off;
if (!_txPgm->prepare(&_txPIO, &_txSM, &off)) {
if (!_txPgm->prepare(&_txPIO, &_txSM, &off, _tx, 1)) {
DEBUGCORE("ERROR: Unable to allocate PIO TX UART, out of PIO resources\n");
// ERROR, no free slots
return;
@ -209,16 +220,17 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
pio_sm_exec(_txPIO, _txSM, pio_encode_mov(pio_isr, pio_osr));
// Start running!
gpio_set_outover(_tx, _invertTX);
pio_sm_set_enabled(_txPIO, _txSM, true);
}
if (_rx != NOPIN) {
_writer = 0;
_reader = 0;
_rxBits = 2 * (_bits + _stop + (_parity != UART_PARITY_NONE ? 1 : 0) + 1) - 1;
_rxBits = _bits + (_parity != UART_PARITY_NONE ? 1 : 0);
_rxPgm = _getRxProgram(_rxBits);
int off;
if (!_rxPgm->prepare(&_rxPIO, &_rxSM, &off)) {
if (!_rxPgm->prepare(&_rxPIO, &_rxSM, &off, _rx, 1)) {
DEBUGCORE("ERROR: Unable to allocate PIO RX UART, out of PIO resources\n");
return;
}
@ -230,7 +242,7 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
pio_sm_clear_fifos(_rxPIO, _rxSM); // Remove any existing data
// Put phase divider into OSR w/o using add'l program memory
pio_sm_put_blocking(_rxPIO, _rxSM, clock_get_hz(clk_sys) / (_baud * 2) - 7 /* insns in PIO halfbit loop */);
pio_sm_put_blocking(_rxPIO, _rxSM, clock_get_hz(clk_sys) / (_baud * 2) - 3);
pio_sm_exec(_rxPIO, _rxSM, pio_encode_pull(false, false));
// Join the TX FIFO to the RX one now that we don't need it
@ -243,10 +255,11 @@ void SerialPIO::begin(unsigned long baud, uint16_t config) {
case 2: pio_set_irq0_source_enabled(_rxPIO, pis_sm2_rx_fifo_not_empty, true); break;
case 3: pio_set_irq0_source_enabled(_rxPIO, pis_sm3_rx_fifo_not_empty, true); break;
}
auto irqno = pio_get_index(_rxPIO) == 0 ? PIO0_IRQ_0 : PIO1_IRQ_0;
auto irqno = pio_irq_0(_rxPIO);
irq_set_exclusive_handler(irqno, _fifoIRQ);
irq_set_enabled(irqno, true);
gpio_set_inover(_rx, _invertRX);
pio_sm_set_enabled(_rxPIO, _rxSM, true);
}
@ -260,6 +273,7 @@ void SerialPIO::end() {
if (_tx != NOPIN) {
pio_sm_set_enabled(_txPIO, _txSM, false);
pio_sm_unclaim(_txPIO, _txSM);
gpio_set_outover(_tx, 0);
}
if (_rx != NOPIN) {
pio_sm_set_enabled(_rxPIO, _rxSM, false);
@ -272,9 +286,10 @@ void SerialPIO::end() {
used = used || !!_pioSP[pioNum][i];
}
if (!used) {
auto irqno = pioNum == 0 ? PIO0_IRQ_0 : PIO1_IRQ_0;
auto irqno = pio_irq_0(_rxPIO);
irq_set_enabled(irqno, false);
}
gpio_set_inover(_rx, 0);
}
_running = false;
}
@ -356,10 +371,10 @@ size_t SerialPIO::write(uint8_t c) {
if (_parity == UART_PARITY_NONE) {
val |= 7 << _bits; // Set 2 stop bits, the HW will only transmit the required number
} else if (_parity == UART_PARITY_EVEN) {
val |= ::_parity(_bits, c) << _bits;
val |= ::_parity(c) << _bits;
val |= 7 << (_bits + 1);
} else {
val |= (1 ^ ::_parity(_bits, c)) << _bits;
val |= (1 ^ ::_parity(c)) << _bits;
val |= 7 << (_bits + 1);
}
val <<= 1; // Start bit = low

View file

@ -29,7 +29,7 @@
extern "C" typedef struct uart_inst uart_inst_t;
class SerialPIO : public HardwareSerial {
class SerialPIO : public arduino::HardwareSerial {
public:
static const pin_size_t NOPIN = 0xff; // Use in constructor to disable RX or TX unit
SerialPIO(pin_size_t tx, pin_size_t rx, size_t fifoSize = 32);
@ -41,6 +41,23 @@ public:
void begin(unsigned long baud, uint16_t config) override;
void end() override;
void setInverted(bool invTx = true, bool invRx = true) {
setInvertTX(invTx);
setInvertRX(invRx);
}
bool setInvertTX(bool invert = true) {
if (!_running) {
_invertTX = invert;
}
return !_running;
}
bool setInvertRX(bool invert = true) {
if (!_running) {
_invertRX = invert;
}
return !_running;
}
virtual int peek() override;
virtual int read() override;
virtual int available() override;
@ -51,7 +68,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 +80,8 @@ protected:
int _stop;
bool _overflow;
mutex_t _mutex;
bool _invertTX;
bool _invertRX;
PIOProgram *_txPgm;
PIO _txPIO;

98
cores/rp2040/SerialSemi.h Normal file
View file

@ -0,0 +1,98 @@
/*
SerialSemi.h - Serial port over Semihosting for ARM
Copyright (c) 2024 Earle F. Philhower, III. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "Semihosting.h"
#include "Arduino.h"
#include "api/HardwareSerial.h"
class SerialSemiClass : public arduino::HardwareSerial {
public:
SerialSemiClass() {
/* noop */
}
~SerialSemiClass() {
/* noop */
}
void begin(unsigned long baudIgnored = 115200) override {
(void)baudIgnored;
}
void begin(unsigned long baudIgnored, uint16_t configIgnored) override {
(void)baudIgnored;
(void)configIgnored;
}
void end() override {
/* noop */
}
virtual int peek() override {
// Can't really peek on SH, so fake it best we can
if (!_peeked) {
_peekedChar = read();
_peeked = true;
}
return _peekedChar;
}
virtual int read() override {
if (_peeked) {
_peeked = false;
return _peekedChar;
}
return Semihost(SEMIHOST_SYS_READC, nullptr);
}
virtual int available() override {
// Can't really tell with SH, so always true. Buyer beware
return 1;
}
virtual int availableForWrite() override {
// Can't really tell with SH, so always true. Buyer beware
return 1;
}
virtual void flush() override {
/* noop */
}
virtual size_t write(uint8_t c) override {
int32_t param = c;
Semihost(SEMIHOST_SYS_WRITEC, &param);
return 1;
}
using Print::write;
operator bool() override {
return true;
}
private:
bool _peeked = false;
uint8_t _peekedChar;
};
extern SerialSemiClass SerialSemi;

View file

@ -32,14 +32,29 @@ extern void serialEvent1() __attribute__((weak));
extern void serialEvent2() __attribute__((weak));
bool SerialUART::setRX(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({1, 13, 17, 29}) /* UART0 */,
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
constexpr uint64_t valid[2] = { __bitset({1, 3, 13, 15, 17, 19, 29, 31, 33, 35, 45, 47}) /* UART0 */,
__bitset({5, 7, 9, 11, 21, 23, 25, 27, 37, 39, 41, 43}) /* UART1 */
};
#elif defined(PICO_RP2350)
constexpr uint64_t valid[2] = { __bitset({1, 3, 13, 15, 17, 19, 29}) /* UART0 */,
__bitset({5, 7, 9, 11, 21, 23, 25, 27}) /* UART1 */
};
#else
constexpr uint64_t valid[2] = { __bitset({1, 13, 17, 29}) /* UART0 */,
__bitset({5, 9, 21, 25}) /* UART1 */
};
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
#endif
if ((!_running) && ((1LL << pin) & valid[uart_get_index(_uart)])) {
_rx = 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 {
@ -49,14 +64,28 @@ bool SerialUART::setRX(pin_size_t pin) {
}
bool SerialUART::setTX(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({0, 12, 16, 28}) /* UART0 */,
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
constexpr uint64_t valid[2] = { __bitset({0, 2, 12, 14, 16, 18, 28, 30, 32, 34, 44, 46}) /* UART0 */,
__bitset({4, 6, 8, 10, 20, 22, 24, 26, 36, 38, 40, 42}) /* UART1 */
};
#elif defined(PICO_RP2350)
constexpr uint64_t valid[2] = { __bitset({0, 2, 12, 14, 16, 18, 28}) /* UART0 */,
__bitset({4, 6, 8, 10, 20, 22, 24, 26}) /* UART1 */
};
#else
constexpr uint64_t valid[2] = { __bitset({0, 12, 16, 28}) /* UART0 */,
__bitset({4, 8, 20, 24}) /* UART1 */
};
if ((!_running) && ((1 << pin) & valid[uart_get_index(_uart)])) {
#endif
if ((!_running) && ((1LL << pin) & valid[uart_get_index(_uart)])) {
_tx = 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 {
@ -66,14 +95,24 @@ bool SerialUART::setTX(pin_size_t pin) {
}
bool SerialUART::setRTS(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({3, 15, 19}) /* UART0 */,
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
constexpr uint64_t valid[2] = { __bitset({3, 15, 19, 31, 35, 47}) /* UART0 */,
__bitset({7, 11, 23, 27, 39, 43}) /* UART1 */
};
#else
constexpr uint64_t valid[2] = { __bitset({3, 15, 19}) /* UART0 */,
__bitset({7, 11, 23, 27}) /* UART1 */
};
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1 << pin) & valid[uart_get_index(_uart)]))) {
#endif
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1LL << pin) & valid[uart_get_index(_uart)]))) {
_rts = 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 {
@ -83,14 +122,24 @@ bool SerialUART::setRTS(pin_size_t pin) {
}
bool SerialUART::setCTS(pin_size_t pin) {
constexpr uint32_t valid[2] = { __bitset({2, 14, 18}) /* UART0 */,
#if defined(PICO_RP2350) && !PICO_RP2350A // RP2350B
constexpr uint64_t valid[2] = { __bitset({2, 14, 18, 30, 34, 46}) /* UART0 */,
__bitset({6, 10, 22, 26, 38, 42}) /* UART1 */
};
#else
constexpr uint64_t valid[2] = { __bitset({2, 14, 18}) /* UART0 */,
__bitset({6, 10, 22, 26}) /* UART1 */
};
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1 << pin) & valid[uart_get_index(_uart)]))) {
#endif
if ((!_running) && ((pin == UART_PIN_NOT_DEFINED) || ((1LL << pin) & valid[uart_get_index(_uart)]))) {
_cts = 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 {
@ -122,11 +171,49 @@ SerialUART::SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx, pin_size
_cts = cts;
mutex_init(&_mutex);
mutex_init(&_fifoMutex);
_invertTX = false;
_invertRX = false;
_invertControl = false;
}
static void _uart0IRQ();
static void _uart1IRQ();
// Does the selected TX/RX need UART_AUX function (rp2350)
static gpio_function_t __gpioFunction(int pin) {
switch (pin) {
#if defined(PICO_RP2350) && !PICO_RP2350A
case 2:
case 3:
case 6:
case 7:
case 10:
case 11:
case 14:
case 15:
case 18:
case 19:
case 22:
case 23:
case 26:
case 27:
case 30:
case 31:
case 34:
case 35:
case 38:
case 39:
case 42:
case 43:
case 46:
case 47:
return GPIO_FUNC_UART_AUX;
#endif
default:
return GPIO_FUNC_UART;
}
}
void SerialUART::begin(unsigned long baud, uint16_t config) {
if (_running) {
end();
@ -137,15 +224,19 @@ void SerialUART::begin(unsigned long baud, uint16_t config) {
_fcnTx = gpio_get_function(_tx);
_fcnRx = gpio_get_function(_rx);
gpio_set_function(_tx, GPIO_FUNC_UART);
gpio_set_function(_rx, GPIO_FUNC_UART);
gpio_set_function(_tx, __gpioFunction(_tx));
gpio_set_outover(_tx, _invertTX ? 1 : 0);
gpio_set_function(_rx, __gpioFunction(_rx));
gpio_set_inover(_rx, _invertRX ? 1 : 0);
if (_rts != UART_PIN_NOT_DEFINED) {
_fcnRts = gpio_get_function(_rts);
gpio_set_function(_rts, GPIO_FUNC_UART);
gpio_set_outover(_rts, _invertControl ? 1 : 0);
}
if (_cts != UART_PIN_NOT_DEFINED) {
_fcnCts = gpio_get_function(_cts);
gpio_set_function(_cts, GPIO_FUNC_UART);
gpio_set_inover(_cts, _invertControl ? 1 : 0);
}
uart_init(_uart, baud);
@ -185,7 +276,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;
@ -230,12 +321,16 @@ void SerialUART::end() {
// Restore pin functions
gpio_set_function(_tx, _fcnTx);
gpio_set_outover(_tx, 0);
gpio_set_function(_rx, _fcnRx);
gpio_set_inover(_rx, 0);
if (_rts != UART_PIN_NOT_DEFINED) {
gpio_set_function(_rts, _fcnRts);
gpio_set_outover(_rts, 0);
}
if (_cts != UART_PIN_NOT_DEFINED) {
gpio_set_function(_cts, _fcnCts);
gpio_set_inover(_cts, 0);
}
}

View file

@ -29,7 +29,7 @@
extern "C" typedef struct uart_inst uart_inst_t;
#define UART_PIN_NOT_DEFINED (255u)
class SerialUART : public HardwareSerial {
class SerialUART : public arduino::HardwareSerial {
public:
SerialUART(uart_inst_t *uart, pin_size_t tx, pin_size_t rx, pin_size_t rts = UART_PIN_NOT_DEFINED, pin_size_t cts = UART_PIN_NOT_DEFINED);
@ -43,6 +43,26 @@ public:
ret &= setTX(tx);
return ret;
}
bool setInvertTX(bool invert = true) {
if (!_running) {
_invertTX = invert;
}
return !_running;
}
bool setInvertRX(bool invert = true) {
if (!_running) {
_invertRX = invert;
}
return !_running;
}
bool setInvertControl(bool invert = true) {
if (!_running) {
_invertControl = invert;
}
return !_running;
}
bool setFIFOSize(size_t size);
bool setPollingMode(bool mode = true);
@ -80,12 +100,13 @@ private:
uart_inst_t *_uart;
pin_size_t _tx, _rx;
pin_size_t _rts, _cts;
enum gpio_function _fcnTx, _fcnRx, _fcnRts, _fcnCts;
gpio_function_t _fcnTx, _fcnRx, _fcnRts, _fcnCts;
int _baud;
mutex_t _mutex;
bool _polling = false;
bool _overflow;
bool _break;
bool _invertTX, _invertRX, _invertControl;
// Lockless, IRQ-handled circular queue
uint32_t _writer;

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,12 +191,20 @@ 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
}
}
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) {
(void) itf;
_dtr = dtr ? true : false;

View file

@ -24,7 +24,7 @@
#include "api/HardwareSerial.h"
#include <stdarg.h>
class SerialUSB : public HardwareSerial {
class SerialUSB : public arduino::HardwareSerial {
public:
SerialUSB() { }
void begin(unsigned long baud = 115200) override;
@ -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;

View file

@ -22,34 +22,56 @@
#include "SerialPIO.h"
/**
@brief Implements a UART port using PIO for input and output
*/
class SoftwareSerial : public SerialPIO {
public:
// Note the rx/tx pins are swapped in PIO vs SWSerial
/**
@brief Constructs a PIO-based UART
@param [in] rx GPIO for RX pin or -1 for transmit-only
@param [in] tx GPIO for TX pin or -1 for receive-only
@param [in] invert True to invert the receive and transmit lines
*/
SoftwareSerial(pin_size_t rx, pin_size_t tx, bool invert = false) : SerialPIO(tx, rx) {
_invert = invert;
}
~SoftwareSerial() {
if (_invert) {
gpio_set_outover(_tx, 0);
gpio_set_outover(_rx, 0);
}
}
/**
@brief Starts the PIO UART
@param [in] baud Serial bit rate
*/
virtual void begin(unsigned long baud = 115200) override {
begin(baud, SERIAL_8N1);
};
/**
@brief Starts the PIO UART
@param [in] baud Serial bit rate
@param [in] config Start/Stop/Len configuration (i.e. SERIAL_8N1 or SERIAL_7E2)
*/
void begin(unsigned long baud, uint16_t config) override {
setInvertTX(_invert);
setInvertRX(_invert);
SerialPIO::begin(baud, config);
if (_invert) {
gpio_set_outover(_tx, GPIO_OVERRIDE_INVERT);
gpio_set_inover(_rx, GPIO_OVERRIDE_INVERT);
}
}
/**
@brief No-op on this core
*/
void listen() { /* noop */ }
/**
@brief No-op on this core
@returns True always
*/
bool isListening() {
return true;
}

474
cores/rp2040/TZ.h Normal file
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")

View file

@ -56,7 +56,7 @@ int64_t _stopTonePIO(alarm_id_t id, void *user_data) {
}
void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
if (pin > 29) {
if (pin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return;
}
@ -71,17 +71,14 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
return; // Weird deadlock case
}
int us = 1'000'000 / frequency / 2;
if (us < 5) {
us = 5;
}
unsigned int delay = (RP2040::f_cpu() + frequency) / (frequency * 2) - 3; // rounded
auto entry = _toneMap.find(pin);
Tone *newTone;
if (entry == _toneMap.end()) {
newTone = new Tone();
newTone->pin = pin;
pinMode(pin, OUTPUT);
if (!_tone2Pgm.prepare(&newTone->pio, &newTone->sm, &newTone->off)) {
if (!_tone2Pgm.prepare(&newTone->pio, &newTone->sm, &newTone->off, pin, 1)) {
DEBUGCORE("ERROR: tone unable to start, out of PIO resources\n");
// ERROR, no free slots
delete newTone;
@ -99,7 +96,9 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
tone2_program_init(newTone->pio, newTone->sm, newTone->off, pin);
}
pio_sm_clear_fifos(newTone->pio, newTone->sm); // Remove any old updates that haven't yet taken effect
pio_sm_put_blocking(newTone->pio, newTone->sm, RP2040::usToPIOCycles(us));
pio_sm_put_blocking(newTone->pio, newTone->sm, delay);
pio_sm_exec(newTone->pio, newTone->sm, pio_encode_pull(false, false));
pio_sm_exec(newTone->pio, newTone->sm, pio_encode_mov(pio_x, pio_osr));
pio_sm_set_enabled(newTone->pio, newTone->sm, true);
_toneMap.insert({pin, newTone});
@ -118,7 +117,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration) {
void noTone(uint8_t pin) {
CoreMutex m(&_toneMutex);
if ((pin > 29) || !m) {
if ((pin > __GPIOCNT) || !m) {
DEBUGCORE("ERROR: Illegal pin in tone (%d)\n", pin);
return;
}

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

View file

@ -19,8 +19,9 @@
*/
#include "_freertos.h"
#include "pico/mutex.h"
#include <pico/mutex.h>
#include <stdlib.h>
#include "Arduino.h"
typedef struct {
mutex_t *src;
@ -28,9 +29,9 @@ typedef struct {
} FMMap;
static FMMap *_map = nullptr;
extern "C" SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m) {
SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive) {
if (!_map) {
_map = (FMMap *)calloc(sizeof(FMMap), 16);
_map = (FMMap *)calloc(16, sizeof(FMMap));
}
// Pre-existing map
for (int i = 0; i < 16; i++) {
@ -42,7 +43,12 @@ extern "C" SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m) {
for (int i = 0; i < 16; i++) {
if (_map[i].src == nullptr) {
// Make a new mutex
SemaphoreHandle_t fm = __freertos_mutex_create();
SemaphoreHandle_t fm;
if (recursive) {
fm = _freertos_recursive_mutex_create();
} else {
fm = __freertos_mutex_create();
}
if (fm == nullptr) {
return nullptr;
}

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
@ -30,37 +30,36 @@ extern bool __isFreeRTOS;
// FreeRTOS has been set up
extern volatile bool __freeRTOSinitted;
#ifdef __cplusplus
extern "C" {
#ifndef INC_FREERTOS_H
struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */
typedef struct QueueDefinition * QueueHandle_t;
typedef QueueHandle_t SemaphoreHandle_t;
#endif
#endif // __cplusplus
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;
extern SemaphoreHandle_t __freertos_mutex_create() __attribute__((weak));
extern SemaphoreHandle_t _freertos_recursive_mutex_create() __attribute__((weak));
extern bool __freertos_check_if_in_isr() __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_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 SemaphoreHandle_t __freertos_mutex_create() __attribute__((weak));
extern SemaphoreHandle_t _freertos_recursive_mutex_create() __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));
extern void __freertos_mutex_take(SemaphoreHandle_t mtx) __attribute__((weak));
#ifndef INC_FREERTOS_H
extern void vTaskSuspendAll() __attribute__((weak));
extern int32_t xTaskResumeAll() __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, BaseType_t* pxHigherPriorityTaskWoken) __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_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));
extern SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m);
extern void __freertos_idle_other_core() __attribute__((weak));
extern void __freertos_resume_other_core() __attribute__((weak));
extern void __freertos_task_exit_critical() __attribute__((weak));
extern void __freertos_task_enter_critical() __attribute__((weak));
#ifdef __cplusplus
}
// Halt the FreeRTOS PendSV task switching magic
extern "C" int __holdUpPendSV;
extern SemaphoreHandle_t __get_freertos_mutex_for_ptr(mutex_t *m, bool recursive = false);
#endif // __cplusplus

7
cores/rp2040/_needsbt.h Normal file
View file

@ -0,0 +1,7 @@
// Simple helper header to ensure pico libs support ?BT
#ifndef ENABLE_CLASSIC
#define ENABLE_CLASSIC 0
#endif
static_assert(ENABLE_CLASSIC, "This library needs Bluetooth enabled. Use the 'Tools->IP/Bluetooth Stack' menu in the IDE to enable it.");

1478
cores/rp2040/_xoshiro.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@
#define ccount_wrap_target 0
#define ccount_wrap 1
#define ccount_pio_version 0
static const uint16_t ccount_program_instructions[] = {
// .wrap_target
@ -27,6 +28,10 @@ static const struct pio_program ccount_program = {
.instructions = ccount_program_instructions,
.length = 2,
.origin = -1,
.pio_version = ccount_pio_version,
#if PICO_PIO_VERSION > 0
.used_gpio_ranges = 0x0
#endif
};
static inline pio_sm_config ccount_program_get_default_config(uint offset) {

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;

View file

@ -0,0 +1,206 @@
/*
CYW43 TCP/Ethernet wrappers
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(PICO_CYW43_SUPPORTED)
#include <lwip/netif.h>
extern "C" {
#include <cyw43.h>
#include <cyw43_stats.h>
}
#include <pico/cyw43_arch.h>
#include <pico/cyw43_driver.h>
#include <pico/lwip_nosys.h>
#include <hardware/resets.h>
#include <hardware/gpio.h>
#include <hardware/adc.h>
#include <hardware/clocks.h>
#include <Arduino.h>
// From cyw43_ctrl.c
#define WIFI_JOIN_STATE_KIND_MASK (0x000f)
#define WIFI_JOIN_STATE_ACTIVE (0x0001)
#define WIFI_JOIN_STATE_FAIL (0x0002)
#define WIFI_JOIN_STATE_NONET (0x0003)
#define WIFI_JOIN_STATE_BADAUTH (0x0004)
#define WIFI_JOIN_STATE_AUTH (0x0200)
#define WIFI_JOIN_STATE_LINK (0x0400)
#define WIFI_JOIN_STATE_KEYED (0x0800)
#define WIFI_JOIN_STATE_ALL (0x0e01)
// The core can't directly call a library, so put in a dummy weak one to be overridden by one in lwip_cyw43 library
extern struct netif *__getCYW43Netif() __attribute__((weak));
struct netif *__getCYW43Netif() {
return nullptr;
}
// CB from the cyw43 driver
extern "C" void __wrap_cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len, const uint8_t *buf) {
(void) cb_data;
(void) itf;
struct netif *netif = __getCYW43Netif();
if (netif && (netif->flags & NETIF_FLAG_LINK_UP)) {
struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p != nullptr) {
pbuf_take(p, buf, len);
if ((netif->input(p, netif) != ERR_OK)) {
pbuf_free(p);
}
CYW43_STAT_INC(PACKET_IN_COUNT);
}
}
}
extern "C" void __wrap_cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) {
(void) self;
(void) itf;
struct netif *netif = __getCYW43Netif();
if (netif) {
netif_set_link_up(netif);
}
}
extern "C" void __wrap_cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) {
(void) self;
(void) itf;
struct netif *netif = __getCYW43Netif();
if (netif) {
netif_set_link_down(netif);
}
self->wifi_join_state &= ~WIFI_JOIN_STATE_ACTIVE;
}
extern "C" int __wrap_cyw43_tcpip_link_status(cyw43_t *self, int itf) {
struct netif *netif = __getCYW43Netif();
//if ((CYW43::_netif->flags & (NETIF_FLAG_UP | NETIF_FLAG_LINK_UP)) == (NETIF_FLAG_UP | NETIF_FLAG_LINK_UP))
// Fake this since it's only used in the SDK
if (netif && ((netif->flags & (NETIF_FLAG_LINK_UP)) == (NETIF_FLAG_LINK_UP))) {
return CYW43_LINK_UP;
} else {
return cyw43_wifi_link_status(self, itf);
}
}
// CBs from the SDK, not needed here as we do TCP later in the game
extern "C" void __wrap_cyw43_cb_tcpip_init(cyw43_t *self, int itf) {
(void) self;
(void) itf;
}
extern "C" void __wrap_cyw43_cb_tcpip_deinit(cyw43_t *self, int itf) {
(void) self;
(void) itf;
}
#ifndef WIFICC
#define WIFICC CYW43_COUNTRY_WORLDWIDE
#endif
// Taken from https://datasheets.raspberrypi.com/picow/connecting-to-the-internet-with-pico-w.pdf
// also discussion in https://github.com/earlephilhower/arduino-pico/issues/849
static bool CheckPicoW() {
#ifdef PICO_RP2040
adc_init();
auto dir = gpio_get_dir(29);
auto fnc = gpio_get_function(29);
adc_gpio_init(29);
adc_select_input(3);
auto adc29 = adc_read();
gpio_set_function(29, fnc);
gpio_set_dir(29, dir);
dir = gpio_get_dir(25);
fnc = gpio_get_function(25);
gpio_init(25);
gpio_set_dir(25, GPIO_IN);
auto gp25 = gpio_get(25);
gpio_set_function(25, fnc);
gpio_set_dir(25, dir);
if (gp25) {
return true; // Can't tell, so assume yes
} else if (adc29 < 200) {
return true; // PicoW
} else {
return false;
}
#else
return true;
#endif
}
bool __isPicoW = true;
extern "C" void init_cyw43_wifi() {
__isPicoW = CheckPicoW();
if (__isPicoW) {
// Fix for overclocked CPU: SPI communication breaks down with default "div by 2" speed
// So, divide clock by 4 for anything including and above 250MHz CPU frequency.
if (clock_get_hz(clk_sys) >= 250000000) {
cyw43_set_pio_clock_divisor(4, 0); // div by 4.0
}
cyw43_arch_init_with_country(WIFICC);
}
}
extern "C" void __lockBluetooth() {
async_context_acquire_lock_blocking(cyw43_arch_async_context());
}
extern "C" void __unlockBluetooth() {
async_context_release_lock(cyw43_arch_async_context());
}
extern "C" void __pinMode(pin_size_t pin, PinMode mode);
extern "C" void __digitalWrite(pin_size_t pin, PinStatus val);
extern "C" PinStatus __digitalRead(pin_size_t pin);
extern "C" void cyw43_pinMode(pin_size_t pin, PinMode mode) {
if (!__isPicoW && (pin == PIN_LED)) {
pin = 25; // Silently swap in the Pico's LED
}
if (pin < 64) {
__pinMode(pin, mode);
} else {
// TBD - There is no GPIO direction control in the driver
}
}
extern "C" void cyw43_digitalWrite(pin_size_t pin, PinStatus val) {
if (!__isPicoW && (pin == PIN_LED)) {
pin = 25; // Silently swap in the Pico's LED
}
if (pin < 64) {
__digitalWrite(pin, val);
} else {
cyw43_arch_gpio_put(pin - 64, val == HIGH ? 1 : 0);
}
}
extern "C" PinStatus cyw43_digitalRead(pin_size_t pin) {
if (!__isPicoW && (pin == PIN_LED)) {
pin = 25; // Silently swap in the Pico's LED
}
if (pin < 64) {
return __digitalRead(pin);
} else {
return cyw43_arch_gpio_get(pin - 64) ? HIGH : LOW;
}
}
#endif

View file

@ -0,0 +1,37 @@
/*
CYW43 TCP/Ethernet wrappers
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 <Arduino.h>
#include <pico/cyw43_driver.h>
extern bool __isPicoW;
#ifdef __cplusplus
extern "C" {
#endif
void init_cyw43_wifi();
void __lockBluetooth();
void __unlockBluetooth();
void cyw43_pinMode(pin_size_t pin, PinMode mode);
void cyw43_digitalWrite(pin_size_t pin, PinStatus val);
PinStatus cyw43_digitalRead(pin_size_t pin);
#ifdef __cplusplus
}
#endif

470
cores/rp2040/gprof_gmon.c Normal file
View file

@ -0,0 +1,470 @@
/* -
Copyright (c) 1983, 1992, 1993
The Regents of the University of California. 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.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 THE REGENTS 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.
*/
// This code is built as a C file because otherwise G++ would add profiling
// code to the preamble of these functions as well, leading to an infinite
// loop in the mcount routine. Because the Arduino IDE can't (easily)
// apply different compile parameters to different files, we set all C++
// files to "-pg" but leave all C files uninstrumented.
// Original code and organization taken from https://mcuoneclipse.com/2015/08/23/tutorial-using-gnu-profiling-gprof-with-arm-cortex-m/
#include <Arduino.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
// Frequency of sampling PC
#ifndef GMON_HZ
#define GMON_HZ 10000
#endif
// Fraction of text space to allocate for histogram counters here, 1/2
#ifndef HISTFRACTION
#ifdef PICO_RP2350
#define HISTFRACTION 4 // Every 8 bytes of .text
#else
#define HISTFRACTION 8 // Every 16 bytes of .text
#endif
#endif
// Fraction of text space to allocate for from hash buckets.
// The value of HASHFRACTION is based on the minimum number of bytes
// of separation between two subroutine call points in the object code.
// Given MIN_SUBR_SEPARATION bytes of separation the value of
// HASHFRACTION is calculated as:
//
// HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
//
// For example, on the VAX, the shortest two call sequence is:
//
// calls $0,(r0)
// calls $0,(r0)
//
// which is separated by only three bytes, thus HASHFRACTION is
// calculated as:
//
// HASHFRACTION = 3 / (2 * 2 - 1) = 1
//
// Note that the division above rounds down, thus if MIN_SUBR_FRACTION
// is less than three, this algorithm will not work!
//
// In practice, however, call instructions are rarely at a minimal
// distance. Hence, we will define HASHFRACTION to be 2 across all
// architectures. This saves a reasonable amount of space for
// profiling data structures without (in practice) sacrificing
// any granularity.
#ifndef HASHFRACTION
#define HASHFRACTION 2
#endif
// Percent of text space to allocate for tostructs with a minimum.
#ifndef ARCDENSITY
#define ARCDENSITY 2 // This is in percentage, relative to text size!
#endif
#define MINARCS 50
#define MAXARCS ((1 << (8 * sizeof(HISTCOUNTER))) - 2)
// Histogram counters are unsigned shorts (according to the kernel)
typedef uint16_t HISTCOUNTER; //#define HISTCOUNTER unsigned short
// In the original profiler code selfpc and count are full 32 bits each
// so the structure actually comes to 12 bytes due to padding (with 2
// bytes wasted per entry). We don't have that much to spare on the Picos,
// so limit the recorded address to 16MB (which is the flash address
// window, anyway) and the counts to 16M (saturating). This saves 4 bytes
// (33%) per entry at the cost of some logic to expand/pack it.
struct tostruct {
uint8_t selfpc[3]; // Callee address/program counter. The caller address is in froms[] array which points to tos[] array
uint8_t count[3]; // How many times it has been called
uint16_t link; // Link to next entry in hash table. For tos[0] this points to the last used entry
};
typedef enum { PROFILE_NOT_INIT = 0, PROFILE_ON, PROFILE_OFF } PROFILE_State;
struct profinfo {
PROFILE_State state; // Profiling state
uint16_t *counter; // Profiling counters
size_t lowpc, highpc; // Range to be profiled
uint32_t scale; // Scale value of bins
};
// Global profinfo for profil() call
static struct profinfo prof = { PROFILE_NOT_INIT, 0, 0, 0, 0 };
// Possible states of profiling
typedef enum { GMON_PROF_ON = 0, GMON_PROF_BUSY, GMON_PROF_ERROR, GMON_PROF_OFF } GMON_State;
// The profiling data structures are housed in this structure.
struct gmonparam {
int state;
uint16_t *kcount; // Histogram PC sample array
size_t kcountsize; // Size of kcount[] array in bytes
uint16_t *froms; // Array of hashed 'from' addresses. The 16bit value is an index into the tos[] array
size_t fromssize; // Size of froms[] array in bytes
struct tostruct *tos; // to struct, contains histogram counter
size_t tossize; // Size of tos[] array in bytes
long tolimit;
size_t lowpc; // Low program counter of area
size_t highpc; // High program counter
size_t textsize; // Code size
};
static struct gmonparam _gmonparam = { GMON_PROF_OFF, NULL, 0, NULL, 0, NULL, 0, 0L, 0, 0, 0};
static bool already_setup = false; // Flag to indicate if we need to init
static bool _perf_in_setup = false; // Are we currently trying to initialize? (avoid infinite recursion)
int __profileMemSize = 0; // Memory allocated by the profiler to store tables
static int s_scale = 0;
#define SCALE_1_TO_1 0x10000L
// Convert an addr to an index
static inline __attribute__((always_inline)) size_t profidx(size_t pc, size_t base, size_t scale) {
size_t i = (pc - base) / 2;
return (unsigned long long int) i * scale / 65536;
}
// Sample the current program counter periodically
#if defined(__riscv)
// TODO - systick-like handler
#else
static void __no_inline_not_in_flash_func(_SystickHandler)(void) {
static size_t pc, idx; // Ensure in heap, not on stack
extern volatile bool __otherCoreIdled;
if (!__otherCoreIdled && (prof.state == PROFILE_ON)) {
pc = ((uint32_t*)(__builtin_frame_address(0)))[14]; // Get SP and use it to get the return address from stack
if ((pc >= prof.lowpc) && (pc < prof.highpc)) {
idx = profidx(pc, prof.lowpc, prof.scale);
prof.counter[idx]++;
}
}
}
#endif
// Convert an index into an address
static inline __attribute__((always_inline)) size_t profaddr(size_t idx, size_t base, size_t scale) {
return base + ((((unsigned long long)(idx) << 16) / (unsigned long long)(scale)) << 1);
}
// Start or stop profiling
// Profiling goes into the SAMPLES buffer of size SIZE (which is treated as an array of uint16_ts of size size/2).
// Each bin represents a range of pc addresses from OFFSET. The number of pc addresses in a bin depends on SCALE.
// (A scale of 65536 maps each bin to two addresses, A scale of 32768 maps each bin to 4 addresses, a scale of
// 1 maps each bin to 128k address). Scale may be 1 - 65536, or zero to turn off profiling
static int __no_inline_not_in_flash_func(profile_ctl)(char *samples, size_t size, size_t offset, uint32_t scale) {
size_t maxbin;
if (scale > 65536) {
return -1;
}
prof.state = PROFILE_OFF;
if (scale) {
bzero(samples, size);
bzero(&prof, sizeof(prof));
maxbin = size >> 1;
prof.counter = (uint16_t*)samples;
prof.lowpc = offset;
prof.highpc = profaddr(maxbin, offset, scale);
prof.scale = scale;
prof.state = PROFILE_ON;
}
return 0;
}
// Control profiling. Profiling is what mcount checks to see if all the data structures are ready.
static void __no_inline_not_in_flash_func(moncontrol)(int mode) {
if (mode) { // Start
profile_ctl((char *)_gmonparam.kcount, _gmonparam.kcountsize, _gmonparam.lowpc, s_scale);
_gmonparam.state = GMON_PROF_ON;
} else { // Stop
profile_ctl((char *)NULL, 0, 0, 0);
_gmonparam.state = GMON_PROF_OFF;
}
}
// General rounding functions
static inline __attribute__((always_inline)) size_t rounddown(size_t x, size_t y) {
return (x / y) * y;
}
static inline __attribute__((always_inline)) size_t roundup(size_t x, size_t y) {
return ((x + y - 1) / y) * y;
}
// Allocate memory and set boundaries before any sampling is performed
void __no_inline_not_in_flash_func(monstartup)(size_t lowpc, size_t highpc) {
register size_t o;
char *cp;
struct gmonparam *p = &_gmonparam;
// Round lowpc and highpc to multiples of the density we're using so the rest of the scaling (here and in gprof) stays in ints.
p->lowpc = rounddown(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
p->highpc = roundup(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
p->textsize = p->highpc - p->lowpc;
p->kcountsize = p->textsize / HISTFRACTION;
p->fromssize = p->textsize / HASHFRACTION;
p->tolimit = p->textsize * ARCDENSITY / 100;
if (p->tolimit < MINARCS) {
p->tolimit = MINARCS;
} else if (p->tolimit > MAXARCS) {
p->tolimit = MAXARCS;
}
p->tossize = p->tolimit * sizeof(struct tostruct);
__profileMemSize = p->kcountsize + p->fromssize + p->tossize;
#ifdef RP2350_PSRAM_CS
cp = pmalloc(__profileMemSize);
#else
cp = malloc(__profileMemSize);
#endif
if (cp == NULL) {
// OOM
already_setup = false;
return;
}
// Zero out cp as value will be added there
bzero(cp, p->kcountsize + p->fromssize + p->tossize);
p->tos = (struct tostruct *)cp;
cp += p->tossize;
p->kcount = (uint16_t *)cp;
cp += p->kcountsize;
p->froms = (uint16_t *)cp;
p->tos[0].link = 0;
o = p->highpc - p->lowpc;
if (p->kcountsize < o) {
s_scale = ((float)p->kcountsize / o) * SCALE_1_TO_1;
} else {
s_scale = SCALE_1_TO_1;
}
moncontrol(1); // Start
}
// Accessors for the selfpc and count fields
static inline __attribute__((always_inline)) void setselfpc(struct tostruct *x, size_t d) {
x->selfpc[0] = d & 0xff;
x->selfpc[1] = (d >> 8) & 0xff;
x->selfpc[2] = (d >> 16) & 0xff;
}
static inline __attribute__((always_inline))void setcount(struct tostruct *x, size_t d) {
x->count[0] = d & 0xff;
x->count[1] = (d >> 8) & 0xff;
x->count[2] = (d >> 16) & 0xff;
}
static inline __attribute__((always_inline)) uint32_t getselfpc(const struct tostruct *x) {
return 0x10000000 | ((uint32_t)x->selfpc[0]) | (((uint32_t)x->selfpc[1]) << 8) | (((uint32_t)x->selfpc[2]) << 16);
}
static inline __attribute__((always_inline)) uint32_t getcount(const struct tostruct *x) {
return ((uint32_t)x->count[0]) | (((uint32_t)x->count[1]) << 8) | (((uint32_t)x->count[2]) << 16);
}
// Called by the GCC function shim (gprof_shim.S) on function entry to record an arc hit
void __no_inline_not_in_flash_func(_mcount_internal)(uint32_t *frompcindex, uint32_t *selfpc) {
register struct tostruct *top;
register struct tostruct *prevtop;
register long toindex;
struct gmonparam *p = &_gmonparam;
if (_perf_in_setup) {
// Avoid infinite recursion
return;
}
if (!already_setup) {
extern char __flash_binary_start; // Start of flash
extern char __etext; // End of .text
already_setup = true;
_perf_in_setup = true;
monstartup((uint32_t)&__flash_binary_start, (uint32_t)&__etext);
_perf_in_setup = false;
}
// Check that we are profiling and that we aren't recursively invoked.
if (p->state != GMON_PROF_ON) {
return;
}
p->state++;
// Check that frompcindex is a reasonable pc value.
frompcindex = (uint32_t*)((long)frompcindex - (long)p->lowpc);
if ((unsigned long)frompcindex > p->textsize) {
goto done;
}
frompcindex = (uint32_t*)&p->froms[((long)frompcindex) / (HASHFRACTION * sizeof(*p->froms))];
toindex = *((uint16_t*)frompcindex); // Get froms[] value
if (toindex == 0) {
// First time traversing this arc
toindex = ++p->tos[0].link; // The link of tos[0] points to the last used record in the array
if (toindex >= p->tolimit) { // More tos[] entries than we can handle!
goto overflow;
}
*((uint16_t*)frompcindex) = (uint16_t)toindex; // Store new 'to' value into froms[]
top = &p->tos[toindex];
setselfpc(top, (uint32_t)selfpc);
setcount(top, 1);
top->link = 0;
goto done;
}
top = &p->tos[toindex];
if (getselfpc(top) == (size_t)selfpc) {
// Arc at front of chain; usual case.
uint32_t cnt = getcount(top) + 1;
if (cnt >= 1 << 24) {
cnt = (1 << 24) - 1;
}
setcount(top, cnt);
goto done;
}
// Have to go looking down chain for it. top points to what we are looking at, prevtop points to previous top. We know it is not at the head of the chain.
for (; /* goto done */;) {
if (top->link == 0) {
// top is end of the chain and none of the chain had top->selfpc == selfpc, so we allocate a new tostruct and link it to the head of the chain.
toindex = ++p->tos[0].link;
if (toindex >= p->tolimit) {
goto overflow;
}
top = &p->tos[toindex];
setselfpc(top, (uint32_t)selfpc);
setcount(top, 1);
top->link = *((uint16_t*)frompcindex);
*(uint16_t*)frompcindex = (uint16_t)toindex;
goto done;
}
// Otherwise, check the next arc on the chain.
prevtop = top;
top = &p->tos[top->link];
if (getselfpc(top) == (size_t)selfpc) {
// Increment its count, move it to the head of the chain.
uint32_t cnt = getcount(top) + 1;
if (cnt >= 1 << 24) {
cnt = (1 << 24) - 1;
}
setcount(top, cnt);
toindex = prevtop->link;
prevtop->link = top->link;
top->link = *((uint16_t*)frompcindex);
*((uint16_t*)frompcindex) = (uint16_t)toindex;
goto done;
}
}
done:
p->state--;
return;
overflow:
p->state++; // Halt further profiling
return;
}
// Write out the GMON.OUT file using internal state
void _writeProfile(int (*writeCB)(const void *data, int len)) {
struct gmonhdr { // GMON.OUT header
size_t lpc; // base pc address of sample buffer
size_t hpc; // max pc address of sampled buffer
int ncnt; // size of sample buffer (plus this header)
int version; // version number
int profrate; // profiling clock rate
int spare[3]; // reserved
};
const unsigned int GMONVERSION = 0x00051879;
struct rawarc { // Per-arc on-disk data format
size_t raw_frompc;
size_t raw_selfpc;
long raw_count;
};
int fromindex;
int endfrom;
size_t frompc;
int toindex;
struct rawarc rawarc;
const int BS = 64;
struct rawarc rawarcbuff[BS];
int rawarcbuffptr = 0;
struct gmonparam *p = &_gmonparam;
struct gmonhdr hdr;
moncontrol(0); // Stop
hdr.lpc = p->lowpc;
hdr.hpc = p->highpc;
hdr.ncnt = p->kcountsize + sizeof(hdr);
hdr.version = GMONVERSION;
hdr.profrate = GMON_HZ;
writeCB((void *)&hdr, sizeof(hdr));
writeCB((void *)p->kcount, p->kcountsize);
endfrom = p->fromssize / sizeof(*p->froms);
for (fromindex = 0; fromindex < endfrom; fromindex++) {
if (p->froms[fromindex] == 0) {
continue;
}
frompc = p->lowpc;
frompc += fromindex * HASHFRACTION * sizeof(*p->froms);
for (toindex = p->froms[fromindex]; toindex != 0; toindex = p->tos[toindex].link) {
rawarc.raw_frompc = frompc;
rawarc.raw_selfpc = getselfpc(&p->tos[toindex]);
rawarc.raw_count = getcount(&p->tos[toindex]);
// Buffer up writes because Semihosting is really slow per write call
rawarcbuff[rawarcbuffptr++] = rawarc;
if (rawarcbuffptr == BS) {
writeCB((void *)rawarcbuff, BS * sizeof(struct rawarc));
rawarcbuffptr = 0;
}
}
}
// Write any remaining bits
if (rawarcbuffptr) {
writeCB((void *)rawarcbuff, rawarcbuffptr * sizeof(struct rawarc));
}
}
// These are referenced by RP2040Support.cpp and called by the runtime init SDK
// Install a periodic PC sampler at the specified frequency
#if defined(__riscv)
void runtime_init_setup_profiling() {
// TODO - is there an equivalent? Or do we need to build a timer IRQ here?
}
#else
#include <hardware/exception.h>
#include <hardware/structs/systick.h>
void runtime_init_setup_profiling() {
exception_set_exclusive_handler(SYSTICK_EXCEPTION, _SystickHandler);
systick_hw->csr = 0x7;
systick_hw->rvr = (F_CPU / GMON_HZ) - 1;
}
#endif

58
cores/rp2040/gprof_shim.S Normal file
View file

@ -0,0 +1,58 @@
#if defined(__riscv)
// Originally from https://github.com/sbzpro/riscv-gprof
# define RSIZE 4
.section .text
.align 2
.globl _mcount
_mcount:
addi sp,sp,-4*RSIZE
sw ra, 3*RSIZE(sp)
mv a1,ra
call _mcount_internal; //jal _mcount_internal
lw ra, 3*RSIZE(sp)
addi sp,sp,4*RSIZE
ret
#else
/*
* profiler.S
* Implements the gprof profiler arc counting function.
* Created on: 06.08.2015
* Author: Erich Styger
* Modified for RP2040/RP2350 on Dec 3 2024 by Earle F. Philhower, III.
*/
.syntax unified
.arch armv7-m
.cpu cortex-m0plus
.text
.thumb
.thumb_func
.align 2
.globl __gnu_mcount_nc
.type __gnu_mcount_nc, %function
.section .time_critical
__gnu_mcount_nc:
// LR = to return to
// SP = to-replace-LR with
push {r0, r1, r2, r3}
push {lr}
// Swap 24/0
ldr r0, [sp, #20]
ldr r1, [sp, #0]
str r0, [sp, #0]
str r1, [sp, #20]
mov r1, lr
ldr r0, [sp, #0] /* caller - at the top of the stack */
bl _mcount_internal /* when __gnu_mcount_nc is called */
pop {r0}
mov lr, r0
pop {r0, r1, r2, r3}
pop {pc}
.end __gnu_mcount_nc
#endif

View file

@ -80,7 +80,7 @@ static SemaphoreHandle_t __getFreeRTOSMutex(_LOCK_T lock) {
} else if (l == &__lock___arc4random_mutex) {
return __lock___arc4random_mutex_freertos;
}
return nullptr;
return __get_freertos_mutex_for_ptr(l, false);
}
static SemaphoreHandle_t __getFreeRTOSRecursiveMutex(_LOCK_T lock) {
@ -96,20 +96,32 @@ static SemaphoreHandle_t __getFreeRTOSRecursiveMutex(_LOCK_T lock) {
} else if (l == &__lock___env_recursive_mutex) {
return __lock___env_recursive_mutex_freertos;
}
return nullptr;
return __get_freertos_mutex_for_ptr((mutex_t *)l, true);
}
void __retarget_lock_init(_LOCK_T *lock) {
void __retarget_lock_init(_LOCK_T lock) {
if (__freeRTOSinitted) {
/* Already done in initFreeRTOSMutexes() */
mutex_t *l = (mutex_t *)lock;
if ((l == &__lock___at_quick_exit_mutex) || (l == &__lock___tz_mutex) || (l == &__lock___dd_hash_mutex) || (l == &__lock___arc4random_mutex)) {
/* Already done in initFreeRTOSMutexes() */
} else {
// Will init the mutex as well
__get_freertos_mutex_for_ptr(l, false);
}
} else {
mutex_init((mutex_t*) lock);
}
}
void __retarget_lock_init_recursive(_LOCK_T *lock) {
void __retarget_lock_init_recursive(_LOCK_T lock) {
if (__freeRTOSinitted) {
/* Already done in initFreeRTOSMutexes() */
recursive_mutex_t *l = (recursive_mutex_t *)lock;
if ((l == &__lock___sinit_recursive_mutex) || (l == &__lock___sfp_recursive_mutex) || (l == &__lock___atexit_recursive_mutex) || (l == &__lock___malloc_recursive_mutex) || (l == &__lock___env_recursive_mutex)) {
/* Already done in initFreeRTOSMutexes() */
} else {
// Will init the mutex as well
__get_freertos_mutex_for_ptr((mutex_t *)l, true);
}
} else {
recursive_mutex_init((recursive_mutex_t*) lock);
}

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,48 +18,82 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "pico/mutex.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include "lwip/dns.h"
#include "lwip/raw.h"
#include "lwip/timeouts.h"
#include <Arduino.h>
#include <pico/mutex.h>
#include <lwip/pbuf.h>
#include <lwip/udp.h>
#include <lwip/tcp.h>
#include <lwip/dns.h>
#include <lwip/raw.h>
#include <lwip/timeouts.h>
#include <pico/cyw43_arch.h>
#include <pico/mutex.h>
#include <sys/lock.h>
#include "_xoshiro.h"
// Global indicator that we're inside an LWIP block
extern "C" {
volatile bool __inLWIP = false;
}
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(__mtxLWIP);
auto_init_recursive_mutex(__lwipMutex); // Only for case with no Ethernet or PicoW, but still doing LWIP (PPP?)
class LWIPMutex {
public:
LWIPMutex() {
noInterrupts();
recursive_mutex_enter_blocking(&__mtxLWIP);
__inLWIP = true;
_ref++;
interrupts();
if (ethernet_arch_lwip_gpio_mask) {
ethernet_arch_lwip_gpio_mask();
}
#if defined(PICO_CYW43_SUPPORTED)
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() {
noInterrupts();
if (0 == --_ref) {
__inLWIP = false;
#if defined(PICO_CYW43_SUPPORTED)
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(PICO_CYW43_SUPPORTED)
}
#endif
if (ethernet_arch_lwip_gpio_unmask) {
ethernet_arch_lwip_gpio_unmask();
}
recursive_mutex_exit(&__mtxLWIP);
interrupts();
}
private:
static int _ref;
};
int LWIPMutex::_ref = 0;
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;
@ -213,19 +247,19 @@ extern "C" {
extern void __real_tcp_setprio(struct tcp_pcb *pcb, u8_t prio);
void __wrap_tcp_setprio(struct tcp_pcb *pcb, u8_t prio) {
LWIPMutex m;
return __real_tcp_setprio(pcb, prio);
__real_tcp_setprio(pcb, prio);
}
extern void __real_tcp_backlog_delayed(struct tcp_pcb* pcb);
void __wrap_tcp_backlog_delayed(struct tcp_pcb* pcb) {
LWIPMutex m;
return __real_tcp_backlog_delayed(pcb);
__real_tcp_backlog_delayed(pcb);
}
extern void __real_tcp_backlog_accepted(struct tcp_pcb* pcb);
void __wrap_tcp_backlog_accepted(struct tcp_pcb* pcb) {
LWIPMutex m;
return __real_tcp_backlog_accepted(pcb);
__real_tcp_backlog_accepted(pcb);
}
extern struct udp_pcb *__real_udp_new(void);
struct udp_pcb *__wrap_udp_new(void) {
@ -275,7 +309,8 @@ extern "C" {
return __real_udp_sendto_if(pcb, p, dst_ip, dst_port, netif);
}
extern void __real_sys_check_timeouts(void);
// sys_check_timeouts is special case because the async process will call it. If we're already in a timeout check, just do a noop
extern void __real_sys_check_timeouts();
void __wrap_sys_check_timeouts(void) {
LWIPMutex m;
__real_sys_check_timeouts();
@ -323,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"

View file

@ -22,16 +22,18 @@
#include "RP2040USB.h"
#include <pico/stdlib.h>
#include <pico/multicore.h>
#include <hardware/vreg.h>
#include <reent.h>
#ifdef RP2350_PSRAM_CS
#include "psram.h"
#endif
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,15 +43,22 @@ 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;
bool core1_disable_systick __attribute__((weak)) = false;
extern void setup1() __attribute__((weak));
extern void loop1() __attribute__((weak));
extern "C" void main1() {
if (!core1_disable_systick) {
// Don't install the SYSTICK exception handler. rp2040.getCycleCount will not work properly on core1
rp2040.begin(1);
}
rp2040.fifo.registerCore();
if (setup1) {
setup1();
@ -79,22 +88,52 @@ extern void __loop() {
static struct _reent *_impure_ptr1 = nullptr;
extern "C" int main() {
#if F_CPU != 125000000
set_sys_clock_khz(F_CPU / 1000, true);
#if (defined(PICO_RP2040) && (F_CPU != 125000000)) || (defined(PICO_RP2350) && (F_CPU != 150000000))
#if defined(PICO_RP2040)
// From runtime_init_clocks() to bump up RP2040 V for 200Mhz+ operation
if ((F_CPU > 133000000) && (vreg_get_voltage() < VREG_VOLTAGE_1_15)) {
vreg_set_voltage(VREG_VOLTAGE_1_15);
// wait for voltage to settle; must use CPU cycles as TIMER is not yet clocked correctly
busy_wait_at_least_cycles((uint32_t)((SYS_CLK_VREG_VOLTAGE_AUTO_ADJUST_DELAY_US * (uint64_t)XOSC_HZ) / 1000000));
}
#endif
#if defined(RP2350_PSRAM_CS) && (F_CPU > 150000000)
// Need to increase the qmi divider before upping sysclk to ensure we keep the output sck w/in legal bounds
psram_reinit_timing(F_CPU);
// Per datasheet, need to do a dummy access and memory barrier before it takes effect
extern uint8_t __psram_start__;
volatile uint8_t *x = &__psram_start__;
*x ^= 0xff;
*x ^= 0xff;
asm volatile("" ::: "memory");
#endif
set_sys_clock_khz(F_CPU / 1000, true);
#if defined(RP2350_PSRAM_CS) && (F_CPU < 150000000)
psram_reinit_timing();
// Per datasheet, need to do a dummy access and memory barrier before it takes effect
extern uint8_t __psram_start__;
volatile uint8_t *x = &__psram_start__;
*x ^= 0xff;
*x ^= 0xff;
asm volatile("" ::: "memory");
#endif
#endif // over/underclock
// Let rest of core know if we're using FreeRTOS
__isFreeRTOS = initFreeRTOS ? true : false;
// Allocate impure_ptr (newlib temps) if there is a 2nd core running
if (!__isFreeRTOS && (setup1 || loop1)) {
_impure_ptr1 = (struct _reent*)calloc(sizeof(struct _reent), 1);
_impure_ptr1 = (struct _reent*)calloc(1, sizeof(struct _reent));
_REENT_INIT_PTR(_impure_ptr1);
}
mutex_init(&_pioMutex);
rp2040.begin();
rp2040.begin(0);
initVariant();
@ -122,6 +161,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
@ -133,11 +175,15 @@ extern "C" int main() {
}
rp2040.fifo.registerCore();
}
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 +209,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;
@ -197,3 +244,10 @@ void hexdump(const void* mem, uint32_t len, uint8_t cols) {
}
const String emptyString = "";
extern "C" void __attribute__((__noreturn__)) __wrap___stack_chk_fail() {
while (true) {
panic("*** stack smashing detected ***: terminated\n");
}
}

View file

@ -19,11 +19,25 @@
*/
#include <Arduino.h>
#include <malloc.h>
#include <reent.h>
#include "psram.h"
extern "C" void *__real_malloc(size_t size);
extern "C" void *__real_calloc(size_t count, size_t size);
extern "C" void *__real_realloc(void *mem, size_t size);
extern "C" void __real_free(void *mem);
extern "C" struct mallinfo __real_mallinfo();
#ifdef RP2350_PSRAM_CS
extern "C" {
extern uint8_t __psram_start__;
extern uint8_t __psram_heap_start__;
void __malloc_lock(struct _reent *ptr);
void __malloc_unlock(struct _reent *ptr);
static void *__ram_start = (void *)0x20000000; // TODO - Is there a SDK exposed variable/macro?
}
#endif
extern "C" void *__wrap_malloc(size_t size) {
noInterrupts();
@ -39,15 +53,75 @@ extern "C" void *__wrap_calloc(size_t count, size_t size) {
return rc;
}
extern "C" void *__wrap_realloc(void *mem, size_t size) {
#ifdef RP2350_PSRAM_CS
// Utilize the existing malloc lock infrastructure and interrupt blocking
// to work with multicore and FreeRTOS
extern "C" void *pmalloc(size_t size) {
noInterrupts();
void *rc = __real_realloc(mem, size);
__malloc_lock(__getreent());
auto rc = __psram_malloc(size);
__malloc_unlock(__getreent());
interrupts();
return rc;
}
extern "C" void *pcalloc(size_t count, size_t size) {
noInterrupts();
__malloc_lock(__getreent());
auto rc = __psram_calloc(count, size);
__malloc_unlock(__getreent());
interrupts();
return rc;
}
#else
// No PSRAM, always fail
extern "C" void *pmalloc(size_t size) {
(void) size;
return nullptr;
}
extern "C" void *pcalloc(size_t count, size_t size) {
(void) count;
(void) size;
return nullptr;
}
#endif
extern "C" void *__wrap_realloc(void *mem, size_t size) {
void *rc;
noInterrupts();
#ifdef RP2350_PSRAM_CS
if (mem && (mem < __ram_start)) {
rc = __psram_realloc(mem, size);
} else {
rc = __real_realloc(mem, size);
}
#else
rc = __real_realloc(mem, size);
#endif
interrupts();
return rc;
}
extern "C" void __wrap_free(void *mem) {
noInterrupts();
#ifdef RP2350_PSRAM_CS
if (mem && (mem < __ram_start)) {
__psram_free(mem);
} else {
__real_free(mem);
}
#else
__real_free(mem);
#endif
interrupts();
}
extern "C" struct mallinfo __wrap_mallinfo() {
noInterrupts();
__malloc_lock(__getreent());
auto ret = __real_mallinfo();
__malloc_unlock(__getreent());
interrupts();
return ret;
}

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:
@ -39,15 +39,13 @@ 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) {
// Tell PIO to initially drive output-high on the selected pin, then map PIO
// onto that pin with the IO muxes.
pio_sm_set_pins_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
pio_sm_set_pindirs_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
pio_sm_set_set_pins(pio, sm, pin_tx, 1);
pio_sm_set_consecutive_pindirs(pio, sm, pin_tx, 1, true);
pio_gpio_init(pio, pin_tx);
pio_sm_config c = pio_tx_program_get_default_config(offset);
@ -68,28 +66,32 @@ static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_t
}
%}
.program pio_rx
; 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)
set x, 18 ; Preload bit counter...overwritten by the app
wait 0 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
wait_mid_start:
jmp y-- wait_mid_start
; 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
bitloop:
mov y, osr
bitloop1:
jmp y-- bitloop1
mov y, osr
bitloop2:
jmp y-- bitloop2
in pins, 1
jmp x-- bitloop
push
% c-sdk {
static inline void pio_rx_program_init(PIO pio, uint sm, uint offset, uint pin) {

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
@ -12,6 +14,7 @@
#define pio_tx_wrap_target 0
#define pio_tx_wrap 5
#define pio_tx_pio_version 0
static const uint16_t pio_tx_program_instructions[] = {
// .wrap_target
@ -29,6 +32,10 @@ static const struct pio_program pio_tx_program = {
.instructions = pio_tx_program_instructions,
.length = 6,
.origin = -1,
.pio_version = pio_tx_pio_version,
#if PICO_PIO_VERSION > 0
.used_gpio_ranges = 0x0
#endif
};
static inline pio_sm_config pio_tx_program_get_default_config(uint offset) {
@ -41,8 +48,8 @@ static inline pio_sm_config pio_tx_program_get_default_config(uint offset) {
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
// onto that pin with the IO muxes.
pio_sm_set_pins_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
pio_sm_set_pindirs_with_mask(pio, sm, 1u << pin_tx, 1u << pin_tx);
pio_sm_set_set_pins(pio, sm, pin_tx, 1);
pio_sm_set_consecutive_pindirs(pio, sm, pin_tx, 1, true);
pio_gpio_init(pio, pin_tx);
pio_sm_config c = pio_tx_program_get_default_config(offset);
// OUT shifts to right, no autopull
@ -64,7 +71,8 @@ static inline void pio_tx_program_init(PIO pio, uint sm, uint offset, uint pin_t
// ------ //
#define pio_rx_wrap_target 0
#define pio_rx_wrap 6
#define pio_rx_wrap 10
#define pio_rx_pio_version 0
static const uint16_t pio_rx_program_instructions[] = {
// .wrap_target
@ -72,17 +80,25 @@ static const uint16_t pio_rx_program_instructions[] = {
0x2020, // 1: wait 0 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
0xa047, // 4: mov y, osr
0x0085, // 5: jmp y--, 5
0xa047, // 6: mov y, osr
0x0087, // 7: jmp y--, 7
0x4001, // 8: in pins, 1
0x0044, // 9: jmp x--, 4
0x8020, // 10: push block
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program pio_rx_program = {
.instructions = pio_rx_program_instructions,
.length = 7,
.length = 11,
.origin = -1,
.pio_version = pio_rx_pio_version,
#if PICO_PIO_VERSION > 0
.used_gpio_ranges = 0x0
#endif
};
static inline pio_sm_config pio_rx_program_get_default_config(uint offset) {

View file

@ -23,6 +23,7 @@
#include <errno.h>
#include <_syslist.h>
#include <sys/times.h>
#include <sys/unistd.h>
#include <pico/stdlib.h>
#include <pico/multicore.h>
@ -33,7 +34,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 +48,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 +58,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 +79,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 +124,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 +139,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 +158,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 +168,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 +178,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 +188,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 +212,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;

437
cores/rp2040/psram.cpp Normal file
View file

@ -0,0 +1,437 @@
// Originally from https://github.com/sparkfun/sparkfun-pico
/**
@file sfe_psram.c
@brief This file contains a function that is used to detect and initialize PSRAM on
SparkFun rp2350 boards.
*/
/*
The MIT License (MIT)
Copyright (c) 2024 SparkFun Electronics
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions: The
above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// Hacked by Earle Philhower to work with the Arduino-Pico core
#include <Arduino.h>
#ifdef RP2350_PSRAM_CS
#include <hardware/address_mapped.h>
#include <hardware/clocks.h>
#include <hardware/gpio.h>
#include <hardware/regs/addressmap.h>
#include <hardware/spi.h>
#include <hardware/structs/qmi.h>
#include <hardware/structs/xip_ctrl.h>
#include <pico/runtime_init.h>
// Include TLSF in this compilation unit
#include "../../lib/tlsf/tlsf.c"
static tlsf_t _mem_heap = nullptr;
static pool_t _mem_psram_pool = nullptr;
// PSRAM heap minus PSRAM global/static variables from the linker
extern "C" {
extern uint8_t __psram_start__;
extern uint8_t __psram_heap_start__;
}
static bool _bInitalized = false;
size_t __psram_size = 0;
size_t __psram_heap_size = 0;
#define PICO_RUNTIME_INIT_PSRAM "11001" // Towards the end, after alarms
#ifndef RP2350_PSRAM_MAX_SELECT_FS64
#define RP2350_PSRAM_MAX_SELECT_FS64 (125'000'000)
#endif
#ifndef RP2350_PSRAM_MIN_DESELECT_FS
#define RP2350_PSRAM_MIN_DESELECT_FS (50'000'000)
#endif
#ifndef RP2350_PSRAM_MAX_SCK_HZ
#define RP2350_PSRAM_MAX_SCK_HZ (109'000'000)
#endif
#ifndef RP2350_PSRAM_ID
#define RP2350_PSRAM_ID (0x5D)
#endif
// DETAILS/
//
// SparkFun RP2350 boards use the following PSRAM IC:
//
// apmemory APS6404L-3SQR-ZR
// https://www.mouser.com/ProductDetail/AP-Memory/APS6404L-3SQR-ZR?qs=IS%252B4QmGtzzpDOdsCIglviw%3D%3D
//
// The origin of this logic is from the Circuit Python code that was downloaded from:
// https://github.com/raspberrypi/pico-sdk-rp2350/issues/12#issuecomment-2055274428
//
// Details on the PSRAM IC that are used during setup/configuration of PSRAM on SparkFun RP2350 boards.
// For PSRAM timing calculations - to use int math, we work in femto seconds (fs) (1e-15),
// NOTE: This idea is from micro python work on psram..
#define SFE_SEC_TO_FS 1000000000000000ll
// max select pulse width = 8us => 8e6 ns => 8000 ns => 8000 * 1e6 fs => 8000e6 fs
// Additionally, the MAX select is in units of 64 clock cycles - will use a constant that
// takes this into account - so 8000e6 fs / 64 = 125e6 fs
const uint32_t SFE_PSRAM_MAX_SELECT_FS64 = RP2350_PSRAM_MAX_SELECT_FS64;
// min deselect pulse width = 50ns => 50 * 1e6 fs => 50e7 fs
const uint32_t SFE_PSRAM_MIN_DESELECT_FS = RP2350_PSRAM_MIN_DESELECT_FS;
// from psram datasheet - max Freq with VDDat 3.3v - SparkFun RP2350 boards run at 3.3v.
// If VDD = 3.0 Max Freq is 133 Mhz
const uint32_t SFE_PSRAM_MAX_SCK_HZ = RP2350_PSRAM_MAX_SCK_HZ;
// PSRAM SPI command codes
const uint8_t PSRAM_CMD_QUAD_END = 0xF5;
const uint8_t PSRAM_CMD_QUAD_ENABLE = 0x35;
const uint8_t PSRAM_CMD_READ_ID = 0x9F;
const uint8_t PSRAM_CMD_RSTEN = 0x66;
const uint8_t PSRAM_CMD_RST = 0x99;
const uint8_t PSRAM_CMD_QUAD_READ = 0xEB;
const uint8_t PSRAM_CMD_QUAD_WRITE = 0x38;
const uint8_t PSRAM_CMD_NOOP = 0xFF;
const uint8_t PSRAM_ID = RP2350_PSRAM_ID;
//-----------------------------------------------------------------------------
/// @brief Communicate directly with the PSRAM IC - validate it is present and return the size
///
/// @return size_t The size of the PSRAM
///
/// @note This function expects the CS pin set
static size_t __no_inline_not_in_flash_func(get_psram_size)(void) {
size_t psram_size = 0;
uint32_t intr_stash = save_and_disable_interrupts();
// Try and read the PSRAM ID via direct_csr.
qmi_hw->direct_csr = 30 << QMI_DIRECT_CSR_CLKDIV_LSB | QMI_DIRECT_CSR_EN_BITS;
// Need to poll for the cooldown on the last XIP transfer to expire
// (via direct-mode BUSY flag) before it is safe to perform the first
// direct-mode operation
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
}
// Exit out of QMI in case we've inited already
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
// Transmit the command to exit QPI quad mode - read ID as standard SPI
qmi_hw->direct_tx =
QMI_DIRECT_TX_OE_BITS | QMI_DIRECT_TX_IWIDTH_VALUE_Q << QMI_DIRECT_TX_IWIDTH_LSB | PSRAM_CMD_QUAD_END;
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
}
(void)qmi_hw->direct_rx;
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS);
// Read the id
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
uint8_t kgd = 0;
uint8_t eid = 0;
for (size_t i = 0; i < 7; i++) {
qmi_hw->direct_tx = (i == 0 ? PSRAM_CMD_READ_ID : PSRAM_CMD_NOOP);
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_TXEMPTY_BITS) == 0) {
}
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
}
if (i == 5) {
kgd = qmi_hw->direct_rx;
} else if (i == 6) {
eid = qmi_hw->direct_rx;
} else {
(void)qmi_hw->direct_rx; // just read and discard
}
}
// Disable direct csr.
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS | QMI_DIRECT_CSR_EN_BITS);
// is this the PSRAM we're looking for obi-wan?
if (kgd == PSRAM_ID) {
// PSRAM size
psram_size = 1024 * 1024; // 1 MiB
uint8_t size_id = eid >> 5;
if (eid == 0x26 || size_id == 2) {
psram_size *= 8;
} else if (size_id == 0) {
psram_size *= 2;
} else if (size_id == 1) {
psram_size *= 4;
}
}
restore_interrupts(intr_stash);
return psram_size;
}
//-----------------------------------------------------------------------------
/// @brief Update the PSRAM timing configuration based on system clock
///
/// @note This function expects interrupts to be enabled on entry
static void __no_inline_not_in_flash_func(set_psram_timing)(uint32_t sysHz) {
// Calculate the clock divider - goal to get clock used for PSRAM <= what
// the PSRAM IC can handle - which is defined in SFE_PSRAM_MAX_SCK_HZ
volatile uint8_t clockDivider = (sysHz + SFE_PSRAM_MAX_SCK_HZ - 1) / SFE_PSRAM_MAX_SCK_HZ;
uint32_t intr_stash = save_and_disable_interrupts();
// Get the clock femto seconds per cycle.
uint32_t fsPerCycle = SFE_SEC_TO_FS / sysHz;
// the maxSelect value is defined in units of 64 clock cycles
// So maxFS / (64 * fsPerCycle) = maxSelect = SFE_PSRAM_MAX_SELECT_FS64/fsPerCycle
volatile uint8_t maxSelect = SFE_PSRAM_MAX_SELECT_FS64 / fsPerCycle;
// minDeselect time - in system clock cycle
// Must be higher than 50ns (min deselect time for PSRAM) so add a fsPerCycle - 1 to round up
// So minFS/fsPerCycle = minDeselect = SFE_PSRAM_MIN_DESELECT_FS/fsPerCycle
volatile uint8_t minDeselect = (SFE_PSRAM_MIN_DESELECT_FS + fsPerCycle - 1) / fsPerCycle;
// printf("Max Select: %d, Min Deselect: %d, clock divider: %d\n", maxSelect, minDeselect, clockDivider);
qmi_hw->m[1].timing = QMI_M1_TIMING_PAGEBREAK_VALUE_1024 << QMI_M1_TIMING_PAGEBREAK_LSB | // Break between pages.
3 << QMI_M1_TIMING_SELECT_HOLD_LSB | // Delay releasing CS for 3 extra system cycles.
1 << QMI_M1_TIMING_COOLDOWN_LSB | 1 << QMI_M1_TIMING_RXDELAY_LSB |
maxSelect << QMI_M1_TIMING_MAX_SELECT_LSB | minDeselect << QMI_M1_TIMING_MIN_DESELECT_LSB |
clockDivider << QMI_M1_TIMING_CLKDIV_LSB;
restore_interrupts(intr_stash);
}
//-----------------------------------------------------------------------------
/// @brief The setup_psram function - note that this is not in flash
///
///
static void __no_inline_not_in_flash_func(runtime_init_setup_psram)(/*uint32_t psram_cs_pin*/) {
// Set the PSRAM CS pin in the SDK
gpio_set_function(RP2350_PSRAM_CS, GPIO_FUNC_XIP_CS1);
// start with zero size
size_t psram_size = get_psram_size();
// No PSRAM - no dice
if (psram_size == 0) {
return;
}
uint32_t intr_stash = save_and_disable_interrupts();
// Enable quad mode.
qmi_hw->direct_csr = 30 << QMI_DIRECT_CSR_CLKDIV_LSB | QMI_DIRECT_CSR_EN_BITS;
// Need to poll for the cooldown on the last XIP transfer to expire
// (via direct-mode BUSY flag) before it is safe to perform the first
// direct-mode operation
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
}
// RESETEN, RESET and quad enable
for (uint8_t i = 0; i < 3; i++) {
qmi_hw->direct_csr |= QMI_DIRECT_CSR_ASSERT_CS1N_BITS;
if (i == 0) {
qmi_hw->direct_tx = PSRAM_CMD_RSTEN;
} else if (i == 1) {
qmi_hw->direct_tx = PSRAM_CMD_RST;
} else {
qmi_hw->direct_tx = PSRAM_CMD_QUAD_ENABLE;
}
while ((qmi_hw->direct_csr & QMI_DIRECT_CSR_BUSY_BITS) != 0) {
}
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS);
for (size_t j = 0; j < 20; j++) {
asm("nop");
}
(void)qmi_hw->direct_rx;
}
// Disable direct csr.
qmi_hw->direct_csr &= ~(QMI_DIRECT_CSR_ASSERT_CS1N_BITS | QMI_DIRECT_CSR_EN_BITS);
// check our interrupts and setup the timing
restore_interrupts(intr_stash);
set_psram_timing((uint32_t)clock_get_hz(clk_sys));
// and now stash interrupts again
intr_stash = save_and_disable_interrupts();
qmi_hw->m[1].rfmt = (QMI_M1_RFMT_PREFIX_WIDTH_VALUE_Q << QMI_M1_RFMT_PREFIX_WIDTH_LSB |
QMI_M1_RFMT_ADDR_WIDTH_VALUE_Q << QMI_M1_RFMT_ADDR_WIDTH_LSB |
QMI_M1_RFMT_SUFFIX_WIDTH_VALUE_Q << QMI_M1_RFMT_SUFFIX_WIDTH_LSB |
QMI_M1_RFMT_DUMMY_WIDTH_VALUE_Q << QMI_M1_RFMT_DUMMY_WIDTH_LSB |
QMI_M1_RFMT_DUMMY_LEN_VALUE_24 << QMI_M1_RFMT_DUMMY_LEN_LSB |
QMI_M1_RFMT_DATA_WIDTH_VALUE_Q << QMI_M1_RFMT_DATA_WIDTH_LSB |
QMI_M1_RFMT_PREFIX_LEN_VALUE_8 << QMI_M1_RFMT_PREFIX_LEN_LSB |
QMI_M1_RFMT_SUFFIX_LEN_VALUE_NONE << QMI_M1_RFMT_SUFFIX_LEN_LSB);
qmi_hw->m[1].rcmd = PSRAM_CMD_QUAD_READ << QMI_M1_RCMD_PREFIX_LSB | 0 << QMI_M1_RCMD_SUFFIX_LSB;
qmi_hw->m[1].wfmt = (QMI_M1_WFMT_PREFIX_WIDTH_VALUE_Q << QMI_M1_WFMT_PREFIX_WIDTH_LSB |
QMI_M1_WFMT_ADDR_WIDTH_VALUE_Q << QMI_M1_WFMT_ADDR_WIDTH_LSB |
QMI_M1_WFMT_SUFFIX_WIDTH_VALUE_Q << QMI_M1_WFMT_SUFFIX_WIDTH_LSB |
QMI_M1_WFMT_DUMMY_WIDTH_VALUE_Q << QMI_M1_WFMT_DUMMY_WIDTH_LSB |
QMI_M1_WFMT_DUMMY_LEN_VALUE_NONE << QMI_M1_WFMT_DUMMY_LEN_LSB |
QMI_M1_WFMT_DATA_WIDTH_VALUE_Q << QMI_M1_WFMT_DATA_WIDTH_LSB |
QMI_M1_WFMT_PREFIX_LEN_VALUE_8 << QMI_M1_WFMT_PREFIX_LEN_LSB |
QMI_M1_WFMT_SUFFIX_LEN_VALUE_NONE << QMI_M1_WFMT_SUFFIX_LEN_LSB);
qmi_hw->m[1].wcmd = PSRAM_CMD_QUAD_WRITE << QMI_M1_WCMD_PREFIX_LSB | 0 << QMI_M1_WCMD_SUFFIX_LSB;
// Mark that we can write to PSRAM.
xip_ctrl_hw->ctrl |= XIP_CTRL_WRITABLE_M1_BITS;
restore_interrupts(intr_stash);
__psram_size = psram_size;
uint32_t used_psram_size = &__psram_heap_start__ - &__psram_start__;
__psram_heap_size = __psram_size - used_psram_size;
}
PICO_RUNTIME_INIT_FUNC_RUNTIME(runtime_init_setup_psram, PICO_RUNTIME_INIT_PSRAM);
// update timing -- used if the system clock/timing was changed.
void psram_reinit_timing(uint32_t hz) {
if (!hz) {
hz = (uint32_t)clock_get_hz(clk_sys);
}
set_psram_timing(hz);
}
static bool __psram_heap_init() {
if (_bInitalized) {
return true;
}
if (!__psram_heap_size) {
return false;
}
_mem_heap = NULL;
_mem_psram_pool = NULL;
_mem_heap = tlsf_create_with_pool((void *)&__psram_heap_start__, __psram_heap_size, 16 * 1024 * 1024);
if (!_mem_heap) {
return false;
}
_mem_psram_pool = tlsf_get_pool(_mem_heap);
if (!_mem_psram_pool) {
return false;
}
_bInitalized = true;
return true;
}
void *__psram_malloc(size_t size) {
if (!__psram_heap_init() || !_mem_heap) {
return NULL;
}
return tlsf_malloc(_mem_heap, size);
}
void __psram_free(void *ptr) {
if (!__psram_heap_init() || !_mem_heap) {
return;
}
tlsf_free(_mem_heap, ptr);
}
void *__psram_realloc(void *ptr, size_t size) {
if (!__psram_heap_init() || !_mem_heap) {
return NULL;
}
return tlsf_realloc(_mem_heap, ptr, size);
}
void *__psram_calloc(size_t num, size_t size) {
if (!__psram_heap_init() || !_mem_heap) {
return NULL;
}
void *ptr = tlsf_malloc(_mem_heap, num * size);
if (ptr) {
bzero(ptr, num * size);
}
return ptr;
}
static bool max_free_walker(void *ptr, size_t size, int used, void *user) {
size_t *max_size = (size_t *)user;
if (!used && *max_size < size) {
*max_size = size;
}
return true;
}
size_t __psram_largest_free_block() {
if (!__psram_heap_init() || !_mem_heap) {
return 0;
}
size_t max_free = 0;
if (_mem_psram_pool) {
tlsf_walk_pool(_mem_psram_pool, max_free_walker, &max_free);
}
return max_free;
}
static bool memory_size_walker(void *ptr, size_t size, int used, void *user) {
*((size_t *)user) += size;
return true;
}
size_t __psram_total_space() {
if (!__psram_heap_init() || !_mem_heap) {
return 0;
}
size_t total_size = 0;
if (_mem_psram_pool) {
tlsf_walk_pool(_mem_psram_pool, memory_size_walker, &total_size);
}
return total_size;
}
static bool memory_used_walker(void *ptr, size_t size, int used, void *user) {
if (used) {
*((size_t *)user) += size;
}
return true;
}
size_t __psram_total_used() {
if (!__psram_heap_init() || !_mem_heap) {
return 0;
}
size_t total_size = 0;
if (_mem_psram_pool) {
tlsf_walk_pool(_mem_psram_pool, memory_used_walker, &total_size);
}
return total_size;
}
#endif // RP2350_PSRAM_CS

41
cores/rp2040/psram.h Normal file
View file

@ -0,0 +1,41 @@
/**
@file sfe_psram.c
@brief This file contains a function that is used to detect and initialize PSRAM on
SparkFun rp2350 boards.
*/
/*
The MIT License (MIT)
Copyright (c) 2024 SparkFun Electronics
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions: The
above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED
"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <Arduino.h>
void psram_reinit_timing(uint32_t hz = 0);
void *__psram_malloc(size_t size);
void __psram_free(void *ptr);
void *__psram_realloc(void *ptr, size_t size);
void *__psram_calloc(size_t num, size_t size);
size_t __psram_largest_free_block();
size_t __psram_total_space();
size_t __psram_total_used();

View file

@ -0,0 +1,383 @@
/*
* Copyright (c) 2011 ARM Ltd
* 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 company may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
*/
#if defined(PICO_RP2350) && defined(__arm__)
/* Prototype: void *memcpy (void *dst, const void *src, size_t count). */
/* Use the version of memcpy implemented using LDRD and STRD.
This version is tuned for Cortex-A15.
This might not be the best for other ARMv7-A CPUs,
but there is no predefine to distinguish between
different CPUs in the same architecture,
and this version is better than the plain memcpy provided in newlib.
Therefore, we use this version for all ARMv7-A CPUS. */
/* To make the same code compile for both ARM and Thumb instruction
sets, switch to unified syntax at the beginning of this function.
However, by using the same code, we may be missing optimization
opportunities. For instance, in LDRD/STRD instructions, the first
destination register must be even and the second consecutive in
ARM state, but not in Thumb state. */
.syntax unified
#if defined (__thumb__)
.thumb
.thumb_func
#endif
#ifdef __native_client__
#define SFI_BREG(reg) sfi_breg reg,
#define IT(insn)
#ifdef __thumb__
#error "thumb and native_client are not compatible!"
#endif
.p2align 4
#else
#define SFI_BREG(reg)
#define IT(insn) insn
#endif
.global __wrap_memcpy
.type __wrap_memcpy, %function
// .section .time_critical.memcpy // Actually slows down a bit because RAM and program RAM conflict
__wrap_memcpy:
/* Assumes that n >= 0, and dst, src are valid pointers.
If there is at least 8 bytes to copy, use LDRD/STRD.
If src and dst are misaligned with different offsets,
first copy byte by byte until dst is aligned,
and then copy using LDRD/STRD and shift if needed.
When less than 8 left, copy a word and then byte by byte. */
/* Save registers (r0 holds the return value):
optimized push {r0, r4, r5, lr}.
To try and improve performance, stack layout changed,
i.e., not keeping the stack looking like users expect
(highest numbered register at highest address). */
push {r0, lr}
strd r4, r5, [sp, #-8]!
/* TODO: Add debug frame directives.
We don't need exception unwind directives, because the code below
does not throw any exceptions and does not call any other functions.
Generally, newlib functions like this lack debug information for
assembler source. */
/* Get copying of tiny blocks out of the way first. */
/* Is there at least 4 bytes to copy? */
subs r2, r2, #4
blt copy_less_than_4 /* If n < 4. */
/* Check word alignment. */
ands ip, r0, #3 /* ip = last 2 bits of dst. */
bne dst_not_word_aligned /* If dst is not word-aligned. */
/* Get here if dst is word-aligned. */
ands ip, r1, #3 /* ip = last 2 bits of src. */
bne src_not_word_aligned /* If src is not word-aligned. */
word_aligned:
/* Get here if source and dst both are word-aligned.
The number of bytes remaining to copy is r2+4. */
/* Is there is at least 64 bytes to copy? */
subs r2, r2, #60
blt copy_less_than_64 /* If r2 + 4 < 64. */
/* First, align the destination buffer to 8-bytes,
to make sure double loads and stores don't cross cache line boundary,
as they are then more expensive even if the data is in the cache
(require two load/store issue cycles instead of one).
If only one of the buffers is not 8-bytes aligned,
then it's more important to align dst than src,
because there is more penalty for stores
than loads that cross cacheline boundary.
This check and realignment are only worth doing
if there is a lot to copy. */
/* Get here if dst is word aligned,
i.e., the 2 least significant bits are 0.
If dst is not 2w aligned (i.e., the 3rd bit is not set in dst),
then copy 1 word (4 bytes). */
ands r3, r0, #4
beq 11f /* If dst already two-word aligned. */
SFI_BREG(r1) \
ldr r3, [r1], #4
SFI_BREG(r0) \
str r3, [r0], #4
subs r2, r2, #4
blt copy_less_than_64
11:
/* TODO: Align to cacheline (useful for PLD optimization). */
/* Every loop iteration copies 64 bytes. */
1:
.irp offset, #0, #8, #16, #24, #32, #40, #48, #56
SFI_BREG(r1) \
ldrd r4, r5, [r1, \offset]
SFI_BREG(r0) \
strd r4, r5, [r0, \offset]
.endr
add r0, r0, #64
add r1, r1, #64
subs r2, r2, #64
bge 1b /* If there is more to copy. */
copy_less_than_64:
/* Get here if less than 64 bytes to copy, -64 <= r2 < 0.
Restore the count if there is more than 7 bytes to copy. */
adds r2, r2, #56
blt copy_less_than_8
/* Copy 8 bytes at a time. */
2:
SFI_BREG(r1) \
ldrd r4, r5, [r1], #8
SFI_BREG(r0) \
strd r4, r5, [r0], #8
subs r2, r2, #8
bge 2b /* If there is more to copy. */
copy_less_than_8:
/* Get here if less than 8 bytes to copy, -8 <= r2 < 0.
Check if there is more to copy. */
cmn r2, #8
beq return /* If r2 + 8 == 0. */
/* Restore the count if there is more than 3 bytes to copy. */
adds r2, r2, #4
blt copy_less_than_4
/* Copy 4 bytes. */
SFI_BREG(r1) \
ldr r3, [r1], #4
SFI_BREG(r0) \
str r3, [r0], #4
copy_less_than_4:
/* Get here if less than 4 bytes to copy, -4 <= r2 < 0. */
/* Restore the count, check if there is more to copy. */
adds r2, r2, #4
beq return /* If r2 == 0. */
/* Get here with r2 is in {1,2,3}={01,10,11}. */
/* Logical shift left r2, insert 0s, update flags. */
lsls r2, r2, #31
/* Copy byte by byte.
Condition ne means the last bit of r2 is 0.
Condition cs means the second to last bit of r2 is set,
i.e., r2 is 1 or 3. */
IT(itt ne)
SFI_BREG(r1) \
ldrbne r3, [r1], #1
SFI_BREG(r0) \
strbne r3, [r0], #1
IT(itttt cs)
SFI_BREG(r1) \
ldrbcs r4, [r1], #1
SFI_BREG(r1) \
ldrbcs r5, [r1]
SFI_BREG(r0) \
strbcs r4, [r0], #1
SFI_BREG(r0) \
strbcs r5, [r0]
return:
/* Restore registers: optimized pop {r0, r4, r5, pc} */
ldrd r4, r5, [sp], #8
#ifdef __native_client__
pop {r0, lr}
sfi_bx lr
#else
pop {r0, pc} /* This is the only return point of memcpy. */
#endif
#ifndef __ARM_FEATURE_UNALIGNED
/* The following assembly macro implements misaligned copy in software.
Assumes that dst is word aligned, src is at offset "pull" bits from
word, push = 32 - pull, and the number of bytes that remain to copy
is r2 + 4, r2 >= 0. */
/* In the code below, r2 is the number of bytes that remain to be
written. The number of bytes read is always larger, because we have
partial words in the shift queue. */
.macro miscopy pull push shiftleft shiftright
/* Align src to the previous word boundary. */
bic r1, r1, #3
/* Initialize the shift queue. */
SFI_BREG(r1) \
ldr r5, [r1], #4 /* Load a word from source. */
subs r2, r2, #4
blt 6f /* Go to misaligned copy of less than 8 bytes. */
/* Get here if there is more than 8 bytes to copy.
The number of bytes to copy is r2+8, r2 >= 0. */
/* Save registers: push { r6, r7 }.
We need additional registers for LDRD and STRD, because in ARM state
the first destination register must be even and the second
consecutive. */
strd r6, r7, [sp, #-8]!
subs r2, r2, #56
blt 4f /* Go to misaligned copy of less than 64 bytes. */
3:
/* Get here if there is more than 64 bytes to copy.
The number of bytes to copy is r2+64, r2 >= 0. */
/* Copy 64 bytes in every iteration.
Use a partial word from the shift queue. */
.irp offset, #0, #8, #16, #24, #32, #40, #48, #56
mov r6, r5, \shiftleft #\pull
SFI_BREG(r1) \
ldrd r4, r5, [r1, \offset]
orr r6, r6, r4, \shiftright #\push
mov r7, r4, \shiftleft #\pull
orr r7, r7, r5, \shiftright #\push
SFI_BREG(r0) \
strd r6, r7, [r0, \offset]
.endr
add r1, r1, #64
add r0, r0, #64
subs r2, r2, #64
bge 3b
4:
/* Get here if there is less than 64 bytes to copy (-64 <= r2 < 0)
and they are misaligned. */
/* Restore the count if there is more than 7 bytes to copy. */
adds r2, r2, #56
/* If less than 8 bytes to copy,
restore registers saved for this loop: optimized poplt { r6, r7 }. */
itt lt
ldrdlt r6, r7, [sp], #8
blt 6f /* Go to misaligned copy of less than 8 bytes. */
5:
/* Copy 8 bytes at a time.
Use a partial word from the shift queue. */
mov r6, r5, \shiftleft #\pull
SFI_BREG(r1) \
ldrd r4, r5, [r1], #8
orr r6, r6, r4, \shiftright #\push
mov r7, r4, \shiftleft #\pull
orr r7, r7, r5, \shiftright #\push
SFI_BREG(r0) \
strd r6, r7, [r0], #8
subs r2, r2, #8
bge 5b /* If there is more to copy. */
/* Restore registers saved for this loop: optimized pop { r6, r7 }. */
ldrd r6, r7, [sp], #8
6:
/* Get here if there less than 8 bytes to copy (-8 <= r2 < 0)
and they are misaligned. */
/* Check if there is more to copy. */
cmn r2, #8
beq return
/* Check if there is less than 4 bytes to copy. */
cmn r2, #4
itt lt
/* Restore src offset from word-align. */
sublt r1, r1, #(\push / 8)
blt copy_less_than_4
/* Use a partial word from the shift queue. */
mov r3, r5, \shiftleft #\pull
/* Load a word from src, but without writeback
(this word is not fully written to dst). */
SFI_BREG(r1) \
ldr r5, [r1]
/* Restore src offset from word-align. */
add r1, r1, #(\pull / 8)
/* Shift bytes to create one dst word and store it. */
orr r3, r3, r5, \shiftright #\push
SFI_BREG(r0) \
str r3, [r0], #4
/* Use single byte copying of the remaining bytes. */
b copy_less_than_4
.endm
#endif /* not __ARM_FEATURE_UNALIGNED */
dst_not_word_aligned:
/* Get here when dst is not aligned and ip has the last 2 bits of dst,
i.e., ip is the offset of dst from word.
The number of bytes that remains to copy is r2 + 4,
i.e., there are at least 4 bytes to copy.
Write a partial word (0 to 3 bytes), such that dst becomes
word-aligned. */
/* If dst is at ip bytes offset from a word (with 0 < ip < 4),
then there are (4 - ip) bytes to fill up to align dst to the next
word. */
rsb ip, ip, #4 /* ip = #4 - ip. */
cmp ip, #2
/* Copy byte by byte with conditionals. */
IT(itt gt)
SFI_BREG(r1) \
ldrbgt r3, [r1], #1
SFI_BREG(r0) \
strbgt r3, [r0], #1
IT(itt ge)
SFI_BREG(r1) \
ldrbge r4, [r1], #1
SFI_BREG(r0) \
strbge r4, [r0], #1
SFI_BREG(r1) \
ldrb lr, [r1], #1
SFI_BREG(r0) \
strb lr, [r0], #1
/* Update the count.
ip holds the number of bytes we have just copied. */
subs r2, r2, ip /* r2 = r2 - ip. */
blt copy_less_than_4 /* If r2 < ip. */
/* Get here if there are more than 4 bytes to copy.
Check if src is aligned. If beforehand src and dst were not word
aligned but congruent (same offset), then now they are both
word-aligned, and we can copy the rest efficiently (without
shifting). */
ands ip, r1, #3 /* ip = last 2 bits of src. */
beq word_aligned /* If r1 is word-aligned. */
src_not_word_aligned:
/* Get here when src is not word-aligned, but dst is word-aligned.
The number of bytes that remains to copy is r2+4. */
#ifdef __ARM_FEATURE_UNALIGNED
/* Copy word by word using LDR when alignment can be done in hardware,
i.e., SCTLR.A is set, supporting unaligned access in LDR and STR. */
subs r2, r2, #60
blt 8f
7:
/* Copy 64 bytes in every loop iteration. */
.irp offset, #0, #4, #8, #12, #16, #20, #24, #28, #32, #36, #40, #44, #48, #52, #56, #60
SFI_BREG(r1) \
ldr r3, [r1, \offset]
SFI_BREG(r0) \
str r3, [r0, \offset]
.endr
add r0, r0, #64
add r1, r1, #64
subs r2, r2, #64
bge 7b
8:
/* Get here if less than 64 bytes to copy, -64 <= r2 < 0.
Check if there is more than 3 bytes to copy. */
adds r2, r2, #60
blt copy_less_than_4
9:
/* Get here if there is less than 64 but at least 4 bytes to copy,
where the number of bytes to copy is r2+4. */
SFI_BREG(r1) \
ldr r3, [r1], #4
SFI_BREG(r0) \
str r3, [r0], #4
subs r2, r2, #4
bge 9b
b copy_less_than_4
#else /* not __ARM_FEATURE_UNALIGNED */
/* ip has last 2 bits of src,
i.e., ip is the offset of src from word, and ip > 0.
Compute shifts needed to copy from src to dst. */
cmp ip, #2
beq miscopy_16_16 /* If ip == 2. */
bge miscopy_24_8 /* If ip == 3. */
/* Get here if ip == 1. */
/* Endian independent macros for shifting bytes within registers. */
#ifndef __ARMEB__
miscopy_8_24: miscopy pull=8 push=24 shiftleft=lsr shiftright=lsl
miscopy_16_16: miscopy pull=16 push=16 shiftleft=lsr shiftright=lsl
miscopy_24_8: miscopy pull=24 push=8 shiftleft=lsr shiftright=lsl
#else /* not __ARMEB__ */
miscopy_8_24: miscopy pull=8 push=24 shiftleft=lsl shiftright=lsr
miscopy_16_16: miscopy pull=16 push=16 shiftleft=lsl shiftright=lsr
miscopy_24_8: miscopy pull=24 push=8 shiftleft=lsl shiftright=lsr
#endif /* not __ARMEB__ */
#endif /* not __ARM_FEATURE_UNALIGNED */
#endif /* memcpy */

View file

@ -0,0 +1,186 @@
/*
Copyright (c) 2023 Raspberry Pi (Trading) Ltd.
SPDX-License-Identifier: BSD-3-Clause
*/
#if defined(PICO_CYW43_SUPPORTED)
#include <btstack.h>
#include <pico/btstack_flash_bank.h>
#include <hardware/flash.h>
#include <hardware/sync.h>
#include <string.h>
#include <Arduino.h>
const uint8_t __bluetooth_tlv[8192] __attribute__((aligned(4096))) = { 0 };
extern const uint8_t __flash_binary_start;
#undef PICO_FLASH_BANK_TOTAL_SIZE
#undef PICO_FLASH_BANK_STORAGE_OFFSET
#define PICO_FLASH_BANK_TOTAL_SIZE sizeof(__bluetooth_tlv)
#define PICO_FLASH_BANK_STORAGE_OFFSET ((unsigned int)(__bluetooth_tlv - &__flash_binary_start))
#if 0
// Check sizes
static_assert(PICO_FLASH_BANK_TOTAL_SIZE % (FLASH_SECTOR_SIZE * 2) == 0, "PICO_FLASH_BANK_TOTAL_SIZE invalid");
static_assert(PICO_FLASH_BANK_TOTAL_SIZE <= PICO_FLASH_SIZE_BYTES, "PICO_FLASH_BANK_TOTAL_SIZE too big");
static_assert(PICO_FLASH_BANK_STORAGE_OFFSET + PICO_FLASH_BANK_TOTAL_SIZE <= PICO_FLASH_SIZE_BYTES, "PICO_FLASH_BANK_TOTAL_SIZE too big");
#endif
// Size of one bank
#define PICO_FLASH_BANK_SIZE (PICO_FLASH_BANK_TOTAL_SIZE / 2)
#if 0
#define DEBUG_PRINT(format,args...) printf(format, ## args)
#else
#define DEBUG_PRINT(...)
#endif
static uint32_t pico_flash_bank_get_size(void * context) {
(void)(context);
return PICO_FLASH_BANK_SIZE;
}
static uint32_t pico_flash_bank_get_alignment(void * context) {
(void)(context);
return 1;
}
static void pico_flash_bank_erase(void * context, int bank) {
(void)(context);
DEBUG_PRINT("erase: bank %d\n", bank);
if (!__isFreeRTOS) {
noInterrupts();
}
rp2040.idleOtherCore();
flash_range_erase(PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank), PICO_FLASH_BANK_SIZE);
rp2040.resumeOtherCore();
if (!__isFreeRTOS) {
interrupts();
}
}
static void pico_flash_bank_read(void *context, int bank, uint32_t offset, uint8_t *buffer, uint32_t size) {
(void)(context);
DEBUG_PRINT("read: bank %d offset %u size %u\n", bank, offset, size);
assert(bank <= 1);
if (bank > 1) {
return;
}
assert(offset < PICO_FLASH_BANK_SIZE);
if (offset >= PICO_FLASH_BANK_SIZE) {
return;
}
assert((offset + size) <= PICO_FLASH_BANK_SIZE);
if ((offset + size) > PICO_FLASH_BANK_SIZE) {
return;
}
// Flash is xip
memcpy(buffer, (void *)(XIP_BASE + PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank) + offset), size);
}
static void pico_flash_bank_write(void * context, int bank, uint32_t offset, const uint8_t *data, uint32_t size) {
(void)(context);
DEBUG_PRINT("write: bank %d offset %u size %u\n", bank, offset, size);
assert(bank <= 1);
if (bank > 1) {
return;
}
assert(offset < PICO_FLASH_BANK_SIZE);
if (offset >= PICO_FLASH_BANK_SIZE) {
return;
}
assert((offset + size) <= PICO_FLASH_BANK_SIZE);
if ((offset + size) > PICO_FLASH_BANK_SIZE) {
return;
}
if (size == 0) {
return;
}
// calc bank start position
const uint32_t bank_start_pos = PICO_FLASH_BANK_STORAGE_OFFSET + (PICO_FLASH_BANK_SIZE * bank);
// Calculate first and last page in the bank
const uint32_t first_page = offset / FLASH_PAGE_SIZE;
const uint32_t last_page = (offset + size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE;
// Now we only care about the offset in the first page
offset %= FLASH_PAGE_SIZE;
// Amount of data we've copied
uint32_t data_pos = 0;
uint32_t size_left = size;
// Write all the pages required
for (uint32_t page = first_page; page < last_page; page++) {
uint8_t page_data[FLASH_PAGE_SIZE];
assert(data_pos < size && size_left <= size);
// Copy data we're not going to overwrite in the first page
if (page == first_page && offset > 0) {
memcpy(page_data,
(void *)(XIP_BASE + bank_start_pos + (page * FLASH_PAGE_SIZE)),
offset);
}
// Copy the data we're not going to overwrite in the last page
if (page == last_page - 1 && (offset + size_left) < FLASH_PAGE_SIZE) {
memcpy(page_data + offset + size_left,
(void *)(XIP_BASE + bank_start_pos + (page * FLASH_PAGE_SIZE) + offset + size_left),
FLASH_PAGE_SIZE - offset - size_left);
}
// Now copy the new data into the page
const uint32_t size_to_copy = MIN(size_left, FLASH_PAGE_SIZE - offset);
memcpy(page_data + offset, data + data_pos, size_to_copy);
data_pos += size_to_copy;
size_left -= size_to_copy;
// zero offset for the following pages
offset = 0;
// Now program the entire page
if (!__isFreeRTOS) {
noInterrupts();
}
rp2040.idleOtherCore();
flash_range_program(bank_start_pos + (page * FLASH_PAGE_SIZE), page_data, FLASH_PAGE_SIZE);
rp2040.resumeOtherCore();
if (!__isFreeRTOS) {
interrupts();
}
}
}
static const hal_flash_bank_t pico_flash_bank_instance_obj = {
/* uint32_t (*get_size)(..) */ &pico_flash_bank_get_size,
/* uint32_t (*get_alignment)(..); */ &pico_flash_bank_get_alignment,
/* void (*erase)(..); */ &pico_flash_bank_erase,
/* void (*read)(..); */ &pico_flash_bank_read,
/* void (*write)(..); */ &pico_flash_bank_write,
};
extern "C" {
const hal_flash_bank_t *pico_flash_bank_instance(void) {
#ifndef NDEBUG
// Check we're not overlapping the binary in flash
//extern char __flash_binary_end;
// assert((uintptr_t)&__flash_binary_end - XIP_BASE <= PICO_FLASH_BANK_STORAGE_OFFSET);
#endif
return &pico_flash_bank_instance_obj;
}
}
#endif

View file

@ -1,348 +0,0 @@
/*
Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
SPDX-License-Identifier: BSD-3-Clause
*/
// Taken from the Pico-SDK v1.4.0 and hacked by EFP3 to allow overriding the LWIP setup
//#include <stdio.h>
#include "pico/cyw43_arch.h"
#include "pico/mutex.h"
#include "pico/sem.h"
#include "hardware/gpio.h"
#include "hardware/irq.h"
#include "cyw43_stats.h"
#include <lwip/init.h>
#include "lwip/timeouts.h"
#ifndef CYW43_PIN_WL_HOST_WAKE
#define CYW43_PIN_WL_HOST_WAKE 24
#endif
#ifndef CYW43_PIN_WL_REG_ON
#define CYW43_PIN_WL_REG_ON 23
#endif
#ifndef CYW43_WL_GPIO_COUNT
#define CYW43_WL_GPIO_COUNT 3
#endif
#ifndef CYW43_WL_GPIO_LED_PIN
#define CYW43_WL_GPIO_LED_PIN 0
#endif
extern volatile bool __inLWIP;
// note same code
#if PICO_CYW43_ARCH_THREADSAFE_BACKGROUND
#if PICO_CYW43_ARCH_THREADSAFE_BACKGROUND && CYW43_LWIP && !NO_SYS
#error PICO_CYW43_ARCH_THREADSAFE_BACKGROUND requires lwIP NO_SYS=1
#endif
#if PICO_CYW43_ARCH_THREADSAFE_BACKGROUND && CYW43_LWIP && MEM_LIBC_MALLOC
#error MEM_LIBC_MALLOC is incompatible with PICO_CYW43_ARCH_THREADSAFE_BACKGROUND
#endif
// todo right now we are now always doing a cyw43_dispatch along with a lwip one when hopping cores in low_prio_irq_schedule_dispatch
#ifndef CYW43_SLEEP_CHECK_MS
#define CYW43_SLEEP_CHECK_MS 50 // How often to run lwip callback
#endif
static alarm_id_t periodic_alarm = -1;
static inline uint recursive_mutex_enter_count(recursive_mutex_t *mutex) {
return mutex->enter_count;
}
static inline lock_owner_id_t recursive_mutex_owner(recursive_mutex_t *mutex) {
return mutex->owner;
}
#define CYW43_GPIO_IRQ_HANDLER_PRIORITY 0x40
enum {
CYW43_DISPATCH_SLOT_CYW43 = 0,
CYW43_DISPATCH_SLOT_ADAPTER,
CYW43_DISPATCH_SLOT_ENUM_COUNT
};
#ifndef CYW43_DISPATCH_SLOT_COUNT
#define CYW43_DISPATCH_SLOT_COUNT CYW43_DISPATCH_SLOT_ENUM_COUNT
#endif
typedef void (*low_prio_irq_dispatch_t)(void);
static void low_prio_irq_schedule_dispatch(size_t slot, low_prio_irq_dispatch_t f);
static uint8_t cyw43_core_num;
#ifndef NDEBUG
static bool in_low_priority_irq;
#endif
static uint8_t low_priority_irq_num;
static bool low_priority_irq_missed;
static low_prio_irq_dispatch_t low_priority_irq_dispatch_slots[CYW43_DISPATCH_SLOT_COUNT];
static recursive_mutex_t cyw43_mutex;
semaphore_t cyw43_irq_sem;
// Called in low priority pendsv interrupt only to do lwip processing and check cyw43 sleep
static void periodic_worker(void) {
#if CYW43_USE_STATS && LWIP_SYS_CHECK_MS
static uint32_t counter;
if (counter++ % (30000 / LWIP_SYS_CHECK_MS) == 0) {
cyw43_dump_stats();
}
#endif
CYW43_STAT_INC(LWIP_RUN_COUNT);
//#if CYW43_LWIP
if (!__inLWIP) {
sys_check_timeouts();
}
//#endif
if (cyw43_poll) {
if (cyw43_sleep > 0) {
if (--cyw43_sleep == 0) {
low_prio_irq_schedule_dispatch(CYW43_DISPATCH_SLOT_CYW43, cyw43_poll);
}
}
}
}
// Regular callback to get lwip to check for timeouts
static int64_t periodic_alarm_handler(__unused alarm_id_t id, __unused void *user_data) {
// Do lwip processing in low priority pendsv interrupt
low_prio_irq_schedule_dispatch(CYW43_DISPATCH_SLOT_ADAPTER, periodic_worker);
return CYW43_SLEEP_CHECK_MS * 1000;
}
void cyw43_await_background_or_timeout_us(uint32_t timeout_us) {
// if we are called from within an IRQ, then don't wait (we are only ever called in a polling loop)
if (!__get_current_exception()) {
sem_acquire_timeout_us(&cyw43_irq_sem, timeout_us);
}
}
// GPIO interrupt handler to tell us there's cyw43 has work to do
static void gpio_irq_handler(void) {
uint32_t events = gpio_get_irq_event_mask(CYW43_PIN_WL_HOST_WAKE);
if (events & GPIO_IRQ_LEVEL_HIGH) {
// As we use a high level interrupt, it will go off forever until it's serviced
// So disable the interrupt until this is done. It's re-enabled again by CYW43_POST_POLL_HOOK
// which is called at the end of cyw43_poll_func
gpio_set_irq_enabled(CYW43_PIN_WL_HOST_WAKE, GPIO_IRQ_LEVEL_HIGH, false);
// also clear the force bit which we use to progratically cause this handler to fire (on the right core)
io_irq_ctrl_hw_t *irq_ctrl_base = get_core_num() ?
&iobank0_hw->proc1_irq_ctrl : &iobank0_hw->proc0_irq_ctrl;
hw_clear_bits(&irq_ctrl_base->intf[CYW43_PIN_WL_HOST_WAKE / 8], GPIO_IRQ_LEVEL_HIGH << (4 * (CYW43_PIN_WL_HOST_WAKE & 7)));
low_prio_irq_schedule_dispatch(CYW43_DISPATCH_SLOT_CYW43, cyw43_poll);
CYW43_STAT_INC(IRQ_COUNT);
}
}
// Low priority interrupt handler to perform background processing
static void low_priority_irq_handler(void) {
assert(cyw43_core_num == get_core_num());
if (recursive_mutex_try_enter(&cyw43_mutex, NULL)) {
if (__inLWIP || (recursive_mutex_enter_count(&cyw43_mutex) != 1)) {
low_priority_irq_missed = true;
CYW43_STAT_INC(PENDSV_DISABLED_COUNT);
} else {
CYW43_STAT_INC(PENDSV_RUN_COUNT);
#ifndef NDEBUG
in_low_priority_irq = true;
#endif
for (size_t i = 0; i < count_of(low_priority_irq_dispatch_slots); i++) {
if (low_priority_irq_dispatch_slots[i] != NULL) {
low_prio_irq_dispatch_t f = low_priority_irq_dispatch_slots[i];
low_priority_irq_dispatch_slots[i] = NULL;
f();
}
}
#ifndef NDEBUG
in_low_priority_irq = false;
#endif
}
recursive_mutex_exit(&cyw43_mutex);
} else {
CYW43_STAT_INC(PENDSV_DISABLED_COUNT);
low_priority_irq_missed = true;
}
sem_release(&cyw43_irq_sem);
}
static bool low_prio_irq_init(uint8_t priority) {
assert(get_core_num() == cyw43_core_num);
int irq = user_irq_claim_unused(false);
if (irq < 0) {
return false;
}
low_priority_irq_num = (uint8_t) irq;
irq_set_exclusive_handler(low_priority_irq_num, low_priority_irq_handler);
irq_set_enabled(low_priority_irq_num, true);
irq_set_priority(low_priority_irq_num, priority);
return true;
}
static void low_prio_irq_deinit(void) {
if (low_priority_irq_num > 0) {
irq_set_enabled(low_priority_irq_num, false);
irq_remove_handler(low_priority_irq_num, low_priority_irq_handler);
user_irq_unclaim(low_priority_irq_num);
low_priority_irq_num = 0;
}
}
int cyw43_arch_init(void) {
cyw43_core_num = get_core_num();
recursive_mutex_init(&cyw43_mutex);
cyw43_init(&cyw43_state);
sem_init(&cyw43_irq_sem, 0, 1);
// Start regular lwip callback to handle timeouts
periodic_alarm = add_alarm_in_us(CYW43_SLEEP_CHECK_MS * 1000, periodic_alarm_handler, NULL, true);
if (periodic_alarm < 0) {
return PICO_ERROR_GENERIC;
}
gpio_add_raw_irq_handler_with_order_priority(IO_IRQ_BANK0, gpio_irq_handler, CYW43_GPIO_IRQ_HANDLER_PRIORITY);
gpio_set_irq_enabled(CYW43_PIN_WL_HOST_WAKE, GPIO_IRQ_LEVEL_HIGH, true);
irq_set_enabled(IO_IRQ_BANK0, true);
lwip_init();
// start low priority handler (no background work is done before this)
bool ok = low_prio_irq_init(PICO_LOWEST_IRQ_PRIORITY);
if (!ok) {
cyw43_arch_deinit();
return PICO_ERROR_GENERIC;
}
return PICO_OK;
}
void cyw43_arch_deinit(void) {
if (periodic_alarm >= 0) {
cancel_alarm(periodic_alarm);
periodic_alarm = -1;
}
gpio_set_irq_enabled(CYW43_PIN_WL_HOST_WAKE, GPIO_IRQ_LEVEL_HIGH, false);
gpio_remove_raw_irq_handler(IO_IRQ_BANK0, gpio_irq_handler);
low_prio_irq_deinit();
}
void cyw43_post_poll_hook(void) {
gpio_set_irq_enabled(CYW43_PIN_WL_HOST_WAKE, GPIO_IRQ_LEVEL_HIGH, true);
}
// This is called in the gpio and low_prio_irq interrupts and on either core
static void low_prio_irq_schedule_dispatch(size_t slot, low_prio_irq_dispatch_t f) {
assert(slot < count_of(low_priority_irq_dispatch_slots));
low_priority_irq_dispatch_slots[slot] = f;
if (cyw43_core_num == get_core_num()) {
//on same core, can dispatch directly
irq_set_pending(low_priority_irq_num);
} else {
// on wrong core, so force via GPIO IRQ which itself calls this method for the CYW43 slot.
// since the CYW43 slot always uses the same function, this is fine with the addition of an
// extra (but harmless) CYW43 slot call when another SLOT is invoked.
// We could do better, but would have to track why the IRQ was called.
io_irq_ctrl_hw_t *irq_ctrl_base = cyw43_core_num ?
&iobank0_hw->proc1_irq_ctrl : &iobank0_hw->proc0_irq_ctrl;
hw_set_bits(&irq_ctrl_base->intf[CYW43_PIN_WL_HOST_WAKE / 8], GPIO_IRQ_LEVEL_HIGH << (4 * (CYW43_PIN_WL_HOST_WAKE & 7)));
}
}
void cyw43_schedule_internal_poll_dispatch(void (*func)(void)) {
low_prio_irq_schedule_dispatch(CYW43_DISPATCH_SLOT_CYW43, func);
}
// Prevent background processing in pensv and access by the other core
// These methods are called in pensv context and on either core
// They can be called recursively
void cyw43_thread_enter(void) {
// Lock the other core and stop low_prio_irq running
recursive_mutex_enter_blocking(&cyw43_mutex);
}
#ifndef NDEBUG
void cyw43_thread_lock_check(void) {
// Lock the other core and stop low_prio_irq running
if (recursive_mutex_enter_count(&cyw43_mutex) < 1 || recursive_mutex_owner(&cyw43_mutex) != lock_get_caller_owner_id()) {
panic("cyw43_thread_lock_check failed");
}
}
#endif
// Re-enable background processing
void cyw43_thread_exit(void) {
// Run low_prio_irq if needed
if (1 == recursive_mutex_enter_count(&cyw43_mutex)) {
// note the outer release of the mutex is not via cyw43_exit in the low_priority_irq case (it is a direct mutex exit)
assert(!in_low_priority_irq);
// if (low_priority_irq_missed) {
// low_priority_irq_missed = false;
if (low_priority_irq_dispatch_slots[CYW43_DISPATCH_SLOT_CYW43]) {
low_prio_irq_schedule_dispatch(CYW43_DISPATCH_SLOT_CYW43, cyw43_poll);
}
// }
}
recursive_mutex_exit(&cyw43_mutex);
}
static void cyw43_delay_until(absolute_time_t until) {
// sleep can be called in IRQs, so there's not much we can do there
if (__get_current_exception()) {
busy_wait_until(until);
} else {
sleep_until(until);
}
}
void cyw43_delay_ms(uint32_t ms) {
cyw43_delay_until(make_timeout_time_ms(ms));
}
void cyw43_delay_us(uint32_t us) {
cyw43_delay_until(make_timeout_time_us(us));
}
void cyw43_arch_poll() {
// should not be necessary
// if (cyw43_poll) {
// low_prio_irq_schedule_dispatch(CYW43_DISPATCH_SLOT_CYW43, cyw43_poll);
// }
}
#ifdef ARDUINO_RASPBERRY_PI_PICO_W
void __attribute__((weak)) cyw43_cb_tcpip_init(cyw43_t *self, int itf);
void cyw43_cb_tcpip_init(cyw43_t *self, int itf) {
(void) self;
(void) itf;
}
void __attribute__((weak)) cyw43_cb_tcpip_deinit(cyw43_t *self, int itf);
void cyw43_cb_tcpip_deinit(cyw43_t *self, int itf) {
(void) self;
(void) itf;
}
void __attribute__((weak)) cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf);
void cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) {
(void) self;
(void) itf;
}
void __attribute__((weak)) cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf);
void cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) {
(void) self;
(void) itf;
}
void __attribute__((weak)) cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len, const uint8_t *buf);
void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len, const uint8_t *buf) {
(void) cb_data;
(void) itf;
(void) len;
(void) buf;
}
#endif
#endif

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

View file

@ -0,0 +1,200 @@
/*
Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/times.h>
#include <time.h>
#include <unistd.h>
#if PICO_ENTER_USB_BOOT_ON_EXIT
#include "pico/bootrom.h"
#endif
#include "pico/time.h"
#include "pico/runtime_init.h"
#if LIB_PICO_PRINTF_PICO
#include "pico/printf.h"
#else
#define weak_raw_printf printf
#define weak_raw_vprintf vprintf
#endif
#if LIB_PICO_STDIO
#include "pico/stdio.h"
#endif
#if PICO_ENTER_USB_BOOT_ON_EXIT
#include "pico/bootrom.h"
#endif
extern char __StackLimit; /* Set by linker. */
#define STDIO_HANDLE_STDIN 0
#define STDIO_HANDLE_STDOUT 1
#define STDIO_HANDLE_STDERR 2
void __attribute__((noreturn)) __weak _exit(__unused int status) {
#if PICO_ENTER_USB_BOOT_ON_EXIT
reset_usb_boot(0, 0);
#else
while (1) {
__breakpoint();
}
#endif
}
__weak void *_sbrk(int incr) {
extern char end; /* Set by linker. */
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &end;
}
prev_heap_end = heap_end;
char *next_heap_end = heap_end + incr;
if (__builtin_expect(next_heap_end > (&__StackLimit), false)) {
#if PICO_USE_OPTIMISTIC_SBRK
if (heap_end == &__StackLimit) {
// errno = ENOMEM;
return (char *) -1;
}
next_heap_end = &__StackLimit;
#else
return (char *) -1;
#endif
}
heap_end = next_heap_end;
return (void *) prev_heap_end;
}
#if 0
static int64_t epoch_time_us_since_boot;
__weak int _gettimeofday(struct timeval *__restrict tv, __unused void *__restrict tz) {
if (tv) {
int64_t us_since_epoch = ((int64_t)to_us_since_boot(get_absolute_time())) - epoch_time_us_since_boot;
tv->tv_sec = (time_t)(us_since_epoch / 1000000);
tv->tv_usec = (suseconds_t)(us_since_epoch % 1000000);
}
return 0;
}
__weak int settimeofday(__unused const struct timeval *tv, __unused const struct timezone *tz) {
if (tv) {
int64_t us_since_epoch = tv->tv_sec * 1000000 + tv->tv_usec;
epoch_time_us_since_boot = (int64_t)to_us_since_boot(get_absolute_time()) - us_since_epoch;
}
return 0;
}
__weak int _times(struct tms *tms) {
#if CLOCKS_PER_SEC >= 1000000
tms->tms_utime = (clock_t)(to_us_since_boot(get_absolute_time()) * (CLOCKS_PER_SEC / 1000000));
#else
tms->tms_utime = (clock_t)(to_us_since_boot(get_absolute_time()) / (1000000 / CLOCKS_PER_SEC));
#endif
tms->tms_stime = 0;
tms->tms_cutime = 0;
tms->tms_cstime = 0;
return 0;
}
__weak pid_t _getpid(void) {
return 0;
}
__weak int _kill(__unused pid_t pid, __unused int sig) {
return -1;
}
int __attribute__((weak)) _read(int handle, char *buffer, int length) {
#if LIB_PICO_STDIO
if (handle == STDIO_HANDLE_STDIN) {
return stdio_get_until(buffer, length, at_the_end_of_time);
}
#endif
return -1;
}
int __attribute__((weak)) _write(int handle, char *buffer, int length) {
#if LIB_PICO_STDIO
if (handle == STDIO_HANDLE_STDOUT || handle == STDIO_HANDLE_STDERR) {
stdio_put_string(buffer, length, false, true);
return length;
}
#endif
return -1;
}
int __attribute__((weak)) _open(__unused const char *fn, __unused int oflag, ...) {
return -1;
}
int __attribute__((weak)) _close(__unused int fd) {
return -1;
}
off_t __attribute__((weak)) _lseek(__unused int fd, __unused off_t pos, __unused int whence) {
return -1;
}
int __attribute__((weak)) _fstat(__unused int fd, __unused struct stat *buf) {
return -1;
}
int __attribute__((weak)) _isatty(int fd) {
return fd == STDIO_HANDLE_STDIN || fd == STDIO_HANDLE_STDOUT || fd == STDIO_HANDLE_STDERR;
}
// exit is not useful... no desire to pull in __call_exitprocs
void exit(int status) {
_exit(status);
}
// incorrect warning from GCC 6
GCC_Pragma("GCC diagnostic push")
GCC_Pragma("GCC diagnostic ignored \"-Wsuggest-attribute=format\"")
void __weak __assert_func(const char *file, int line, const char *func, const char *failedexpr) {
weak_raw_printf("assertion \"%s\" failed: file \"%s\", line %d%s%s\n",
failedexpr, file, line, func ? ", function: " : "",
func ? func : "");
_exit(1);
}
GCC_Pragma("GCC diagnostic pop")
#endif
void runtime_init(void) {
#ifndef NDEBUG
if (__get_current_exception()) {
// crap; started in exception handler
__breakpoint();
}
#endif
#if !PICO_RUNTIME_SKIP_INIT_PER_CORE_INSTALL_STACK_GUARD
// install core0 stack guard
extern char __StackBottom;
runtime_init_per_core_install_stack_guard(&__StackBottom);
#endif
// todo maybe we want to do this in the future, but it does stuff like register_tm_clones
// which we didn't do in previous SDKs
//extern void __libc_init_array(void);
//__libc_init_array();
// ... so instead just do the __preinit_array
runtime_run_initializers();
// ... and the __init_array
extern void (*__init_array_start)(void);
extern void (*__init_array_end)(void);
for (void (**p)(void) = &__init_array_start; p < &__init_array_end; ++p) {
(*p)();
}
}

View file

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

View file

@ -0,0 +1,75 @@
/*
16-bit axis gamepad definition
Copyright (c) 2024 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 "tusb.h"
#include "class/hid/hid_device.h"
#define TUD_HID_REPORT_DESC_GAMEPAD16(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
/* Report ID if any */\
__VA_ARGS__ \
/* 16 bit X, Y, Z, Rz, Rx, Ry (min -32767, max 32767 ) */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\
HID_LOGICAL_MIN_N ( -32767, 2 ) ,\
HID_LOGICAL_MAX_N ( 32767, 2 ) ,\
HID_REPORT_COUNT ( 6 ) ,\
HID_REPORT_SIZE ( 16 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* 8 bit DPad/Hat Button Map */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\
HID_LOGICAL_MIN ( 1 ) ,\
HID_LOGICAL_MAX ( 8 ) ,\
HID_PHYSICAL_MIN ( 0 ) ,\
HID_PHYSICAL_MAX_N ( 315, 2 ) ,\
HID_REPORT_COUNT ( 1 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* 32 bit Button Map */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
HID_USAGE_MIN ( 1 ) ,\
HID_USAGE_MAX ( 32 ) ,\
HID_LOGICAL_MIN ( 0 ) ,\
HID_LOGICAL_MAX ( 1 ) ,\
HID_REPORT_COUNT ( 32 ) ,\
HID_REPORT_SIZE ( 1 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
HID_COLLECTION_END \
// HID Gamepad Protocol Report.
typedef struct TU_ATTR_PACKED {
int16_t x; ///< Delta x movement of left analog-stick
int16_t y; ///< Delta y movement of left analog-stick
int16_t z; ///< Delta z movement of right analog-joystick
int16_t rz; ///< Delta Rz movement of right analog-joystick
int16_t rx; ///< Delta Rx movement of analog left trigger
int16_t ry; ///< Delta Ry movement of analog right trigger
uint8_t hat; ///< Buttons mask for currently pressed buttons in the DPad/hat
uint32_t buttons; ///< Buttons mask for currently pressed buttons
} hid_gamepad16_report_t;

View file

@ -18,18 +18,19 @@
; Side-set pin 0 is used for Tone output
; OSR == Halfcycle count
; OSR == Halfcycle count - 3
.program tone2
.side_set 1 opt
pull ; TXFIFO -> OSR, or X -> OSR if no new period
mov x, osr ; OSR -> X
; pull ; TXFIFO -> OSR, or X -> OSR if no new period
; mov x, osr ; OSR -> X
.wrap_target
high:
pull noblock ; Potentially grab new HALFCYCLECOUNT, OTW copy from backup in X
mov x, osr ; OSR -> X
mov y, osr side 1 ; HALFCYCLECOUNT -> Y
mov x, osr side 1 ; OSR -> X
mov y, osr ; HALFCYCLECOUNT -> Y
highloop:
jmp y-- highloop ; while (y--) { /* noop delay */ }
@ -38,7 +39,7 @@ low:
lowloop:
jmp y-- lowloop ; while (y--) { /* noop delay */ }
jmp high ; GOTO high
.wrap ; GOTO high
% c-sdk {
static inline void tone2_program_init(PIO pio, uint sm, uint offset, uint pin) {

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
@ -11,27 +13,29 @@
// ----- //
#define tone2_wrap_target 0
#define tone2_wrap 8
#define tone2_wrap 5
#define tone2_pio_version 0
static const uint16_t tone2_program_instructions[] = {
// .wrap_target
0x80a0, // 0: pull block
0xa027, // 1: mov x, osr
0x8080, // 2: pull noblock
0xa027, // 3: mov x, osr
0xb847, // 4: mov y, osr side 1
0x8080, // 0: pull noblock
0xb827, // 1: mov x, osr side 1
0xa047, // 2: mov y, osr
0x0083, // 3: jmp y--, 3
0xb047, // 4: mov y, osr side 0
0x0085, // 5: jmp y--, 5
0xb047, // 6: mov y, osr side 0
0x0087, // 7: jmp y--, 7
0x0002, // 8: jmp 2
// .wrap
};
#if !PICO_NO_HARDWARE
static const struct pio_program tone2_program = {
.instructions = tone2_program_instructions,
.length = 9,
.length = 6,
.origin = -1,
.pio_version = tone2_pio_version,
#if PICO_PIO_VERSION > 0
.used_gpio_ranges = 0x0
#endif
};
static inline pio_sm_config tone2_program_get_default_config(uint offset) {

View file

@ -30,7 +30,7 @@ void __clearADCPin(pin_size_t p);
static uint32_t analogScale = 255;
static uint32_t analogFreq = 1000;
static uint32_t pwmInitted = 0;
static uint64_t pwmInitted = 0;
static bool scaleInitted = false;
static bool adcInitted = false;
static uint16_t analogWritePseudoScale = 1;
@ -79,7 +79,7 @@ extern "C" void analogWriteResolution(int res) {
extern "C" void analogWrite(pin_size_t pin, int val) {
CoreMutex m(&_dacMutex);
if ((pin > 29) || !m) {
if ((pin >= __GPIOCNT) || !m) {
DEBUGCORE("ERROR: Illegal analogWrite pin (%d)\n", pin);
return;
}
@ -101,12 +101,12 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
}
scaleInitted = true;
}
if (!(pwmInitted & (1 << pwm_gpio_to_slice_num(pin)))) {
if (!(pwmInitted & (1LL << pwm_gpio_to_slice_num(pin)))) {
pwm_config c = pwm_get_default_config();
pwm_config_set_clkdiv(&c, clock_get_hz(clk_sys) / ((float)analogScale * analogFreq));
pwm_config_set_wrap(&c, analogScale - 1);
pwm_init(pwm_gpio_to_slice_num(pin), &c, true);
pwmInitted |= 1 << pwm_gpio_to_slice_num(pin);
pwmInitted |= 1LL << pwm_gpio_to_slice_num(pin);
}
val <<= analogWritePseudoScale;
@ -125,17 +125,17 @@ extern "C" void analogWrite(pin_size_t pin, int val) {
auto_init_mutex(_adcMutex);
static uint8_t _readBits = 10;
static uint8_t _lastADCMux = 0;
static uint32_t _adcGPIOInit = 0;
static uint64_t _adcGPIOInit = 0;
void __clearADCPin(pin_size_t p) {
_adcGPIOInit &= ~(1 << p);
_adcGPIOInit &= ~(1LL << p);
}
extern "C" int analogRead(pin_size_t pin) {
CoreMutex m(&_adcMutex);
pin_size_t maxPin = max(A0, A3);
pin_size_t minPin = min(A0, A3);
pin_size_t maxPin = __GPIOCNT;
pin_size_t minPin = __FIRSTANALOGGPIO;
if ((pin < minPin) || (pin > maxPin) || !m) {
DEBUGCORE("ERROR: Illegal analogRead pin (%d)\n", pin);
@ -145,9 +145,9 @@ extern "C" int analogRead(pin_size_t pin) {
adc_init();
adcInitted = true;
}
if (!(_adcGPIOInit & (1 << pin))) {
if (!(_adcGPIOInit & (1LL << pin))) {
adc_gpio_init(pin);
_adcGPIOInit |= 1 << pin;
_adcGPIOInit |= 1LL << pin;
}
if (_lastADCMux != pin) {
adc_select_input(pin - minPin);
@ -169,7 +169,7 @@ extern "C" float analogReadTemp(float vref) {
_lastADCMux = 0;
adc_set_temp_sensor_enabled(true);
delay(1); // Allow things to settle. Without this, readings can be erratic
adc_select_input(4); // Temperature sensor
adc_select_input(__GPIOCNT - __FIRSTANALOGGPIO); // Temperature sensor
int v = adc_read();
adc_set_temp_sensor_enabled(false);
float t = 27.0f - ((v * vref / 4096.0f) - 0.706f) / 0.001721f; // From the datasheet

View file

@ -23,10 +23,15 @@
extern void __clearADCPin(pin_size_t p);
static PinMode _pm[30];
static PinMode _pm[__GPIOCNT];
extern "C" void pinMode(pin_size_t ulPin, PinMode ulMode) __attribute__((weak, alias("__pinMode")));
extern "C" void __pinMode(pin_size_t ulPin, PinMode ulMode) {
if (ulPin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
return;
}
switch (ulMode) {
case INPUT:
gpio_init(ulPin);
@ -72,20 +77,16 @@ extern "C" void __pinMode(pin_size_t ulPin, PinMode ulMode) {
return;
}
if (ulPin > 29) {
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
return;
}
_pm[ulPin] = ulMode;
if ((ulPin >= std::min(A0, A3)) && (ulPin <= std::max(A0, A3))) {
if (ulPin >= __FIRSTANALOGGPIO) {
__clearADCPin(ulPin);
}
}
extern "C" void digitalWrite(pin_size_t ulPin, PinStatus ulVal) __attribute__((weak, alias("__digitalWrite")));
extern "C" void __digitalWrite(pin_size_t ulPin, PinStatus ulVal) {
if (ulPin > 29) {
if (ulPin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal pin in pinMode (%d)\n", ulPin);
return;
}
@ -109,7 +110,7 @@ extern "C" void __digitalWrite(pin_size_t ulPin, PinStatus ulVal) {
extern "C" PinStatus digitalRead(pin_size_t ulPin) __attribute__((weak, alias("__digitalRead")));
extern "C" PinStatus __digitalRead(pin_size_t ulPin) {
if (ulPin > 29) {
if (ulPin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal pin in digitalRead (%d)\n", ulPin);
return LOW;
}

View file

@ -22,77 +22,70 @@
#include <CoreMutex.h>
#include <hardware/gpio.h>
#include <hardware/sync.h>
#include <map>
#include "_freertos.h"
// Support nested IRQ disable/re-enable
#ifndef maxIRQs
#define maxIRQs 15
#endif
static uint32_t _irqStackTop[2] = { 0, 0 };
static uint32_t _irqStack[2][maxIRQs];
extern "C" void interrupts() {
auto core = get_core_num();
if (!_irqStackTop[core]) {
// ERROR
return;
if (__freeRTOSinitted) {
__freertos_task_exit_critical();
} else {
auto core = get_core_num();
if (!_irqStackTop[core]) {
// ERROR
return;
}
restore_interrupts(_irqStack[core][--_irqStackTop[core]]);
}
restore_interrupts(_irqStack[core][--_irqStackTop[core]]);
}
extern "C" void noInterrupts() {
auto core = get_core_num();
if (_irqStackTop[core] == maxIRQs) {
// ERROR
panic("IRQ stack overflow");
if (__freeRTOSinitted) {
__freertos_task_enter_critical();
} else {
auto core = get_core_num();
if (_irqStackTop[core] == maxIRQs) {
// ERROR
panic("IRQ stack overflow");
}
_irqStack[core][_irqStackTop[core]++] = save_and_disable_interrupts();
}
_irqStack[core][_irqStackTop[core]++] = save_and_disable_interrupts();
}
auto_init_mutex(_irqMutex);
static uint64_t _gpioIrqEnabled = 0; // Sized to work with RP2350B, 48 GPIOs
static uint64_t _gpioIrqUseParam;
void *_gpioIrqCB[__GPIOCNT];
void *_gpioIrqCBParam[__GPIOCNT];
// Only 1 GPIO IRQ callback for all pins, so we need to look at the pin it's for and
// dispatch to the real callback manually
auto_init_mutex(_irqMutex);
class CBInfo {
public:
CBInfo(voidFuncPtr cb) : _cb(cb), _useParam(false), _param(nullptr) { };
CBInfo(voidFuncPtrParam cbParam, void *param) : _cbParam(cbParam), _useParam(true), _param(param) { };
void callback() {
if (_useParam && _cbParam) {
_cbParam(_param);
} else if (_cb) {
_cb();
}
}
private:
union {
voidFuncPtr _cb;
voidFuncPtrParam _cbParam;
};
bool _useParam;
void *_param;
};
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));
if (m) {
auto irq = _map.find(gpio);
if (irq != _map.end()) {
auto cb = irq->second;
cb.callback();
uint64_t mask = 1LL << gpio;
if (_gpioIrqEnabled & mask) {
if (_gpioIrqUseParam & mask) {
voidFuncPtr cb = (voidFuncPtr)_gpioIrqCB[gpio];
cb();
} else {
voidFuncPtrParam cb = (voidFuncPtrParam)_gpioIrqCB[gpio];
cb(_gpioIrqCBParam[gpio]);
}
}
}
// To be called when appropriately protected w/IRQ and mutex protects
static void _detachInterruptInternal(pin_size_t pin) {
auto irq = _map.find(pin);
if (irq != _map.end()) {
uint64_t mask = 1LL << pin;
if (_gpioIrqEnabled & mask) {
gpio_set_irq_enabled(pin, 0x0f /* all */, false);
_map.erase(pin);
_gpioIrqEnabled &= ~mask;
}
}
@ -101,7 +94,7 @@ extern "C" void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus
if (!m) {
return;
}
uint64_t mask = 1LL << pin;
uint32_t events;
switch (mode) {
case LOW: events = 1; break;
@ -113,8 +106,9 @@ extern "C" void attachInterrupt(pin_size_t pin, voidFuncPtr callback, PinStatus
}
noInterrupts();
_detachInterruptInternal(pin);
CBInfo cb(callback);
_map.insert({pin, cb});
_gpioIrqEnabled |= mask;
_gpioIrqUseParam &= ~mask; // No parameter
_gpioIrqCB[pin] = (void *)callback;
gpio_set_irq_enabled_with_callback(pin, events, true, _gpioInterruptDispatcher);
interrupts();
}
@ -124,7 +118,7 @@ void attachInterruptParam(pin_size_t pin, voidFuncPtrParam callback, PinStatus m
if (!m) {
return;
}
uint64_t mask = 1LL << pin;
uint32_t events;
switch (mode) {
case LOW: events = 1; break;
@ -136,8 +130,10 @@ void attachInterruptParam(pin_size_t pin, voidFuncPtrParam callback, PinStatus m
}
noInterrupts();
_detachInterruptInternal(pin);
CBInfo cb(callback, param);
_map.insert({pin, cb});
_gpioIrqEnabled |= mask;
_gpioIrqUseParam &= ~mask; // No parameter
_gpioIrqCB[pin] = (void *)callback;
_gpioIrqCBParam[pin] = param;
gpio_set_irq_enabled_with_callback(pin, events, true, _gpioInterruptDispatcher);
interrupts();
}

View file

@ -26,7 +26,7 @@ extern "C" unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeo
uint64_t start = time_us_64();
uint64_t abort = start + timeout;
if (pin > 29) {
if (pin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal pin in pulseIn (%d)\n", pin);
return 0;
}

View file

@ -24,11 +24,11 @@
extern "C" uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder) {
uint8_t value = 0;
uint8_t i;
if (dataPin > 29) {
if (dataPin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal dataPin in shiftIn (%d)\n", dataPin);
return 0;
}
if (clockPin > 29) {
if (clockPin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal clockPin in shiftIn (%d)\n", clockPin);
return 0;
}
@ -46,19 +46,19 @@ extern "C" uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bit
extern "C" void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val) {
uint8_t i;
if (dataPin > 29) {
if (dataPin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal dataPin in shiftOut (%d)\n", dataPin);
return;
}
if (clockPin > 29) {
if (clockPin >= __GPIOCNT) {
DEBUGCORE("ERROR: Illegal clockPin in shiftOut (%d)\n", clockPin);
return;
}
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST) {
digitalWrite(dataPin, !!(val & (1 << i)));
digitalWrite(dataPin, !!(val & (1 << i)) ? HIGH : LOW);
} else {
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(dataPin, !!(val & (1 << (7 - i))) ? HIGH : LOW);
}
digitalWrite(clockPin, HIGH);

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
docs/a2dp.rst Normal file
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.

View file

@ -12,9 +12,9 @@ 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
recording is done at 16-bit levels (but be aware that the ADC in the Pico will only
ever return values between 0...4095).
Up to 4 (or 8 in the case of the RP2350B) 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).
The interface for the ``ADCInput`` device is very similar to the ``I2S`` input
device, and most code can be ported simply by instantiating a ``ADCInput``
@ -26,11 +26,12 @@ allowed while in use.
ADC Input API
-------------
ADCInput(pin0 [, pin1, pin2, pin3])
ADCInput(pin0 [, pin1, pin2, pin3[, pin4, pin5, pin6, pin7])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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
order (i.e. ``ADCInput(A0, A1);`` is valid, but ``ADCInput(A1, A0)`` is not.
Only pins ``A0`` ... ``A3`` (``A7`` on RP2350B) 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)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -47,7 +48,7 @@ Adjusts the pin to record. Only legal before ``ADCInput::begin()``.
bool setFrequency(long sampleRate)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sets the ADC sampling frequency, but does not start recording (however if the
device was already running, it will wontinue to run at the new frequency). Note
device was already running, it will continue to run at the new frequency). Note
that every pin requested will be sampled at this frequency, one after the other.
That is, if you have code like this:

View file

@ -14,12 +14,12 @@ Returns a value from 0...4095 correspionding to the ADC reading
of the specific pin.
void analogReadResolution(int bits)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Determines the resolution (in bits) of the value returned by the analogRead() function.
Default resolution is 10bit.
float analogReadTemp(float vref = 3.3f)
~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns the temperature, in Celsius, of the onboard thermal sensor.
If you have a custom Vref for the ADC on your RP2040 board, you can pass it in as a parameter. Calling with no parameters assumes the normal, 3.3V Vref.
This reading is not exceedingly accurate and of relatively low
@ -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

View file

@ -120,7 +120,7 @@ Valid values for min and max are `BR_TLS10`, `BR_TLS11`, `BR_TLS12`. Min and ma
ESP32 Compatibility
===================
~~~~~~~~~~~~~~~~~~~
Simple ESP32 ``WiFiClientSecure`` compatibility is built-in, allow for some sketches to run without any modification.
The following methods are implemented:

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:

51
docs/bluetooth.rst Normal file
View file

@ -0,0 +1,51 @@
Bluetooth on PicoW Support
==========================
As of the Pico-SDK version 1.5.0, the PicoW has **BETA** Bluetooth support.
Enabling Bluetooth
------------------
To enable Bluetooth (BT), use the ``Tools->IP/Bluetooth Stack`` menu. It
requires around 80KB of flash and 20KB of RAM when enabled.
Both Bluetooth Classic and BluetoothBLE are enabled in ``btstack_config.h``.
Included Bluetooth Libraries
----------------------------
You may use the ``KeyboardBT``, ``MouseBT``, or ``JoystickBT`` to emulate a
Bluetooth Classic HID device using the same API as their USB versions.
You may use the ``KeyboardBLE``, ``MouseBLE``, or ``JoystickBLE`` to emulate a
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
method, but please be aware that the Raspberry Pi team has built an
interrupt-driven version of the BT execute loop, so there is no need
to actually call ``btstack_run_loop_execute`` because the ``async_context``
handler will do it for you.
There is no need to call ``cyw43_arch_init`` in your code, either, as that
is part of the PicoW variant booting process.
For many BTStack examples, you simply need call the included
``btstack_main()`` and make sure that ``hci_power_control(HCI_POWER_ON);`` is
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. ``__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.
Otherwise the change will not take effect in the precompiled code, leading
to really bad behavior.

21
docs/bootsel.rst Normal file
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);
}
}

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